From c830d758e78c01499cc3b72f4530439f68a6fd2f Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sun, 11 Aug 2019 12:48:33 +0200 Subject: [PATCH 001/134] Added M3AP ETSI TS 136 444 V14.0.0 ASN1 references Added M2AP ETSI TS 136 443 V14.0.0 ASN1 references --- .../M2AP/MESSAGES/ASN1/R14/m2ap-14.0.0.asn1 | 1897 +++++++++++++++++ openair2/M2AP/MESSAGES/asn1tostruct.py | 697 ++++++ .../M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 | 1316 ++++++++++++ .../MESSAGES/ASN1/R14/m3ap-14.0.0.asn1.bak | 1360 ++++++++++++ openair3/M3AP/MESSAGES/ASN1/asn1tostruct.py | 732 +++++++ 5 files changed, 6002 insertions(+) create mode 100644 openair2/M2AP/MESSAGES/ASN1/R14/m2ap-14.0.0.asn1 create mode 100644 openair2/M2AP/MESSAGES/asn1tostruct.py create mode 100644 openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 create mode 100644 openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1.bak create mode 100644 openair3/M3AP/MESSAGES/ASN1/asn1tostruct.py diff --git a/openair2/M2AP/MESSAGES/ASN1/R14/m2ap-14.0.0.asn1 b/openair2/M2AP/MESSAGES/ASN1/R14/m2ap-14.0.0.asn1 new file mode 100644 index 0000000000..997501f1a6 --- /dev/null +++ b/openair2/M2AP/MESSAGES/ASN1/R14/m2ap-14.0.0.asn1 @@ -0,0 +1,1897 @@ +-- 3GPP TS 36.443 V15.0.0 (2018-09) +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +M2AP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m2ap (4) version1 (1) m2ap-PDU-Descriptions (0) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + ProcedureCode +FROM M2AP-CommonDataTypes + + + SessionStartRequest, + SessionStartResponse, + SessionStartFailure, + SessionStopRequest, + SessionStopResponse, + SessionUpdateRequest, + SessionUpdateResponse, + SessionUpdateFailure, + MbmsSchedulingInformation, + MbmsSchedulingInformationResponse, + ErrorIndication, + Reset, + ResetAcknowledge, + M2SetupRequest, + M2SetupResponse, + M2SetupFailure, + ENBConfigurationUpdate, + ENBConfigurationUpdateAcknowledge, + ENBConfigurationUpdateFailure, + MCEConfigurationUpdate, + MCEConfigurationUpdateAcknowledge, + MCEConfigurationUpdateFailure, + MbmsServiceCountingRequest, + MbmsServiceCountingResponse, + MbmsServiceCountingFailure, + MbmsServiceCountingResultsReport, + PrivateMessage, + MbmsOverloadNotification +FROM M2AP-PDU-Contents + + id-sessionStart, + id-sessionStop, + id-sessionUpdate, + id-mbmsServiceCounting, + id-mbmsServiceCountingResultsReport, + id-mbmsSchedulingInformation, + id-errorIndication, + id-reset, + id-m2Setup, + id-eNBConfigurationUpdate, + id-mCEConfigurationUpdate, + id-privateMessage, + id-mbmsOverloadNotification +FROM M2AP-Constants; + + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +M2AP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +M2AP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode M2AP-ELEMENTARY-PROCEDURE.&procedureCode ({M2AP-ELEMENTARY-PROCEDURES}), + criticality M2AP-ELEMENTARY-PROCEDURE.&criticality ({M2AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M2AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({M2AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode M2AP-ELEMENTARY-PROCEDURE.&procedureCode ({M2AP-ELEMENTARY-PROCEDURES}), + criticality M2AP-ELEMENTARY-PROCEDURE.&criticality ({M2AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M2AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({M2AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode M2AP-ELEMENTARY-PROCEDURE.&procedureCode ({M2AP-ELEMENTARY-PROCEDURES}), + criticality M2AP-ELEMENTARY-PROCEDURE.&criticality ({M2AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M2AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({M2AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +M2AP-ELEMENTARY-PROCEDURES M2AP-ELEMENTARY-PROCEDURE ::= { + M2AP-ELEMENTARY-PROCEDURES-CLASS-1 | + M2AP-ELEMENTARY-PROCEDURES-CLASS-2 , + ... +} + +M2AP-ELEMENTARY-PROCEDURES-CLASS-1 M2AP-ELEMENTARY-PROCEDURE ::= { + sessionStart | + sessionStop | + sessionUpdate | + mbmsSchedulingInformation | + reset | + m2Setup | + eNBConfigurationUpdate | + mCEConfigurationUpdate | + mbmsServiceCounting , + ... +} + +M2AP-ELEMENTARY-PROCEDURES-CLASS-2 M2AP-ELEMENTARY-PROCEDURE ::= { + errorIndication | + privateMessage | + mbmsServiceCountingResultsReport | + mbmsOverloadNotification , + ... + +} + + +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +sessionStart M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE SessionStartRequest + SUCCESSFUL OUTCOME SessionStartResponse + UNSUCCESSFUL OUTCOME SessionStartFailure + PROCEDURE CODE id-sessionStart + CRITICALITY reject +} + +sessionStop M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE SessionStopRequest + SUCCESSFUL OUTCOME SessionStopResponse + PROCEDURE CODE id-sessionStop + CRITICALITY reject +} + +sessionUpdate M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE SessionUpdateRequest + SUCCESSFUL OUTCOME SessionUpdateResponse + UNSUCCESSFUL OUTCOME SessionUpdateFailure + PROCEDURE CODE id-sessionUpdate + CRITICALITY reject +} + +mbmsSchedulingInformation M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MbmsSchedulingInformation + SUCCESSFUL OUTCOME MbmsSchedulingInformationResponse + PROCEDURE CODE id-mbmsSchedulingInformation + CRITICALITY reject +} + +errorIndication M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-errorIndication + CRITICALITY ignore +} + +reset M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-reset + CRITICALITY reject +} + +m2Setup M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE M2SetupRequest + SUCCESSFUL OUTCOME M2SetupResponse + UNSUCCESSFUL OUTCOME M2SetupFailure + PROCEDURE CODE id-m2Setup + CRITICALITY reject +} + +eNBConfigurationUpdate M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ENBConfigurationUpdate + SUCCESSFUL OUTCOME ENBConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME ENBConfigurationUpdateFailure + PROCEDURE CODE id-eNBConfigurationUpdate + CRITICALITY reject +} + +mCEConfigurationUpdate M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MCEConfigurationUpdate + SUCCESSFUL OUTCOME MCEConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME MCEConfigurationUpdateFailure + PROCEDURE CODE id-mCEConfigurationUpdate + CRITICALITY reject +} + +mbmsServiceCounting M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MbmsServiceCountingRequest + SUCCESSFUL OUTCOME MbmsServiceCountingResponse + UNSUCCESSFUL OUTCOME MbmsServiceCountingFailure + PROCEDURE CODE id-mbmsServiceCounting + CRITICALITY reject +} + +mbmsServiceCountingResultsReport M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MbmsServiceCountingResultsReport + PROCEDURE CODE id-mbmsServiceCountingResultsReport + CRITICALITY reject +} + +privateMessage M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore +} + +mbmsOverloadNotification M2AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MbmsOverloadNotification + PROCEDURE CODE id-mbmsOverloadNotification + CRITICALITY reject +} + +END + +-- ************************************************************** +-- +-- PDU definitions for M2AP. +-- +-- ************************************************************** + +M2AP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m2ap (4) version1 (1) m2ap-PDU-Contents (1) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + Cause, + CriticalityDiagnostics, + ENB-MBMS-Configuration-data-Item, + ENB-MBMS-Configuration-data-ConfigUpdate-Item, + ENB-MBMS-M2AP-ID, + ENBname, + GlobalENB-ID, + GlobalMCE-ID, + MBSFN-Area-ID, + MBMS-Service-Area, + MBMS-Session-ID, + MBMSsessionListPerPMCH-Item, + MBMS-Service-associatedLogicalM2-ConnectionItem, + MBSFN-Subframe-Configuration, + MCCH-Update-Time, + MCCHrelatedBCCH-ConfigPerMBSFNArea-Item, + MCE-MBMS-M2AP-ID, + MCEname, + PMCH-Configuration, + Common-Subframe-Allocation-Period, + TimeToWait, + TMGI, + TNL-Information, + SFN, + MBMSsessionsToBeSuspendedListPerPMCH-Item, + SC-PTM-Information + +FROM M2AP-Ies + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerList{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-ContainerPairList{}, + ProtocolIE-Single-Container{}, + M2AP-PRIVATE-IES, + M2AP-PROTOCOL-EXTENSION, + M2AP-PROTOCOL-IES, + M2AP-PROTOCOL-IES-PAIR +FROM M2AP-Containers + + id-MCE-MBMS-M2AP-ID, + id-ENB-MBMS-M2AP-ID, + id-TMGI, + id-MBMS-Session-ID, + id-MBMS-Service-Area, + id-TNL-Information, + id-Alternative-TNL-Information, + id-CriticalityDiagnostics, + id-Cause, + id-MBSFN-Area-Configuration-List, + id-MBSFN-Subframe-Configuration-Item, + id-MBSFN-Subframe-Configuration-List, + id-MCCH-Update-Time, + id-PMCH-Configuration-List, + id-PMCH-Configuration-Item, + id-Common-Subframe-Allocation-Period, + id-GlobalENB-ID, + id-ENBname, + id-ENB-MBMS-Configuration-data-List, + id-ENB-MBMS-Configuration-data-Item, + id-GlobalMCE-ID, + id-MCEname, + id-MCCHrelatedBCCH-ConfigPerMBSFNArea, + id-MCCHrelatedBCCH-ConfigPerMBSFNArea-Item, + id-TimeToWait, + id-ENB-MBMS-Configuration-data-List-ConfigUpdate, + id-ENB-MBMS-Configuration-data-ConfigUpdate-Item, + id-MBSFN-Area-ID, + id-ResetType, + id-MBMS-Service-associatedLogicalM2-ConnectionItem, + id-MBMS-Service-associatedLogicalM2-ConnectionListResAck, + id-MBMS-Counting-Request-Session, + id-MBMS-Counting-Request-Session-Item, + id-MBMS-Counting-Result-List, + id-MBMS-Counting-Result-Item, + id-MBMS-Suspension-Notification-List, + id-MBMS-Suspension-Notification-Item, + id-PMCH-Overload-Status, + id-Overload-Status-Per-PMCH-List, + id-Active-MBMS-Session-List, + id-SC-PTM-Information, + maxnoofMBSFN-Allocations, + maxnoofMBSFNareas, + maxnoofPMCHsperMBSFNarea, + maxnoofCells, + maxnoofMBMSServiceAreasPerCell, + maxnoofSessionsPerPMCH, + maxnooferrors, + maxNrOfIndividualM2ConnectionsToReset, + maxnoofCountingService + +FROM M2AP-Constants; + +-- ************************************************************** +-- +-- SESSION START REQUEST +-- +-- ************************************************************** + +SessionStartRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{SessionStartRequest-Ies}}, + ... +} + +SessionStartRequest-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY reject TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-Service-Area CRITICALITY reject TYPE MBMS-Service-Area PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY reject TYPE TNL-Information PRESENCE mandatory}| + { ID id-Alternative-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-SC-PTM-Information CRITICALITY reject TYPE SC-PTM-Information PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- SESSION START RESPONSE +-- +-- ************************************************************** + +SessionStartResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ SessionStartResponse-Ies}}, + ... +} + +SessionStartResponse-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY ignore TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-ENB-MBMS-M2AP-ID CRITICALITY ignore TYPE ENB-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- SESSION START FAILURE +-- +-- ************************************************************** + +SessionStartFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ SessionStartFailure-Ies}}, + ... +} + +SessionStartFailure-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY ignore TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- SESSION STOP REQUEST +-- +-- ************************************************************** + +SessionStopRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{SessionStopRequest-Ies}}, + ... +} + +SessionStopRequest-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY reject TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-ENB-MBMS-M2AP-ID CRITICALITY reject TYPE ENB-MBMS-M2AP-ID PRESENCE mandatory } , + ... +} + +-- ************************************************************** +-- +-- SESSION STOP RESPONSE +-- +-- ************************************************************** + +SessionStopResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ SessionStopResponse-Ies}}, + ... +} + +SessionStopResponse-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY ignore TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-ENB-MBMS-M2AP-ID CRITICALITY ignore TYPE ENB-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... +} + +-- ************************************************************** +-- +-- SESSION UPDATE REQUEST +-- +-- ************************************************************** + +SessionUpdateRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{SessionUpdateRequest-Ies}}, + ... +} + +SessionUpdateRequest-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY reject TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory}| + { ID id-ENB-MBMS-M2AP-ID CRITICALITY reject TYPE ENB-MBMS-M2AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-Service-Area CRITICALITY ignore TYPE MBMS-Service-Area PRESENCE optional}| + { ID id-TNL-Information CRITICALITY reject TYPE TNL-Information PRESENCE optional}| + { ID id-SC-PTM-Information CRITICALITY reject TYPE SC-PTM-Information PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- SESSION UPDATE RESPONSE +-- +-- ************************************************************** + +SessionUpdateResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ SessionUpdateResponse-Ies}}, + ... +} + +SessionUpdateResponse-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY ignore TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-ENB-MBMS-M2AP-ID CRITICALITY ignore TYPE ENB-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} +-- ************************************************************** +-- +-- SESSION UPDATE FAILURE +-- +-- ************************************************************** + +SessionUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ SessionUpdateFailure-Ies}}, + ... +} + +SessionUpdateFailure-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY ignore TYPE MCE-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-ENB-MBMS-M2AP-ID CRITICALITY ignore TYPE ENB-MBMS-M2AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- MBMS SCHEDULING INFORMATION +-- +-- ************************************************************** + +MbmsSchedulingInformation ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MbmsSchedulingInformation-Ies}}, + ... +} + +MbmsSchedulingInformation-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCCH-Update-Time CRITICALITY reject TYPE MCCH-Update-Time PRESENCE mandatory }| + { ID id-MBSFN-Area-Configuration-List CRITICALITY reject TYPE MBSFN-Area-Configuration-List PRESENCE mandatory }, + ... +} + +MBSFN-Area-Configuration-List ::= SEQUENCE (SIZE(1.. maxnoofMBSFNareas)) OF ProtocolIE-Container { { MBSFN-Area-Configuration-Item } } + +MBSFN-Area-Configuration-Item M2AP-PROTOCOL-IES ::= { + { ID id-PMCH-Configuration-List CRITICALITY reject TYPE PMCH-Configuration-List PRESENCE mandatory }| + { ID id-MBSFN-Subframe-Configuration-List CRITICALITY reject TYPE MBSFN-Subframe-ConfigurationList PRESENCE mandatory }| + { ID id-Common-Subframe-Allocation-Period CRITICALITY reject TYPE Common-Subframe-Allocation-Period PRESENCE mandatory }| + { ID id-MBSFN-Area-ID CRITICALITY reject TYPE MBSFN-Area-ID PRESENCE mandatory }| + { ID id-MBMS-Suspension-Notification-List CRITICALITY ignore TYPE MBMS-Suspension-Notification-List PRESENCE optional }, + ... +} + +PMCH-Configuration-List ::= SEQUENCE (SIZE(0.. maxnoofPMCHsperMBSFNarea)) OF ProtocolIE-Single-Container { { PMCH-Configuration-ItemIEs } } + +PMCH-Configuration-ItemIEs M2AP-PROTOCOL-IES ::= { + { ID id-PMCH-Configuration-Item CRITICALITY reject TYPE PMCH-Configuration-Item PRESENCE mandatory }, + ... +} + +PMCH-Configuration-Item ::= SEQUENCE { + pmch-Configuration PMCH-Configuration, + mbms-Session-List MBMSsessionListPerPMCH-Item, + iE-Extensions ProtocolExtensionContainer { { PMCH-Configuration-ItemExtIEs} } OPTIONAL, + ... +} + +PMCH-Configuration-ItemExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBSFN-Subframe-ConfigurationList ::= SEQUENCE (SIZE(1.. maxnoofMBSFN-Allocations)) OF ProtocolIE-Single-Container { { MBSFN-Subframe-ConfigurationItem } } + +MBSFN-Subframe-ConfigurationItem M2AP-PROTOCOL-IES ::= { + { ID id-MBSFN-Subframe-Configuration-Item CRITICALITY reject TYPE MBSFN-Subframe-Configuration PRESENCE mandatory }, + ... +} + +MBMS-Suspension-Notification-List ::= SEQUENCE (SIZE(1.. maxnoofPMCHsperMBSFNarea)) OF ProtocolIE-Single-Container { { MBMS-Suspension-Notification-ItemIEs } } + +MBMS-Suspension-Notification-ItemIEs M2AP-PROTOCOL-IES ::= { + { ID id-MBMS-Suspension-Notification-Item CRITICALITY ignore TYPE MBMS-Suspension-Notification-Item PRESENCE optional}, + ... +} + +MBMS-Suspension-Notification-Item ::= SEQUENCE { + sfn SFN, + mbms-Sessions-To-Be-Suspended-List MBMSsessionsToBeSuspendedListPerPMCH-Item, + iE-Extensions ProtocolExtensionContainer { { MBMS-Suspension-Notification-ItemExtIEs} } OPTIONAL, + ... +} + +MBMS-Suspension-Notification-ItemExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- ************************************************************** +-- +-- MBMS SCHEDULING INFORMATION RESPONSE +-- +-- ************************************************************** + +MbmsSchedulingInformationResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MbmsSchedulingInformationResponse-Ies}}, + ... +} + +MbmsSchedulingInformationResponse-Ies M2AP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- M2 SETUP REQUEST +-- +-- ************************************************************** + +M2SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{M2SetupRequest-Ies}}, + ... +} + +M2SetupRequest-Ies M2AP-PROTOCOL-IES ::= { + { ID id-GlobalENB-ID CRITICALITY reject TYPE GlobalENB-ID PRESENCE mandatory}| + { ID id-ENBname CRITICALITY ignore TYPE ENBname PRESENCE optional}| + { ID id-ENB-MBMS-Configuration-data-List CRITICALITY reject TYPE ENB-MBMS-Configuration-data-List PRESENCE mandatory}, + ... +} + +ENB-MBMS-Configuration-data-List ::= SEQUENCE (SIZE(1.. maxnoofCells)) OF ProtocolIE-Single-Container { { ENB-MBMS-Configuration-data-ItemIEs } } + +ENB-MBMS-Configuration-data-ItemIEs M2AP-PROTOCOL-IES ::= { + { ID id-ENB-MBMS-Configuration-data-Item CRITICALITY reject TYPE ENB-MBMS-Configuration-data-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- M2 SETUP RESPONSE +-- +-- ************************************************************** + +M2SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ M2SetupResponse-Ies}}, + ... +} + +M2SetupResponse-Ies M2AP-PROTOCOL-IES ::= { + { ID id-GlobalMCE-ID CRITICALITY reject TYPE GlobalMCE-ID PRESENCE mandatory }| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional }| + { ID id-MCCHrelatedBCCH-ConfigPerMBSFNArea CRITICALITY reject TYPE MCCHrelatedBCCH-ConfigPerMBSFNArea PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +MCCHrelatedBCCH-ConfigPerMBSFNArea ::= SEQUENCE (SIZE(1.. maxnoofMBSFNareas)) OF ProtocolIE-Single-Container { { MCCHrelatedBCCH-ConfigPerMBSFNArea-ItemIEs } } + +MCCHrelatedBCCH-ConfigPerMBSFNArea-ItemIEs M2AP-PROTOCOL-IES ::= { + { ID id-MCCHrelatedBCCH-ConfigPerMBSFNArea-Item CRITICALITY reject TYPE MCCHrelatedBCCH-ConfigPerMBSFNArea-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- M2 SETUP FAILURE +-- +-- ************************************************************** + +M2SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ M2SetupFailure-Ies}}, + ... +} + +M2SetupFailure-Ies M2AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + + ... +} + +-- ************************************************************** +-- +-- ENB CONFIGURATION UPDATE +-- +-- ************************************************************** + +ENBConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ENBConfigurationUpdate-Ies}}, + ... +} + +ENBConfigurationUpdate-Ies M2AP-PROTOCOL-IES ::= { + { ID id-GlobalENB-ID CRITICALITY reject TYPE GlobalENB-ID PRESENCE optional }| + { ID id-ENBname CRITICALITY ignore TYPE ENBname PRESENCE optional }| + { ID id-ENB-MBMS-Configuration-data-List-ConfigUpdate CRITICALITY reject TYPE ENB-MBMS-Configuration-data-List-ConfigUpdate PRESENCE optional }, + ... +} +ENB-MBMS-Configuration-data-List-ConfigUpdate ::= SEQUENCE (SIZE(1.. maxnoofCells)) OF ProtocolIE-Single-Container { { ENB-MBMS-Configuration-data-ConfigUpdate-ItemIEs } } + +ENB-MBMS-Configuration-data-ConfigUpdate-ItemIEs M2AP-PROTOCOL-IES ::= { + { ID id-ENB-MBMS-Configuration-data-ConfigUpdate-Item CRITICALITY reject TYPE ENB-MBMS-Configuration-data-ConfigUpdate-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- ENB CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +ENBConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ ENBConfigurationUpdateAcknowledge-Ies}}, + ... +} + +ENBConfigurationUpdateAcknowledge-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCCHrelatedBCCH-ConfigPerMBSFNArea CRITICALITY reject TYPE MCCHrelatedBCCH-ConfigPerMBSFNArea PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- ENB CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +ENBConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ ENBConfigurationUpdateFailure-Ies}}, + ... +} + +ENBConfigurationUpdateFailure-Ies M2AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + + ... +} + + +-- ************************************************************** +-- +-- MCE CONFIGURATION UPDATE +-- +-- ************************************************************** + +MCEConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MCEConfigurationUpdate-Ies}}, + ... +} + +MCEConfigurationUpdate-Ies M2AP-PROTOCOL-IES ::= { + { ID id-GlobalMCE-ID CRITICALITY reject TYPE GlobalMCE-ID PRESENCE optional }| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional }| + { ID id-MCCHrelatedBCCH-ConfigPerMBSFNArea CRITICALITY reject TYPE MCCHrelatedBCCH-ConfigPerMBSFNArea PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- MCE CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +MCEConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MCEConfigurationUpdateAcknowledge-Ies}}, + ... +} + +MCEConfigurationUpdateAcknowledge-Ies M2AP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + + +-- ************************************************************** +-- +-- MCE CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +MCEConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MCEConfigurationUpdateFailure-Ies}}, + ... +} + +MCEConfigurationUpdateFailure-Ies M2AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + + ... +} + + +-- ************************************************************** +-- +-- ERROR INDICATION +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ErrorIndication-Ies}}, + ... +} + +ErrorIndication-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCE-MBMS-M2AP-ID CRITICALITY ignore TYPE MCE-MBMS-M2AP-ID PRESENCE optional}| + { ID id-ENB-MBMS-M2AP-ID CRITICALITY ignore TYPE ENB-MBMS-M2AP-ID PRESENCE optional}| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- RESET +-- +-- ************************************************************** + +Reset ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{Reset-Ies}}, + ... +} + +Reset-Ies M2AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory}, + ... +} + +ResetType ::= CHOICE { + m2-Interface ResetAll, + partOfM2-Interface MBMS-Service-associatedLogicalM2-ConnectionListRes, + ... +} + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +MBMS-Service-associatedLogicalM2-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM2ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM2-ConnectionItemRes } } + +MBMS-Service-associatedLogicalM2-ConnectionItemRes M2AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM2-ConnectionItem CRITICALITY reject TYPE MBMS-Service-associatedLogicalM2-ConnectionItem PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- RESET ACKNOWLEDGE +-- +-- ************************************************************** + +ResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ResetAcknowledge-Ies}}, + ... +} + +ResetAcknowledge-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM2-ConnectionListResAck CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM2-ConnectionListResAck PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +MBMS-Service-associatedLogicalM2-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM2ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM2-ConnectionItemResAck } } + +MBMS-Service-associatedLogicalM2-ConnectionItemResAck M2AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM2-ConnectionItem CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM2-ConnectionItem PRESENCE mandatory}, + ... +} + + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container {{PrivateMessage-Ies}}, + ... +} + +PrivateMessage-Ies M2AP-PRIVATE-IES ::= { + ... +} + + +-- ************************************************************** +-- +-- MBMS SERVICE COUNTING REQUEST +-- +-- ************************************************************** + +MbmsServiceCountingRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MbmsServiceCountingRequest-Ies}}, + ... +} + +MbmsServiceCountingRequest-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MCCH-Update-Time CRITICALITY reject TYPE MCCH-Update-Time PRESENCE mandatory }| + { ID id-MBSFN-Area-ID CRITICALITY reject TYPE MBSFN-Area-ID PRESENCE mandatory }| + { ID id-MBMS-Counting-Request-Session CRITICALITY reject TYPE MBMS-Counting-Request-Session PRESENCE mandatory }, + ... +} + +MBMS-Counting-Request-Session ::= SEQUENCE (SIZE(1.. maxnoofCountingService)) OF ProtocolIE-Container { { MBMS-Counting-Request-Session-Item } } + +MBMS-Counting-Request-Session-Item M2AP-PROTOCOL-IES ::= { + { ID id-MBMS-Counting-Request-Session-Item CRITICALITY reject TYPE MBMS-Counting-Request-SessionIE PRESENCE mandatory }, + ... +} + +MBMS-Counting-Request-SessionIE ::= SEQUENCE{ + tmgi TMGI, + iE-Extensions ProtocolExtensionContainer { { MBMS-Counting-Request-SessionIE-ExtIEs} } OPTIONAL, + ... +} + +MBMS-Counting-Request-SessionIE-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- ************************************************************** +-- +-- MBMS SERVICE COUNTING RESPONSE +-- +-- ************************************************************** + +MbmsServiceCountingResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MbmsServiceCountingResponse-Ies}}, + ... +} + +MbmsServiceCountingResponse-Ies M2AP-PROTOCOL-IES ::= { + + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- MBMS SERVICE COUNTING FAILURE +-- +-- ************************************************************** + +MbmsServiceCountingFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MbmsServiceCountingFailure-Ies}}, + ... +} + +MbmsServiceCountingFailure-Ies M2AP-PROTOCOL-IES ::= { + + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + + +-- ************************************************************** +-- +-- MBMS SERVICE COUNTING RESULTS REPORT +-- +-- ************************************************************** + +MbmsServiceCountingResultsReport ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MbmsServiceCountingResultsReport-Ies}}, + ... +} + +MbmsServiceCountingResultsReport-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MBSFN-Area-ID CRITICALITY reject TYPE MBSFN-Area-ID PRESENCE mandatory}| + { ID id-MBMS-Counting-Result-List CRITICALITY reject TYPE MBMS-Counting-Result-List PRESENCE mandatory}, + ... +} + +MBMS-Counting-Result-List ::= SEQUENCE (SIZE(1.. maxnoofCountingService)) OF ProtocolIE-Container { { MBMS-Counting-Result-Item } } + +MBMS-Counting-Result-Item M2AP-PROTOCOL-IES ::= { + { ID id-MBMS-Counting-Result-Item CRITICALITY reject TYPE MBMS-Counting-Result PRESENCE mandatory }, + ... +} + +MBMS-Counting-Result ::= SEQUENCE{ + tmgi TMGI, + countingResult CountingResult, + iE-Extensions ProtocolExtensionContainer { { MBMS-Counting-Result-ExtIEs} } OPTIONAL, + ... +} + +MBMS-Counting-Result-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +CountingResult ::= INTEGER (0..1023) + +-- ************************************************************** +-- +-- MBMS OVERLOAD NOTIFICATION +-- +-- ************************************************************** + +MbmsOverloadNotification ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MbmsOverloadNotification-Ies}}, + ... +} + +MbmsOverloadNotification-Ies M2AP-PROTOCOL-IES ::= { + { ID id-MBSFN-Area-ID CRITICALITY reject TYPE MBSFN-Area-ID PRESENCE mandatory}| + { ID id-Overload-Status-Per-PMCH-List CRITICALITY reject TYPE Overload-Status-Per-PMCH-List PRESENCE mandatory}, + ... +} + +Overload-Status-Per-PMCH-List ::= SEQUENCE (SIZE(1..maxnoofPMCHsperMBSFNarea)) OF ProtocolIE-Container { { Overload-Status-Per-PMCH-Item } } + +Overload-Status-Per-PMCH-Item M2AP-PROTOCOL-IES ::= { + { ID id-PMCH-Overload-Status CRITICALITY reject TYPE PMCH-Overload-Status PRESENCE mandatory }| + { ID id-Active-MBMS-Session-List CRITICALITY reject TYPE Active-MBMS-Session-List PRESENCE optional }, + ... +} + +PMCH-Overload-Status ::= ENUMERATED {normal, overload, ...} + +Active-MBMS-Session-List ::= SEQUENCE (SIZE(1..maxnoofSessionsPerPMCH)) OF ProtocolIE-Container { { Active-MBMS-Session-Item } } + +Active-MBMS-Session-Item M2AP-PROTOCOL-IES ::= { + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory }, + ... +} + +END + +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +M2AP-Ies { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m2ap (4) version1 (1) m2ap-Ies (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + id-MCH-Scheduling-PeriodExtended, + id-MCH-Scheduling-PeriodExtended2, + id-Modification-PeriodExtended, + id-Modulation-Coding-Scheme2, + id-Repetition-PeriodExtended, + id-Subcarrier-SpacingMBMS, + id-SubframeAllocationExtended, + maxnoofMBSFNareas, + maxnoofPMCHsperMBSFNarea, + maxnoofCells, + maxnoofMBMSServiceAreasPerCell, + maxnoofSessionsPerPMCH, + maxnooferrors, + maxnoofCellsforMBMS + +FROM M2AP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage +FROM M2AP-CommonDataTypes + + ProtocolExtensionContainer{}, + ProtocolIE-Single-Container{}, + M2AP-PROTOCOL-EXTENSION, + M2AP-PROTOCOL-IES +FROM M2AP-Containers; + +-- A + +AllocatedSubframesEnd ::= INTEGER (0..1535) + +AllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL +} + +AllocationAndRetentionPriority-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- B + +BitRate ::= INTEGER (0..10000000000) + +-- C + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + nAS CauseNAS, + protocol CauseProtocol, + misc CauseMisc, + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + hardware-failure, + om-intervention, + unspecified, + ... +} + +CauseNAS ::= ENUMERATED { + unspecified, + ... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unknown-or-already-allocated-MCE-MBMS-M2AP-ID, + unknown-or-already-allocated-eNB-MBMS-M2AP-ID, + unknown-or-inconsistent-pair-of-MBMS-M2AP-IDs, + radio-resources-not-available, + interaction-with-other-procedure, + unspecified, + ..., + invalid-QoS-combination, + not-supported-QCI-value + +} + +CauseTransport ::= ENUMERATED { + transport-resource-unavailable, + unspecified, + ... +} + +Cell-Information ::= SEQUENCE { + eCGI ECGI, + cellReservationInfo ENUMERATED {reservedCell, nonReservedCell, ...}, + iE-Extensions ProtocolExtensionContainer { { Cell-Information-ExtIEs} } OPTIONAL, + ... +} + +Cell-Information-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cell-Information-List ::= SEQUENCE (SIZE(1..maxnoofCells)) OF Cell-Information + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, + ... +} + + +CriticalityDiagnostics-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxnooferrors)) OF + SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-List-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + + +-- D +-- E + +ECGI ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + eUTRANcellIdentifier EUTRANCellIdentifier, + iE-Extensions ProtocolExtensionContainer { {ECGI-ExtIEs} } OPTIONAL, + ... +} + +ECGI-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + + +ENB-ID ::= CHOICE { + macro-eNB-ID BIT STRING (SIZE (20)), + ... , + short-Macro-eNB-ID BIT STRING (SIZE(18)), + long-Macro-eNB-ID BIT STRING (SIZE(21)) +} + +ENB-MBMS-Configuration-data-Item ::= SEQUENCE { + eCGI ECGI, + mbsfnSynchronisationArea MBSFN-SynchronisationArea-ID, + mbmsServiceAreaList MBMS-Service-Area-ID-List, + iE-Extensions ProtocolExtensionContainer { { ENB-MBMS-Configuration-data-Item-ExtIEs} } OPTIONAL, + ... +} + +ENB-MBMS-Configuration-data-Item-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +ENB-MBMS-Configuration-data-ConfigUpdate-Item ::= CHOICE { + mBMSConfigData ENB-MBMS-Configuration-data-Item, + eCGI ECGI, + ... +} + +ENB-MBMS-M2AP-ID ::= INTEGER (0..65535) + +ENBname ::= PrintableString (SIZE (1..150,...)) + +EUTRANCellIdentifier ::= BIT STRING (SIZE (28)) + + +-- F +-- G + +GBR-QosInformation ::= SEQUENCE { + mBMS-E-RAB-MaximumBitrateDL BitRate, + mBMS-E-RAB-GuaranteedBitrateDL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +GlobalENB-ID ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + eNB-ID ENB-ID, + iE-Extensions ProtocolExtensionContainer { {GlobalENB-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalENB-ID-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +GlobalMCE-ID ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + mCE-ID MCE-ID, + iE-Extensions ProtocolExtensionContainer { {GlobalMCE-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalMCE-ID-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +GTP-TEID ::= OCTET STRING (SIZE (4)) + +-- H +-- I + +IPAddress ::= OCTET STRING (SIZE(4..16)) + +-- J +-- K +-- L + +LCID ::= INTEGER (0..28) + +-- M + +MBMS-Cell-List ::= SEQUENCE (SIZE(1.. maxnoofCellsforMBMS)) OF ECGI + +MBMS-E-RAB-QoS-Parameters ::= SEQUENCE { + qCI QCI, + gbrQosInformation GBR-QosInformation OPTIONAL, + allocationAndRetentionPriority AllocationAndRetentionPriority, + iE-Extensions ProtocolExtensionContainer { { MBMS-E-RAB-QoS-Parameters-ExtIEs} } OPTIONAL, + ... +} + +MBMS-E-RAB-QoS-Parameters-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBMS-Service-associatedLogicalM2-ConnectionItem ::= SEQUENCE { + eNB-MBMS-M2AP-ID ENB-MBMS-M2AP-ID OPTIONAL, + mCE-MBMS-M2AP-ID MCE-MBMS-M2AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-Service-associatedLogicalM2-ConnectionItemExtIEs} } OPTIONAL, + ... +} + + +MBMS-Service-associatedLogicalM2-ConnectionItemExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBMS-Service-Area ::= OCTET STRING + +MBMS-Service-Area-ID-List ::= SEQUENCE (SIZE(1..maxnoofMBMSServiceAreasPerCell)) OF MBMS-Service-Area + +MBMS-Session-ID ::= OCTET STRING (SIZE (1)) + +MBMSsessionListPerPMCH-Item ::= SEQUENCE (SIZE(1..maxnoofSessionsPerPMCH)) OF SEQUENCE { + tmgi TMGI, + lcid LCID, + iE-Extensions ProtocolExtensionContainer { { MBMSsessionListPerPMCH-Item-ExtIEs} } OPTIONAL, + ... +} + +MBMSsessionListPerPMCH-Item-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBMSsessionsToBeSuspendedListPerPMCH-Item ::= SEQUENCE (SIZE(1..maxnoofSessionsPerPMCH)) OF SEQUENCE { + tmgi TMGI, + iE-Extensions ProtocolExtensionContainer { { MBMSsessionsToBeSuspendedListPerPMCH-Item-ExtIEs} } OPTIONAL, + ... +} + +MBMSsessionsToBeSuspendedListPerPMCH-Item-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBSFN-Area-ID ::= INTEGER (0..255) + +MBSFN-SynchronisationArea-ID ::= INTEGER (0..65535) + +MBSFN-Subframe-Configuration ::= SEQUENCE { + radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32}, + radioframeAllocationOffset INTEGER (0..7), + subframeAllocation CHOICE { + oneFrame BIT STRING (SIZE (6) ), + fourFrames BIT STRING (SIZE (24) ) }, + iE-Extensions ProtocolExtensionContainer { { MBSFN-Subframe-Configuration-ExtIEs} } OPTIONAL, + ... +} + +MBSFN-Subframe-Configuration-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + {ID id-SubframeAllocationExtended CRITICALITY reject EXTENSION SubframeAllocationExtended PRESENCE optional}, + ... +} + +MCCH-Update-Time ::= INTEGER (0..255) + +MCCHrelatedBCCH-ConfigPerMBSFNArea-Item ::= SEQUENCE { + mbsfnArea MBSFN-Area-ID, + pdcchLength ENUMERATED {s1, s2, ...}, + repetitionPeriod ENUMERATED {rf32, rf64, rf128, rf256}, + offset INTEGER (0..10), + modificationPeriod ENUMERATED {rf512, rf1024}, + subframeAllocationInfo BIT STRING (SIZE(6)), + modulationAndCodingScheme ENUMERATED {n2, n7, n13, n19}, + cellInformationList Cell-Information-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MCCHrelatedBCCH-ConfigPerMBSFNArea-Item-ExtIEs} } OPTIONAL, + ... +} + +MCCHrelatedBCCH-ConfigPerMBSFNArea-Item-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { +-- Extension for Rel-14 to support MCCH repetition period values –- + {ID id-Repetition-PeriodExtended CRITICALITY reject EXTENSION Repetition-PeriodExtended PRESENCE optional}| +-- Extension for Rel-14 to support MCCH modification period values –- + {ID id-Modification-PeriodExtended CRITICALITY reject EXTENSION Modification-PeriodExtended PRESENCE optional}| + {ID id-Subcarrier-SpacingMBMS CRITICALITY reject EXTENSION Subcarrier-SpacingMBMS PRESENCE optional}, + ... +} + +MCE-ID ::= OCTET STRING (SIZE(2)) + +MCE-MBMS-M2AP-ID ::= INTEGER (0.. 16777215) + +MCEname ::= PrintableString (SIZE (1..150,...)) + + +MCH-Scheduling-Period ::= ENUMERATED {rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024} + +MCH-Scheduling-PeriodExtended ::= ENUMERATED {rf4, ...} + +MCH-Scheduling-PeriodExtended2 ::= ENUMERATED {rf1, rf2, ...} + + +Modulation-Coding-Scheme2 ::= INTEGER (0..27) + +Modification-PeriodExtended ::= ENUMERATED {rf1, rf2, rf4, rf8, rf16, rf32, rf64, rf128, rf256, ...} + +-- N +-- O +-- P + +PLMN-Identity ::= OCTET STRING (SIZE(3)) + +PMCH-Configuration ::= SEQUENCE { + allocatedSubframesEnd AllocatedSubframesEnd, + dataMCS INTEGER (0..28), + mchSchedulingPeriod MCH-Scheduling-Period, + iE-Extensions ProtocolExtensionContainer { {PMCH-Configuration-ExtIEs} } OPTIONAL, + ... +} + +PMCH-Configuration-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { +-- Extension for Rel-12 to support 256QAM for MTCH – + {ID id-Modulation-Coding-Scheme2 CRITICALITY reject EXTENSION Modulation-Coding-Scheme2 PRESENCE optional}| +-- Extension for Rel-12 to support shorter MCH scheduling period – + {ID id-MCH-Scheduling-PeriodExtended CRITICALITY reject EXTENSION MCH-Scheduling-PeriodExtended PRESENCE optional}| +-- Extension for Rel-14 to support shorter MCH scheduling period values – + {ID id-MCH-Scheduling-PeriodExtended2 CRITICALITY reject EXTENSION MCH-Scheduling-PeriodExtended2 PRESENCE optional}, + ... +} + +Common-Subframe-Allocation-Period ::= ENUMERATED {rf4, rf8, rf16, rf32, rf64, rf128, rf256} + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable +} + +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) + +-- Q + +QCI ::= INTEGER (0..255) + +-- R + +Repetition-PeriodExtended ::= ENUMERATED {rf1, rf2, rf4, rf8, rf16, ...} + +-- S + +SC-PTM-Information ::= SEQUENCE { + mbmsCellList MBMS-Cell-List, + mbms-E-RAB-QoS-Parameters MBMS-E-RAB-QoS-Parameters, + iE-Extensions ProtocolExtensionContainer { {SC-PTM-Information-ExtIEs} } OPTIONAL, + ... +} + +SC-PTM-Information-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +SFN ::= INTEGER (0..1023) + +Subcarrier-SpacingMBMS ::= ENUMERATED {khz-7dot5, khz-1dot25, ...} + +SubframeAllocationExtended ::= CHOICE { + oneFrameExtension BIT STRING (SIZE(2)), + fourFrameExtension BIT STRING (SIZE(8)), + choice-extension ProtocolIE-Single-Container { { SubframeAllocationExtended-ExtIEs} }, + + ... +} + + +SubframeAllocationExtended-ExtIEs M2AP-PROTOCOL-IES ::= { ... +} + +-- T + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TMGI ::= SEQUENCE { + pLMNidentity PLMN-Identity, + serviceID OCTET STRING (SIZE (3)), + iE-Extensions ProtocolExtensionContainer { {TMGI-ExtIEs} } OPTIONAL, + ... +} + +TMGI-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + + +TNL-Information ::= SEQUENCE { + iPMCAddress IPAddress, + iPSourceAddress IPAddress, + gTP-TEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { {TNL-Information-ExtIEs} } OPTIONAL, + ... +} + +TNL-Information-ExtIEs M2AP-PROTOCOL-EXTENSION ::= { + ... +} + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + + +-- U +-- V +-- W +-- X +-- Y +-- Z + +END + +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +M2AP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m2ap (4) version1 (1) m2ap-CommonDataTypes (3) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 + +-- ************************************************************** +-- +-- Common Data Types +-- +-- ************************************************************** + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0.. maxPrivateIEs), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + + +ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs) + + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome} + +END + +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + +M2AP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m2ap (4) version1 (1) m2ap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + ProcedureCode, + ProtocolIE-ID +FROM M2AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-sessionStart ProcedureCode ::= 0 +id-sessionStop ProcedureCode ::= 1 +id-mbmsSchedulingInformation ProcedureCode ::= 2 +id-errorIndication ProcedureCode ::= 3 +id-reset ProcedureCode ::= 4 +id-m2Setup ProcedureCode ::= 5 +id-eNBConfigurationUpdate ProcedureCode ::= 6 +id-mCEConfigurationUpdate ProcedureCode ::= 7 +id-privateMessage ProcedureCode ::= 8 +id-sessionUpdate ProcedureCode ::= 9 +id-mbmsServiceCounting ProcedureCode ::= 10 +id-mbmsServiceCountingResultsReport ProcedureCode ::= 11 +id-mbmsOverloadNotification ProcedureCode ::= 12 + +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + +maxnoofMBSFNareas INTEGER ::= 256 +maxnoofMBSFN-Allocations INTEGER ::= 8 +maxnoofPMCHsperMBSFNarea INTEGER ::= 15 +maxnoofCells INTEGER ::= 256 +maxnoofMBMSServiceAreasPerCell INTEGER ::= 256 +maxnoofSessionsPerPMCH INTEGER ::= 29 +maxnooferrors INTEGER ::= 256 +maxNrOfIndividualM2ConnectionsToReset INTEGER ::= 256 +maxnoofCountingService INTEGER ::= 16 +maxnoofCellsforMBMS INTEGER ::= 4096 + + +-- ************************************************************** +-- +-- Ies +-- +-- ************************************************************** + +id-MCE-MBMS-M2AP-ID ProtocolIE-ID ::= 0 +id-ENB-MBMS-M2AP-ID ProtocolIE-ID ::= 1 +id-TMGI ProtocolIE-ID ::= 2 +id-MBMS-Session-ID ProtocolIE-ID ::= 3 +id-MBMS-Service-Area ProtocolIE-ID ::= 6 +id-TNL-Information ProtocolIE-ID ::= 7 +id-CriticalityDiagnostics ProtocolIE-ID ::= 8 +id-Cause ProtocolIE-ID ::= 9 +id-MBSFN-Area-Configuration-List ProtocolIE-ID ::= 10 +id-PMCH-Configuration-List ProtocolIE-ID ::= 11 +id-PMCH-Configuration-Item ProtocolIE-ID ::= 12 +id-GlobalENB-ID ProtocolIE-ID ::= 13 +id-ENBname ProtocolIE-ID ::= 14 +id-ENB-MBMS-Configuration-data-List ProtocolIE-ID ::= 15 +id-ENB-MBMS-Configuration-data-Item ProtocolIE-ID ::= 16 +id-GlobalMCE-ID ProtocolIE-ID ::= 17 +id-MCEname ProtocolIE-ID ::= 18 +id-MCCHrelatedBCCH-ConfigPerMBSFNArea ProtocolIE-ID ::= 19 +id-MCCHrelatedBCCH-ConfigPerMBSFNArea-Item ProtocolIE-ID ::= 20 +id-TimeToWait ProtocolIE-ID ::= 21 +id-MBSFN-Subframe-Configuration-List ProtocolIE-ID ::= 22 +id-MBSFN-Subframe-Configuration-Item ProtocolIE-ID ::= 23 +id-Common-Subframe-Allocation-Period ProtocolIE-ID ::= 24 +id-MCCH-Update-Time ProtocolIE-ID ::= 25 +id-ENB-MBMS-Configuration-data-List-ConfigUpdate ProtocolIE-ID ::= 26 +id-ENB-MBMS-Configuration-data-ConfigUpdate-Item ProtocolIE-ID ::= 27 +id-MBMS-Service-associatedLogicalM2-ConnectionItem ProtocolIE-ID ::= 28 +id-MBSFN-Area-ID ProtocolIE-ID ::= 29 +id-ResetType ProtocolIE-ID ::= 30 +id-MBMS-Service-associatedLogicalM2-ConnectionListResAck ProtocolIE-ID ::= 31 +id-MBMS-Counting-Request-Session ProtocolIE-ID ::= 32 +id-MBMS-Counting-Request-Session-Item ProtocolIE-ID ::= 33 +id-MBMS-Counting-Result-List ProtocolIE-ID ::= 34 +id-MBMS-Counting-Result-Item ProtocolIE-ID ::= 35 +id-Modulation-Coding-Scheme2 ProtocolIE-ID ::= 36 +id-MCH-Scheduling-PeriodExtended ProtocolIE-ID ::= 37 +id-Alternative-TNL-Information ProtocolIE-ID ::= 38 +id-Overload-Status-Per-PMCH-List ProtocolIE-ID ::= 39 +id-PMCH-Overload-Status ProtocolIE-ID ::= 41 +id-Active-MBMS-Session-List ProtocolIE-ID ::= 42 +id-MBMS-Suspension-Notification-List ProtocolIE-ID ::= 43 +id-MBMS-Suspension-Notification-Item ProtocolIE-ID ::= 44 +id-SC-PTM-Information ProtocolIE-ID ::= 45 +id-Modification-PeriodExtended ProtocolIE-ID ::= 46 +id-Repetition-PeriodExtended ProtocolIE-ID ::= 47 +id-MCH-Scheduling-PeriodExtended2 ProtocolIE-ID ::= 48 +id-Subcarrier-SpacingMBMS ProtocolIE-ID ::= 49 +id-SubframeAllocationExtended ProtocolIE-ID ::= 50 + +END + + +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +M2AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m2ap (4) version1 (1) m2ap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs, + Criticality, + Presence, + PrivateIE-ID, + ProtocolIE-ID +FROM M2AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Class Definition for Protocol Ies +-- +-- ************************************************************** + +M2AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Ies +-- +-- ************************************************************** + +M2AP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +M2AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private Ies +-- +-- ************************************************************** + +M2AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol Ies +-- +-- ************************************************************** + +ProtocolIE-Container {M2AP-PROTOCOL-IES : IesSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IesSetParam}} + +ProtocolIE-Single-Container {M2AP-PROTOCOL-IES : IesSetParam} ::= + ProtocolIE-Field {{IesSetParam}} + +ProtocolIE-Field {M2AP-PROTOCOL-IES : IesSetParam} ::= SEQUENCE { + id M2AP-PROTOCOL-IES.&id ({IesSetParam}), + criticality M2AP-PROTOCOL-IES.&criticality ({IesSetParam}{@id}), + value M2AP-PROTOCOL-IES.&Value ({IesSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {M2AP-PROTOCOL-IES-PAIR : IesSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IesSetParam}} + +ProtocolIE-FieldPair {M2AP-PROTOCOL-IES-PAIR : IesSetParam} ::= SEQUENCE { + id M2AP-PROTOCOL-IES-PAIR.&id ({IesSetParam}), + firstCriticality M2AP-PROTOCOL-IES-PAIR.&firstCriticality ({IesSetParam}{@id}), + firstValue M2AP-PROTOCOL-IES-PAIR.&FirstValue ({IesSetParam}{@id}), + secondCriticality M2AP-PROTOCOL-IES-PAIR.&secondCriticality ({IesSetParam}{@id}), + secondValue M2AP-PROTOCOL-IES-PAIR.&SecondValue ({IesSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container Lists for Protocol IE Containers +-- +-- ************************************************************** + +ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, M2AP-PROTOCOL-IES : IesSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-Container {{IesSetParam}} + +ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, M2AP-PROTOCOL-IES-PAIR : IesSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-ContainerPair {{IesSetParam}} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {M2AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {M2AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id M2AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality M2AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue M2AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private Ies +-- +-- ************************************************************** + +PrivateIE-Container {M2AP-PRIVATE-IES : IesSetParam} ::= + SEQUENCE (SIZE (1..maxPrivateIEs)) OF + PrivateIE-Field {{IesSetParam}} + +PrivateIE-Field {M2AP-PRIVATE-IES : IesSetParam} ::= SEQUENCE { + id M2AP-PRIVATE-IES.&id ({IesSetParam}), + criticality M2AP-PRIVATE-IES.&criticality ({IesSetParam}{@id}), + value M2AP-PRIVATE-IES.&Value ({IesSetParam}{@id}) +} + +END + + diff --git a/openair2/M2AP/MESSAGES/asn1tostruct.py b/openair2/M2AP/MESSAGES/asn1tostruct.py new file mode 100644 index 0000000000..8c0f7e8a16 --- /dev/null +++ b/openair2/M2AP/MESSAGES/asn1tostruct.py @@ -0,0 +1,697 @@ +import re, os, sys, string +import datetime +import getopt +import getpass + +version = "1.0.2" + +lines = "" +iesDefs = {} +ieofielist = {} +outdir = './' + +filenames = [] +verbosity = 0 +prefix = "" + +FAIL = '\033[91m' +WARN = '\033[93m' +ENDC = '\033[0m' + +fileprefix = "" +fileprefix_first_upper = "" + +def printFail(string): + sys.stderr.write(FAIL + string + ENDC + "\n") + +def printWarning(string): + print WARN + string + ENDC + +def printDebug(string): + if verbosity > 0: + print string + +def outputHeaderToFile(f, filename): + now = datetime.datetime.now() + f.write("""/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +""") + f.write("/*******************************************************************************\n") + f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version)) + f.write(" * Please do not modify this file but regenerate it via script.\n") + f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames)) + f.write(" ******************************************************************************/\n") + +def lowerFirstCamelWord(word): + """ puts the first word in a CamelCase Word in lowercase. + + I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest + """ + newstr = '' + swapped = word.swapcase() + idx = 0 + + # if it's all-caps, return an all-lowered version + lowered = word.lower() + + if swapped == lowered: + return lowered + + for c in swapped: + if c in string.lowercase: + newstr += c + idx += 1 + else: + break + if idx < 2: + newstr += word[idx:] + else: + newstr = newstr[:-1]+ word[idx-1:] + + return newstr + +def usage(): + print "Python parser for asn1 v%s" % (version) + print "Usage: python asn1tostruct.py [options]" + print "Available options:" + print "-d Enable script debug" + print "-f [file] Input file to parse" + print "-o [dir] Output files to given directory" + print "-h Print this help and return" + +try: + opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"]) +except getopt.GetoptError as err: + # print help information and exit: + usage() + sys.exit(2) + +for o, a in opts: + if o in ("-f", "--file"): + filenames.append(a) + if o in ("-d", "--debug"): + verbosity = 1 + if o in ("-o", "--outdir"): + outdir = a + if outdir.rfind('/') != len(outdir): + outdir += '/' + if o in ("-h", "--help"): + usage() + sys.exit(2) + +for filename in filenames: + file = open(filename, 'r') + for line in file: + # Removing any comment + if line.find('--') >= 0: + line = line[:line.find('--')] + # Removing any carriage return + lines += re.sub('\r', '', line) + + for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE): + ieofielist[m[0]] = m[1] + for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE): + ieofielist[m[0]] = m[1] + + for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n', lines, re.MULTILINE): + ies = [] + maxLength = 0 + # TODO: handle extensions + if i[1].find('EXTENSION') >= 0: + continue + if fileprefix == "": + fileprefix = i[1][:i[1].find('-')].lower() + for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE): + for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE): + printDebug("Got new ie for message " + i[0] + ": " + str(k)) + if len(k[2]) > maxLength: + maxLength = len(k[2]) + ies.append(k) + + if len(ies) > 0: + iesDefs[i[0]] = { "length": maxLength, "ies": ies } + else: + printWarning("Didn't find any information element for message: " + i[0]) + +if len(iesDefs) == 0: + printFail("No Information Element parsed, exiting") + sys.exit(0) + +fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:] + +f = open(outdir + fileprefix + '_ies_defs.h', 'w') +outputHeaderToFile(f, filename) +f.write("#include \"%s_common.h\"\n\n" % (fileprefix)) +f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper())) +f.write("/* Define the version of script used to generate this file */\n") +f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version))) + +for key in iesDefs: + + if key not in ieofielist.values(): + continue + + for (i, j) in ieofielist.items(): + if j == key: + break + + f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i))) + f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i]))))) + f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i))) + +for key in iesDefs: + keyupperunderscore = re.sub('-', '_', key.upper()) + keylowerunderscore = re.sub('-', '_', key.lower()) + shift = 0 + + if len(iesDefs[key]["ies"]) == 0: + continue + + # Presence mask + for ie in iesDefs[key]["ies"]: + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] == "optional" or ie[3] == "conditional": + f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift, + pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9)) + shift += 1 + if (shift > 0): + f.write("\n") + + f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key))) + if (shift > 0): + f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2)) + for ie in iesDefs[key]["ies"]: + ieunderscore = re.sub('-', '_', ie[2]) + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + if ie[2] in ieofielist: + f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore)) + else: + f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2)) + if ie[3] == "optional": + f.write(" ///< Optional field") + elif ie[3] == "conditional": + f.write(" ///< Conditional field") + f.write("\n") + + f.write("} %s_t;\n\n" % (re.sub('-', '_', key))) + +f.write("typedef struct %s_message_s {\n" % (fileprefix)) +f.write(" %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper)) +f.write(" %s_Criticality_t criticality;\n" % (fileprefix_first_upper)) +f.write(" uint8_t direction;\n") +f.write(" union {\n") + +messageList = iesDefs.keys() +messageList.sort() +for message in messageList: + if message in ieofielist.values(): + continue + if len(iesDefs[message]["ies"]) == 0: + continue + f.write(" %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message)))) +f.write(" } msg;\n") +f.write("} %s_message;\n\n" % (fileprefix)) + +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + keylowerunderscore = re.sub('-', '_', key.lower()) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + f.write("/** \\brief Decode function for %s ies.\n" % (key)) + if len(iesDefs[key]["ies"]) != 0: + f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" * \\param any_p Pointer to the ANY value to decode.\n") + f.write(" **/\n") + f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore)) + + if len(iesDefs[key]["ies"]) != 0: + f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" ANY_t *any_p);\n\n") + + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("/** \\brief Encode function for %s ies.\n" % (key)) + f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" **/\n") + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) + f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + +for key in iesDefs: + if key not in ieofielist.values(): + continue + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + f.write("/** \\brief Encode function for %s ies.\n" % (key)) + f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" **/\n") + f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) + f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower)) + f.write("/** \\brief Decode function for %s ies.\n" % (key)) + f.write(" * \\param any_p Pointer to the ANY value to decode.\n") + f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n") + f.write(" **/\n") + f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower)) + f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct))) + +for key in iesDefs: + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + if key in ieofielist.values(): + f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" * \\param file File descriptor to write output.\n") + f.write(" **/\n") + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower()))) + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + f.write(" %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower)) + else: + f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct)) + f.write(" * \\param message_p Pointer to root message.\n") + f.write(" * \\param file File descriptor to write output.\n") + f.write(" **/\n") + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + f.write(" %s_message *message_p);\n\n" % (fileprefix)) + +f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower())) +f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower())) +f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower())) +f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper())) + +#Generate Decode functions +f = open(outdir + fileprefix + '_decoder.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix)) +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + ielistname = re.sub('UE', 'ue', asn1cStruct) + ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstlower) + + f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + if len(iesDefs[key]["ies"]) != 0: + f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" ANY_t *any_p) {\n\n") + + f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower)) + f.write(" int i, decoded = 0;\n") + if len(iesDefs[key]["ies"]) != 0: + f.write(" int tempDecoded = 0;\n") + + f.write(" assert(any_p != NULL);\n") + if len(iesDefs[key]["ies"]) != 0: + f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + + f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName))) + f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower)) + f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess)) + f.write(" %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:])) + f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess)) + f.write(" switch(ie_p->id) {\n") + for ie in iesDefs[key]["ies"]: + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore) + ietypesubst = re.sub('-', '', ie[2]) + ietypeunderscore = re.sub('-', '_', ie[2]) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" {\n") + f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + if ie[3] != "mandatory": + f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst))) + f.write(" %s_ERROR(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore)) + f.write(" if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" decoded += tempDecoded;\n") + f.write(" if (asn1_xer_print)\n") + f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + if ie[2] in ieofielist.keys(): + f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" %s_ERROR(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" }\n") + else: + f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore)) + #f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" } break;\n") + f.write(" default:\n") + f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower()))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return decoded;\n") + f.write("}\n\n") + +for key in iesDefs: + if key not in ieofielist.values(): + continue + + keyname = re.sub('IEs', '', re.sub('Item', 'List', key)) + + f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower())) + f.write(" %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" int i, decoded = 0;\n") + f.write(" int tempDecoded = 0;\n\n") + + f.write(" assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))); + f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))); + + f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" switch (ie_p->id) {\n") + for ie in iesDefs[key]["ies"]: + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" {\n") + f.write(" %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" %s_ERROR(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname))) + f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + #f.write(" free(%s_p);\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" decoded += tempDecoded;\n") + f.write(" if (asn1_xer_print)\n") + f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)), + re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" } break;\n") + f.write(" default:\n") + f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower()))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return decoded;\n") + f.write("}\n\n") + + +#Generate IES Encode functions +f = open(outdir + fileprefix + '_encoder.c', 'w') +outputHeaderToFile(f,filename) +f.write("#include \"%s_common.h\"\n" % (fileprefix)) +f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix)) +for key in iesDefs: + if key in ieofielist.values(): + continue + + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstwordlower) + + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + # No IE to encode... + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower)) + f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + + f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper)) + + f.write(" assert(%s != NULL);\n" % (firstwordlower)); + f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); + + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + ietypeunderscore = re.sub('-', '_', ie[2]) + + if ie[3] != "mandatory": + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + #f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore)) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess)) + f.write(" }\n\n") + else: + if ie[2] in ieofielist.keys(): + f.write(" %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower)) + f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore)) + f.write("\n") + f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + if ie[2] in ieofielist.keys(): + f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower)) + else: + f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess)) + if ie[2] in ieofielist.keys(): + f.write(" /* Free any dynamic allocation that is no more used */\n") + f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower)) + + f.write(" return 0;\n") + f.write("}\n\n") + +for (key, value) in iesDefs.items(): + if key not in ieofielist.values(): + continue + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + for (i, j) in ieofielist.items(): + if j == key: + break + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower())) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower)) + f.write(" %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) + f.write(" int i;\n") + + f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper)) + + f.write(" assert(%s != NULL);\n" % (firstwordlower)); + f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); + + f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower)) + f.write(" }\n") + f.write(" return 0;\n") + f.write("}\n\n") + +#Generate xer print functions +f = open(outdir + fileprefix + '_xer_print.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \n") +f.write("#include \n\n") +f.write("#include \n#include \n\n") +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix)) + +f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower())) +f.write("""int +%s_xer__print2fp(const void *buffer, size_t size, void *app_key) { + FILE *stream = (FILE *)app_key; + + if(fwrite(buffer, 1, size, stream) != size) + return -1; + + return 0; +} + +""" % (fileprefix.lower())) + +f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) { + char *string = (char *)app_key; + + /* Copy buffer to the formatted string */ + memcpy(&string[%s_string_total_size], buffer, size); + + %s_string_total_size += size; + + return 0; +} + +""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower())) + +f.write("""static asn_enc_rval_t +xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr, + asn_app_consume_bytes_f *cb, void *app_key, int indent) { + asn_enc_rval_t er, tmper; + const char *mname; + size_t mlen; + int xcan = 2; + + if(!td || !sptr) goto cb_failed; + + mname = td->xml_tag; + mlen = strlen(mname); + + _i_ASN_TEXT_INDENT(0, indent); + _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1); + + tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key); + if(tmper.encoded == -1) return tmper; + + _ASN_CALLBACK3("\\n", xcan); + + er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; + + _ASN_ENCODED_OK(er); +cb_failed: + _ASN_ENCODE_FAILED; +} +""") + +for (key, value) in iesDefs.items(): + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + iesStructName = lowerFirstCamelWord(re.sub('-', '_', key)) + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + + if key in ieofielist.values(): + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower())))) + else: + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower()))) + #f.write(" FILE *file,\n") + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + if key in ieofielist.values(): + iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key))) + f.write(" %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName)) + f.write(" int i;\n") + f.write(" asn_enc_rval_t er;\n") + else: + f.write(" %s_message *message_p)\n{\n" % (fileprefix)) + f.write(" %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName)) + f.write(" asn_enc_rval_t er;\n") + #f.write(" void *app_key = (void *)file;\n") + #f.write(" asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower())) + + f.write(" %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName)) + + if key in ieofielist.values(): + # Increase indentation level + f.write(" for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + #f.write(" xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" }\n") + else: + f.write(" cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key)))) + f.write(" xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper) + f.write(" xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper) + + f.write(" cb(\" <%s>\\n\", %d, app_key);\n" % (key, len(" <%s>\n" % (key)))) + + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ietypeunderscore = re.sub('-', '_', ie[2]) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] != "mandatory": + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s->presenceMask & %s_%s_PRESENT)\n " % (iesStructName, keyupperunderscore, ieupperunderscore)) + + # Is it an encapsulated IE ? + if ie[2] in ieofielist.keys(): + f.write(" %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower)) + else: + f.write(" xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower)) + f.write(" cb(\" \\n\", %d, app_key);\n" % (key, len(" \n" % (key)))) + f.write(" cb(\"\\n\", %d, app_key);\n" % (key, len("\n" % (key)))) + + f.write(" _ASN_ENCODED_OK(er);\n") + #if key not in ieofielist.values(): + #f.write("cb_failed:\n") + #f.write(" return er;\n") + f.write("}\n\n") diff --git a/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 b/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 new file mode 100644 index 0000000000..009eebb13e --- /dev/null +++ b/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 @@ -0,0 +1,1316 @@ +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +M3AP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-PDU-Descriptions (0) } +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + ProcedureCode +FROM M3AP-CommonDataTypes + + MBMSSessionStartRequest, + MBMSSessionStartResponse, + MBMSSessionStartFailure, + MBMSSessionStopRequest, + MBMSSessionStopResponse, + MBMSSessionUpdateRequest, + MBMSSessionUpdateResponse, + MBMSSessionUpdateFailure, + MCEConfigurationUpdate, + MCEConfigurationUpdateAcknowledge, + MCEConfigurationUpdateFailure, + M3SetupRequest, + M3SetupResponse, + M3SetupFailure, + ErrorIndication, + Reset, + ResetAcknowledge, + PrivateMessage + +FROM M3AP-PDU-Contents + + id-mBMSsessionStart, + id-mBMSsessionStop, + id-mBMSsessionUpdate, + id-mCEConfigurationUpdate, + id-m3Setup, + id-errorIndication, + id-Reset, + id-privateMessage +FROM M3AP-Constants; + + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +M3AP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +M3AP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +M3AP-ELEMENTARY-PROCEDURES M3AP-ELEMENTARY-PROCEDURE ::= { + M3AP-ELEMENTARY-PROCEDURES-CLASS-1 | + M3AP-ELEMENTARY-PROCEDURES-CLASS-2 , + ... +} + +M3AP-ELEMENTARY-PROCEDURES-CLASS-1 M3AP-ELEMENTARY-PROCEDURE ::= { + mBMSsessionStart | + mBMSsessionStop | + mBMSsessionUpdate | + reset | + m3Setup | + mCEConfigurationUpdate , + ... +} + +M3AP-ELEMENTARY-PROCEDURES-CLASS-2 M3AP-ELEMENTARY-PROCEDURE ::= { + errorIndication | + privateMessage , + ... + +} + + +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +mBMSsessionStart M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MBMSSessionStartRequest + SUCCESSFUL OUTCOME MBMSSessionStartResponse + UNSUCCESSFUL OUTCOME MBMSSessionStartFailure + PROCEDURE CODE id-mBMSsessionStart + CRITICALITY reject +} + +mBMSsessionStop M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MBMSSessionStopRequest + SUCCESSFUL OUTCOME MBMSSessionStopResponse + PROCEDURE CODE id-mBMSsessionStop + CRITICALITY reject +} + +mBMSsessionUpdate M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MBMSSessionUpdateRequest + SUCCESSFUL OUTCOME MBMSSessionUpdateResponse + UNSUCCESSFUL OUTCOME MBMSSessionUpdateFailure + PROCEDURE CODE id-mBMSsessionUpdate + CRITICALITY reject +} + +errorIndication M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-errorIndication + CRITICALITY ignore +} + +reset M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-Reset + CRITICALITY reject +} + +privateMessage M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore +} + +mCEConfigurationUpdate M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MCEConfigurationUpdate + SUCCESSFUL OUTCOME MCEConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME MCEConfigurationUpdateFailure + PROCEDURE CODE id-mCEConfigurationUpdate + CRITICALITY reject +} + + +m3Setup M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE M3SetupRequest + SUCCESSFUL OUTCOME M3SetupResponse + UNSUCCESSFUL OUTCOME M3SetupFailure + PROCEDURE CODE id-m3Setup + CRITICALITY reject +} + +END + +-- ************************************************************** +-- +-- PDU definitions for M3AP. +-- +-- ************************************************************** + +M3AP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-PDU-Contents (1) } +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + Absolute-Time-ofMBMS-Data, + Cause, + CriticalityDiagnostics, + Global-MCE-ID, + MBMS-E-RAB-QoS-Parameters, + MBMS-Service-associatedLogicalM3-ConnectionItem, + MBMS-Service-Area, + MBMSServiceArea1, + MBMS-Session-Duration, + MBMS-Session-ID, + MCE-MBMS-M3AP-ID, + MCEname, + MinimumTimeToMBMSDataTransfer, + MME-MBMS-M3AP-ID, + TimeToWait, + TMGI, + TNL-Information, + Reestablishment, + MBMS-Cell-List + +FROM M3AP-IEs + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerList{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-ContainerPairList{}, + ProtocolIE-Single-Container{}, + M3AP-PRIVATE-IES, + M3AP-PROTOCOL-EXTENSION, + M3AP-PROTOCOL-IES, + M3AP-PROTOCOL-IES-PAIR +FROM M3AP-Containers + + id-AllocationAndRetentionPriority, + id-MCE-MBMS-M3AP-ID, + id-MME-MBMS-M3AP-ID, + id-TMGI, + id-MBMS-Session-ID, + id-MBMS-E-RAB-QoS-Parameters, + id-MBMS-Session-Duration, + id-MBMS-Service-Area, + id-TNL-Information, + id-Alternative-TNL-Information, + id-CriticalityDiagnostics, + id-Cause, + id-MBMS-Service-Area-List, + id-MBMS-Service-Area-List-Item, + id-TimeToWait, + id-ResetType, + id-MBMS-Service-associatedLogicalM3-ConnectionItem, + id-MBMS-Service-associatedLogicalM3-ConnectionListResAck, + id-MBMSServiceAreaList, + id-MinimumTimeToMBMSDataTransfer, + id-Time-ofMBMS-DataStop, + id-Time-ofMBMS-DataTransfer, + id-Global-MCE-ID, + id-MCEname, + id-Reestablishment, + id-MBMS-Cell-List, + maxnoofMBMSServiceAreaIdentitiesPerMCE, + maxnooferrors, + maxNrOfIndividualM3ConnectionsToReset + +FROM M3AP-Constants; + +-- ************************************************************** +-- +-- MBMS SESSION START REQUEST +-- +-- ************************************************************** + +MBMSSessionStartRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MBMSSessionStartRequest-IEs}}, + ... +} + +MBMSSessionStartRequest-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| + { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| + { ID id-MBMS-Service-Area CRITICALITY reject TYPE MBMS-Service-Area PRESENCE mandatory}| + { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY reject TYPE TNL-Information PRESENCE mandatory}| + { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| + { ID id-Reestablishment CRITICALITY ignore TYPE Reestablishment PRESENCE optional}| + { ID id-Alternative-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION START RESPONSE +-- +-- ************************************************************** + +MBMSSessionStartResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionStartResponse-IEs}}, + ... +} + +MBMSSessionStartResponse-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- MBMS SESSION START FAILURE +-- +-- ************************************************************** + +MBMSSessionStartFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionStartFailure-IEs}}, + ... +} + +MBMSSessionStartFailure-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- MBMS SESSION STOP REQUEST +-- +-- ************************************************************** + +MBMSSessionStopRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MBMSSessionStopRequest-IEs}}, + ... +} + +MBMSSessionStopRequest-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-Time-ofMBMS-DataStop CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION STOP RESPONSE +-- +-- ************************************************************** + +MBMSSessionStopResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionStopResponse-IEs}}, + ... +} + +MBMSSessionStopResponse-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION UPDATE REQUEST +-- +-- ************************************************************** + +MBMSSessionUpdateRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MBMSSessionUpdateRequest-IEs}}, + ... +} + +MBMSSessionUpdateRequest-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| + { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| + { ID id-MBMS-Service-Area CRITICALITY ignore TYPE MBMS-Service-Area PRESENCE optional}| + { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| + { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION UPDATE RESPONSE +-- +-- ************************************************************** + +MBMSSessionUpdateResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateResponse-IEs}}, + ... +} + +MBMSSessionUpdateResponse-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION UPDATE FAILURE +-- +-- ************************************************************** + +MBMSSessionUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateFailure-IEs}}, + ... +} + +MBMSSessionUpdateFailure-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- ERROR INDICATION +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ErrorIndication-IEs}}, + ... +} + +ErrorIndication-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE optional } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE optional } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... +} + + +-- ************************************************************** +-- +-- Reset +-- +-- ************************************************************** + +Reset ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetIEs} }, + ... +} + +ResetIEs M3AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... +} + +ResetType ::= CHOICE { + m3-Interface ResetAll, + partOfM3-Interface MBMS-Service-associatedLogicalM3-ConnectionListRes, + ... +} + + + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +MBMS-Service-associatedLogicalM3-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM3-ConnectionItemRes } } + +MBMS-Service-associatedLogicalM3-ConnectionItemRes M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY reject TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- Reset Acknowledge +-- +-- ************************************************************** + +ResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, + ... +} + +ResetAcknowledgeIEs M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionListResAck CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionListResAck PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +MBMS-Service-associatedLogicalM3-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM3-ConnectionItemResAck } } + +MBMS-Service-associatedLogicalM3-ConnectionItemResAck M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, + ... +} + +PrivateMessage-IEs M3AP-PRIVATE-IES ::= { + ... +} + + +-- ************************************************************** +-- +-- M3 SETUP ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- M3 Setup Request +-- +-- ************************************************************** + +M3SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {M3SetupRequestIEs} }, + ... +} + +M3SetupRequestIEs M3AP-PROTOCOL-IES ::= { + { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE mandatory}| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| + { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE optional}, + ... +} + + +MBMSServiceAreaListItem ::= SEQUENCE (SIZE(1..maxnoofMBMSServiceAreaIdentitiesPerMCE)) OF MBMSServiceArea1 + + +-- ************************************************************** +-- +-- M3 Setup Response +-- +-- ************************************************************** + +M3SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {M3SetupResponseIEs} }, + ... +} + + +M3SetupResponseIEs M3AP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- M3 Setup Failure +-- +-- ************************************************************** + +M3SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {M3SetupFailureIEs} }, + ... +} + +M3SetupFailureIEs M3AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MCE CONFIGURATION UPDATE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- MCE Configuration Update +-- +-- ************************************************************** + +MCEConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateIEs} }, + ... +} + +MCEConfigurationUpdateIEs M3AP-PROTOCOL-IES ::= { + { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE optional}| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| + { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MCE Configuration Update Acknowledge +-- +-- ************************************************************** + +MCEConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateAcknowledgeIEs} }, + ... +} + + +MCEConfigurationUpdateAcknowledgeIEs M3AP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- MCE Configuration Update Failure +-- +-- ************************************************************** + +MCEConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateFailureIEs} }, + ... +} + +MCEConfigurationUpdateFailureIEs M3AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +END + +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +M3AP-IEs { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-IEs (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + id-AllocationAndRetentionPriority, + maxnooferrors, + maxnoofCellsforMBMS + +FROM M3AP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage +FROM M3AP-CommonDataTypes + + ProtocolExtensionContainer{}, + ProtocolIE-Single-Container{}, + M3AP-PROTOCOL-EXTENSION, + M3AP-PROTOCOL-IES +FROM M3AP-Containers; + +-- A + +Absolute-Time-ofMBMS-Data ::= BIT STRING (SIZE (64)) + +AllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL +} + +AllocationAndRetentionPriority-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} +-- B + +BitRate ::= INTEGER (0..10000000000) + +-- C + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + nAS CauseNAS, + protocol CauseProtocol, + misc CauseMisc, + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, + unspecified, + ... +} + +CauseNAS ::= ENUMERATED { + unspecified, + ... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unknown-or-already-allocated-MME-MBMS-M3AP-ID, + unknown-or-already-allocated-MCE-MBMS-M3AP-ID, + unknown-or-inconsistent-pair-of-MBMS-M3AP-IDs, + radio-resources-not-available, + invalid-QoS-combination, + interaction-with-other-procedure, + not-supported-QCI-value, + unspecified, + ..., + uninvolved-MCE + +} + +CauseTransport ::= ENUMERATED { + transport-resource-unavailable, + unspecified, + ... +} + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, + ... +} + + +CriticalityDiagnostics-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxnooferrors)) OF + SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-List-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + + +-- D +-- E + +ECGI ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + eUTRANcellIdentifier EUTRANCellIdentifier, + iE-Extensions ProtocolExtensionContainer { {ECGI-ExtIEs} } OPTIONAL, + ... +} + +ECGI-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRANCellIdentifier ::= BIT STRING (SIZE (28)) + +ExtendedMCE-ID ::= OCTET STRING (SIZE(1)) + +-- F +-- G + +Global-MCE-ID ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + mCE-ID MCE-ID, + extendedMCE-ID ExtendedMCE-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {GlobalMCE-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalMCE-ID-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +GBR-QosInformation ::= SEQUENCE { + mBMS-E-RAB-MaximumBitrateDL BitRate, + mBMS-E-RAB-GuaranteedBitrateDL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +GTP-TEID ::= OCTET STRING (SIZE (4)) + +-- H +-- I + +IPAddress ::= OCTET STRING (SIZE(4..16, ...)) + +-- J +-- K +-- L +-- M + +MBMS-Cell-List ::= SEQUENCE (SIZE(1.. maxnoofCellsforMBMS)) OF ECGI + +MBMS-E-RAB-QoS-Parameters ::= SEQUENCE { + qCI QCI, + gbrQosInformation GBR-QosInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-E-RAB-QoS-Parameters-ExtIEs} } OPTIONAL, + ... +} + +MBMS-E-RAB-QoS-Parameters-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { +-- Extension for Release 10 ARP support -- + {ID id-AllocationAndRetentionPriority CRITICALITY ignore EXTENSION AllocationAndRetentionPriority PRESENCE mandatory}, + ... +} + +MBMS-Service-associatedLogicalM3-ConnectionItem ::= SEQUENCE { + mME-MBMS-M3AP-ID MME-MBMS-M3AP-ID OPTIONAL, + mCE-MBMS-M3AP-ID MCE-MBMS-M3AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs} } OPTIONAL, + ... +} + + +MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBMSServiceArea1 ::= OCTET STRING (SIZE (2)) + +MBMS-Service-Area ::= OCTET STRING + + +MBMS-Session-Duration ::= OCTET STRING (SIZE (3)) + +MBMS-Session-ID ::= OCTET STRING (SIZE (1)) + + +MCE-MBMS-M3AP-ID ::= INTEGER (0..65535) + +MCE-ID ::= OCTET STRING (SIZE(2)) + +MCEname ::= PrintableString (SIZE (1..150,...)) + +MinimumTimeToMBMSDataTransfer ::= OCTET STRING (SIZE (1)) + +MME-MBMS-M3AP-ID ::= INTEGER (0..65535) + +-- N +-- O +-- P + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable +} + +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) + +PLMN-Identity ::= OCTET STRING (SIZE(3)) + +-- Q + +QCI ::= INTEGER (0..255) + +-- R + +Reestablishment ::= ENUMERATED {true, ...} + +-- S +-- T + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TMGI ::= SEQUENCE { + pLMNidentity PLMN-Identity, + serviceID OCTET STRING (SIZE (3)), + iE-Extensions ProtocolExtensionContainer { {TMGI-ExtIEs} } OPTIONAL +} + +TMGI-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + + +TNL-Information ::= SEQUENCE { + iPMCAddress IPAddress, + iPSourceAddress IPAddress, + gTP-DLTEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { {TNL-Information-ExtIEs} } OPTIONAL, + ... +} + +TNL-Information-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + + +-- U +-- V +-- W +-- X +-- Y +-- Z + +END + +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +M3AP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-CommonDataTypes (3) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 + +-- ************************************************************** +-- +-- Common Data Types +-- +-- ************************************************************** + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0.. maxPrivateIEs), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + + +ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs) + + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome} + +END + +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + +M3AP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + ProcedureCode, + ProtocolIE-ID +FROM M3AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-mBMSsessionStart ProcedureCode ::= 0 +id-mBMSsessionStop ProcedureCode ::= 1 +id-errorIndication ProcedureCode ::= 2 +id-privateMessage ProcedureCode ::= 3 +id-Reset ProcedureCode ::= 4 +id-mBMSsessionUpdate ProcedureCode ::= 5 +id-mCEConfigurationUpdate ProcedureCode ::= 6 +id-m3Setup ProcedureCode ::= 7 + + + +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + +maxnoofMBMSServiceAreaIdentitiesPerMCE INTEGER ::= 65536 +maxnooferrors INTEGER ::= 256 +maxNrOfIndividualM3ConnectionsToReset INTEGER ::= 256 +maxnoofCellsforMBMS INTEGER ::= 4096 + +-- ************************************************************** +-- +-- IEs +-- +-- ************************************************************** + +id-MME-MBMS-M3AP-ID ProtocolIE-ID ::= 0 +id-MCE-MBMS-M3AP-ID ProtocolIE-ID ::= 1 +id-TMGI ProtocolIE-ID ::= 2 +id-MBMS-Session-ID ProtocolIE-ID ::= 3 +id-MBMS-E-RAB-QoS-Parameters ProtocolIE-ID ::= 4 +id-MBMS-Session-Duration ProtocolIE-ID ::= 5 +id-MBMS-Service-Area ProtocolIE-ID ::= 6 +id-TNL-Information ProtocolIE-ID ::= 7 +id-CriticalityDiagnostics ProtocolIE-ID ::= 8 +id-Cause ProtocolIE-ID ::= 9 +id-MBMS-Service-Area-List ProtocolIE-ID ::= 10 +id-MBMS-Service-Area-List-Item ProtocolIE-ID ::= 11 +id-TimeToWait ProtocolIE-ID ::= 12 +id-ResetType ProtocolIE-ID ::= 13 +id-MBMS-Service-associatedLogicalM3-ConnectionItem ProtocolIE-ID ::= 14 +id-MBMS-Service-associatedLogicalM3-ConnectionListResAck ProtocolIE-ID ::= 15 +id-MinimumTimeToMBMSDataTransfer ProtocolIE-ID ::= 16 +id-AllocationAndRetentionPriority ProtocolIE-ID ::= 17 +id-Global-MCE-ID ProtocolIE-ID ::= 18 +id-MCEname ProtocolIE-ID ::= 19 +id-MBMSServiceAreaList ProtocolIE-ID ::= 20 +id-Time-ofMBMS-DataTransfer ProtocolIE-ID ::= 21 +id-Time-ofMBMS-DataStop ProtocolIE-ID ::= 22 +id-Reestablishment ProtocolIE-ID ::= 23 +id-Alternative-TNL-Information ProtocolIE-ID ::= 24 +id-MBMS-Cell-List ProtocolIE-ID ::= 25 +END + + + +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +M3AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs, + Criticality, + Presence, + PrivateIE-ID, + ProtocolIE-ID +FROM M3AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +M3AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +M3AP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +M3AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +M3AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Single-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field {M3AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id M3AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality M3AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value M3AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} + +ProtocolIE-FieldPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { + id M3AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality M3AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue M3AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality M3AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue M3AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container Lists for Protocol IE Containers +-- +-- ************************************************************** + +ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, M3AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-Container {{IEsSetParam}} + +ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-ContainerPair {{IEsSetParam}} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id M3AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality M3AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue M3AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container {M3AP-PRIVATE-IES : IEsSetParam} ::= + SEQUENCE (SIZE (1..maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field {M3AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id M3AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality M3AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value M3AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END + + diff --git a/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1.bak b/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1.bak new file mode 100644 index 0000000000..fac7864ba3 --- /dev/null +++ b/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1.bak @@ -0,0 +1,1360 @@ +-- M3AP-PDU-Descriptions.asn +-- +-- 3GPP TS 36.444 V13.2.0 (2016-03) +-- http://www.3gpp.org/ftp/Specs/archive/36_series/36.444/36444-d20.zip +-- +-- 9.3.3 Elementary Procedure Definitions +-- + +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +M3AP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-PDU-Descriptions (0) } +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + ProcedureCode +FROM M3AP-CommonDataTypes + + MBMSSessionStartRequest, + MBMSSessionStartResponse, + MBMSSessionStartFailure, + MBMSSessionStopRequest, + MBMSSessionStopResponse, + MBMSSessionUpdateRequest, + MBMSSessionUpdateResponse, + MBMSSessionUpdateFailure, + MCEConfigurationUpdate, + MCEConfigurationUpdateAcknowledge, + MCEConfigurationUpdateFailure, + M3SetupRequest, + M3SetupResponse, + M3SetupFailure, + ErrorIndication, + Reset, + ResetAcknowledge, + PrivateMessage + +FROM M3AP-PDU-Contents + + id-mBMSsessionStart, + id-mBMSsessionStop, + id-mBMSsessionUpdate, + id-mCEConfigurationUpdate, + id-m3Setup, + id-errorIndication, + id-Reset, + id-privateMessage +FROM M3AP-Constants; + + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +M3AP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +M3AP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +M3AP-ELEMENTARY-PROCEDURES M3AP-ELEMENTARY-PROCEDURE ::= { + M3AP-ELEMENTARY-PROCEDURES-CLASS-1 | + M3AP-ELEMENTARY-PROCEDURES-CLASS-2 , + ... +} + +M3AP-ELEMENTARY-PROCEDURES-CLASS-1 M3AP-ELEMENTARY-PROCEDURE ::= { + mBMSsessionStart | + mBMSsessionStop | + mBMSsessionUpdate | + reset | + m3Setup | + mCEConfigurationUpdate , + ... +} + +M3AP-ELEMENTARY-PROCEDURES-CLASS-2 M3AP-ELEMENTARY-PROCEDURE ::= { + errorIndication | + privateMessage , + ... + +} + + +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +mBMSsessionStart M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MBMSSessionStartRequest + SUCCESSFUL OUTCOME MBMSSessionStartResponse + UNSUCCESSFUL OUTCOME MBMSSessionStartFailure + PROCEDURE CODE id-mBMSsessionStart + CRITICALITY reject +} + +mBMSsessionStop M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MBMSSessionStopRequest + SUCCESSFUL OUTCOME MBMSSessionStopResponse + PROCEDURE CODE id-mBMSsessionStop + CRITICALITY reject +} + +mBMSsessionUpdate M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MBMSSessionUpdateRequest + SUCCESSFUL OUTCOME MBMSSessionUpdateResponse + UNSUCCESSFUL OUTCOME MBMSSessionUpdateFailure + PROCEDURE CODE id-mBMSsessionUpdate + CRITICALITY reject +} + +errorIndication M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-errorIndication + CRITICALITY ignore +} + +reset M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-Reset + CRITICALITY reject +} + +privateMessage M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore +} + +mCEConfigurationUpdate M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE MCEConfigurationUpdate + SUCCESSFUL OUTCOME MCEConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME MCEConfigurationUpdateFailure + PROCEDURE CODE id-mCEConfigurationUpdate + CRITICALITY reject +} + + +m3Setup M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE M3SetupRequest + SUCCESSFUL OUTCOME M3SetupResponse + UNSUCCESSFUL OUTCOME M3SetupFailure + PROCEDURE CODE id-m3Setup + CRITICALITY reject +} + +END + +-- M3AP-PDU-Contents.asn +-- +-- 3GPP TS 36.444 V13.2.0 (2016-03) +-- http://www.3gpp.org/ftp/Specs/archive/36_series/36.444/36444-d20.zip +-- +-- 9.3.4 PDU Definitions +-- + +-- ************************************************************** +-- +-- PDU definitions for M3AP. +-- +-- ************************************************************** + +M3AP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-PDU-Contents (1) } +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + Absolute-Time-ofMBMS-Data, + Cause, + CriticalityDiagnostics, + Global-MCE-ID, + MBMS-E-RAB-QoS-Parameters, + MBMS-Service-associatedLogicalM3-ConnectionItem, + MBMS-Service-Area, + MBMSServiceArea1, + MBMS-Session-Duration, + MBMS-Session-ID, + MCE-MBMS-M3AP-ID, + MCEname, + MinimumTimeToMBMSDataTransfer, + MME-MBMS-M3AP-ID, + TimeToWait, + TMGI, + TNL-Information, + Reestablishment, + MBMS-Cell-List + +FROM M3AP-IEs + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerList{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-ContainerPairList{}, + ProtocolIE-Single-Container{}, + M3AP-PRIVATE-IES, + M3AP-PROTOCOL-EXTENSION, + M3AP-PROTOCOL-IES, + M3AP-PROTOCOL-IES-PAIR +FROM M3AP-Containers + + id-AllocationAndRetentionPriority, + id-MCE-MBMS-M3AP-ID, + id-MME-MBMS-M3AP-ID, + id-TMGI, + id-MBMS-Session-ID, + id-MBMS-E-RAB-QoS-Parameters, + id-MBMS-Session-Duration, + id-MBMS-Service-Area, + id-TNL-Information, + id-Alternative-TNL-Information, + id-CriticalityDiagnostics, + id-Cause, + id-MBMS-Service-Area-List, + id-MBMS-Service-Area-List-Item, + id-TimeToWait, + id-ResetType, + id-MBMS-Service-associatedLogicalM3-ConnectionItem, + id-MBMS-Service-associatedLogicalM3-ConnectionListResAck, + id-MBMSServiceAreaList, + id-MinimumTimeToMBMSDataTransfer, + id-Time-ofMBMS-DataStop, + id-Time-ofMBMS-DataTransfer, + id-Global-MCE-ID, + id-MCEname, + id-Reestablishment, + id-MBMS-Cell-List, + maxnoofMBMSServiceAreaIdentitiesPerMCE, + maxnooferrors, + maxNrOfIndividualM3ConnectionsToReset + +FROM M3AP-Constants; + +-- ************************************************************** +-- +-- MBMS SESSION START REQUEST +-- +-- ************************************************************** + +MBMSSessionStartRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MBMSSessionStartRequest-IEs}}, + ... +} + +MBMSSessionStartRequest-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| + { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| + { ID id-MBMS-Service-Area CRITICALITY reject TYPE MBMS-Service-Area PRESENCE mandatory}| + { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY reject TYPE TNL-Information PRESENCE mandatory}| + { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| + { ID id-Reestablishment CRITICALITY ignore TYPE Reestablishment PRESENCE optional}| + { ID id-Alternative-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION START RESPONSE +-- +-- ************************************************************** + +MBMSSessionStartResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionStartResponse-IEs}}, + ... +} + +MBMSSessionStartResponse-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- MBMS SESSION START FAILURE +-- +-- ************************************************************** + +MBMSSessionStartFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionStartFailure-IEs}}, + ... +} + +MBMSSessionStartFailure-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- MBMS SESSION STOP REQUEST +-- +-- ************************************************************** + +MBMSSessionStopRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MBMSSessionStopRequest-IEs}}, + ... +} + +MBMSSessionStopRequest-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-Time-ofMBMS-DataStop CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION STOP RESPONSE +-- +-- ************************************************************** + +MBMSSessionStopResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionStopResponse-IEs}}, + ... +} + +MBMSSessionStopResponse-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION UPDATE REQUEST +-- +-- ************************************************************** + +MBMSSessionUpdateRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{MBMSSessionUpdateRequest-IEs}}, + ... +} + +MBMSSessionUpdateRequest-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| + { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| + { ID id-MBMS-Service-Area CRITICALITY ignore TYPE MBMS-Service-Area PRESENCE optional}| + { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| + { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION UPDATE RESPONSE +-- +-- ************************************************************** + +MBMSSessionUpdateResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateResponse-IEs}}, + ... +} + +MBMSSessionUpdateResponse-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- MBMS SESSION UPDATE FAILURE +-- +-- ************************************************************** + +MBMSSessionUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateFailure-IEs}}, + ... +} + +MBMSSessionUpdateFailure-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- ERROR INDICATION +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ErrorIndication-IEs}}, + ... +} + +ErrorIndication-IEs M3AP-PROTOCOL-IES ::= { + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE optional } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE optional } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... +} + + +-- ************************************************************** +-- +-- Reset +-- +-- ************************************************************** + +Reset ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetIEs} }, + ... +} + +ResetIEs M3AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... +} + +ResetType ::= CHOICE { + m3-Interface ResetAll, + partOfM3-Interface MBMS-Service-associatedLogicalM3-ConnectionListRes, + ... +} + + + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +MBMS-Service-associatedLogicalM3-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM3-ConnectionItemRes } } + +MBMS-Service-associatedLogicalM3-ConnectionItemRes M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY reject TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- Reset Acknowledge +-- +-- ************************************************************** + +ResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, + ... +} + +ResetAcknowledgeIEs M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionListResAck CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionListResAck PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +MBMS-Service-associatedLogicalM3-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM3-ConnectionItemResAck } } + +MBMS-Service-associatedLogicalM3-ConnectionItemResAck M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, + ... +} + +PrivateMessage-IEs M3AP-PRIVATE-IES ::= { + ... +} + + +-- ************************************************************** +-- +-- M3 SETUP ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- M3 Setup Request +-- +-- ************************************************************** + +M3SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {M3SetupRequestIEs} }, + ... +} + +M3SetupRequestIEs M3AP-PROTOCOL-IES ::= { + { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE mandatory}| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| + { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE mandatory}, + ... +} + + +MBMSServiceAreaListItem ::= SEQUENCE (SIZE(1..maxnoofMBMSServiceAreaIdentitiesPerMCE)) OF MBMSServiceArea1 + + +-- ************************************************************** +-- +-- M3 Setup Response +-- +-- ************************************************************** + +M3SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {M3SetupResponseIEs} }, + ... +} + + +M3SetupResponseIEs M3AP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- M3 Setup Failure +-- +-- ************************************************************** + +M3SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {M3SetupFailureIEs} }, + ... +} + +M3SetupFailureIEs M3AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MCE CONFIGURATION UPDATE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- MCE Configuration Update +-- +-- ************************************************************** + +MCEConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateIEs} }, + ... +} + +MCEConfigurationUpdateIEs M3AP-PROTOCOL-IES ::= { + { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE optional}| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| + { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE optional}, + ... +} + +-- ************************************************************** +-- +-- MCE Configuration Update Acknowledge +-- +-- ************************************************************** + +MCEConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateAcknowledgeIEs} }, + ... +} + + +MCEConfigurationUpdateAcknowledgeIEs M3AP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- MCE Configuration Update Failure +-- +-- ************************************************************** + +MCEConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateFailureIEs} }, + ... +} + +MCEConfigurationUpdateFailureIEs M3AP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... +} + +END + +-- M3AP-IEs.asn +-- +-- 3GPP TS 36.444 V13.2.0 (2016-03) +-- http://www.3gpp.org/ftp/Specs/archive/36_series/36.444/36444-d20.zip +-- +-- 9.3.5 Information Element Definitions +-- + +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +M3AP-IEs { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-IEs (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + id-AllocationAndRetentionPriority, + maxnooferrors, + maxnoofCellsforMBMS + +FROM M3AP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage +FROM M3AP-CommonDataTypes + + ProtocolExtensionContainer{}, + ProtocolIE-Single-Container{}, + M3AP-PROTOCOL-EXTENSION, + M3AP-PROTOCOL-IES +FROM M3AP-Containers; + +-- A + +Absolute-Time-ofMBMS-Data ::= BIT STRING (SIZE (64)) + +AllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL +} + +AllocationAndRetentionPriority-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} +-- B + +BitRate ::= INTEGER (0..10000000000) + +-- C + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + nAS CauseNAS, + protocol CauseProtocol, + misc CauseMisc, + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, + unspecified, + ... +} + +CauseNAS ::= ENUMERATED { + unspecified, + ... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unknown-or-already-allocated-MME-MBMS-M3AP-ID, + unknown-or-already-allocated-MCE-MBMS-M3AP-ID, + unknown-or-inconsistent-pair-of-MBMS-M3AP-IDs, + radio-resources-not-available, + invalid-QoS-combination, + interaction-with-other-procedure, + not-supported-QCI-value, + unspecified, + ..., + uninvolved-MCE + +} + +CauseTransport ::= ENUMERATED { + transport-resource-unavailable, + unspecified, + ... +} + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, + ... +} + + +CriticalityDiagnostics-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxnooferrors)) OF + SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-List-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + + +-- D +-- E + +ECGI ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + eUTRANcellIdentifier EUTRANCellIdentifier, + iE-Extensions ProtocolExtensionContainer { {ECGI-ExtIEs} } OPTIONAL, + ... +} + +ECGI-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRANCellIdentifier ::= BIT STRING (SIZE (28)) + +ExtendedMCE-ID ::= OCTET STRING (SIZE(1)) + +-- F +-- G + +Global-MCE-ID ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + mCE-ID MCE-ID, + extendedMCE-ID ExtendedMCE-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {GlobalMCE-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalMCE-ID-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +GBR-QosInformation ::= SEQUENCE { + mBMS-E-RAB-MaximumBitrateDL BitRate, + mBMS-E-RAB-GuaranteedBitrateDL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +GTP-TEID ::= OCTET STRING (SIZE (4)) + +-- H +-- I + +IPAddress ::= OCTET STRING (SIZE(4..16, ...)) + +-- J +-- K +-- L +-- M + +MBMS-Cell-List ::= SEQUENCE (SIZE(1.. maxnoofCellsforMBMS)) OF ECGI + +MBMS-E-RAB-QoS-Parameters ::= SEQUENCE { + qCI QCI, + gbrQosInformation GBR-QosInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-E-RAB-QoS-Parameters-ExtIEs} } OPTIONAL, + ... +} + +MBMS-E-RAB-QoS-Parameters-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { +-- Extension for Release 10 ARP support -- + {ID id-AllocationAndRetentionPriority CRITICALITY ignore EXTENSION AllocationAndRetentionPriority PRESENCE mandatory}, + ... +} + +MBMS-Service-associatedLogicalM3-ConnectionItem ::= SEQUENCE { + mME-MBMS-M3AP-ID MME-MBMS-M3AP-ID OPTIONAL, + mCE-MBMS-M3AP-ID MCE-MBMS-M3AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs} } OPTIONAL, + ... +} + + +MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +MBMSServiceArea1 ::= OCTET STRING (SIZE (2)) + +MBMS-Service-Area ::= OCTET STRING + + +MBMS-Session-Duration ::= OCTET STRING (SIZE (3)) + +MBMS-Session-ID ::= OCTET STRING (SIZE (1)) + + +MCE-MBMS-M3AP-ID ::= INTEGER (0..65535) + +MCE-ID ::= OCTET STRING (SIZE(2)) + +MCEname ::= PrintableString (SIZE (1..150,...)) + +MinimumTimeToMBMSDataTransfer ::= OCTET STRING (SIZE (1)) + +MME-MBMS-M3AP-ID ::= INTEGER (0..65535) + +-- N +-- O +-- P + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable +} + +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) + +PLMN-Identity ::= OCTET STRING (SIZE(3)) + +-- Q + +QCI ::= INTEGER (0..255) + +-- R + +Reestablishment ::= ENUMERATED {true, ...} + +-- S +-- T + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TMGI ::= SEQUENCE { + pLMNidentity PLMN-Identity, + serviceID OCTET STRING (SIZE (3)), + iE-Extensions ProtocolExtensionContainer { {TMGI-ExtIEs} } OPTIONAL +} + +TMGI-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + + +TNL-Information ::= SEQUENCE { + iPMCAddress IPAddress, + iPSourceAddress IPAddress, + gTP-DLTEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { {TNL-Information-ExtIEs} } OPTIONAL, + ... +} + +TNL-Information-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { + ... +} + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + + +-- U +-- V +-- W +-- X +-- Y +-- Z + +END + +-- M3AP-CommonDataTypes.asn +-- +-- 3GPP TS 36.444 V13.2.0 (2016-03) +-- http://www.3gpp.org/ftp/Specs/archive/36_series/36.444/36444-d20.zip +-- +-- 9.3.6 Common Definitions +-- + +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +M3AP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-CommonDataTypes (3) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 + +-- ************************************************************** +-- +-- Common Data Types +-- +-- ************************************************************** + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0.. maxPrivateIEs), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + + +ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs) + + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome} + +END + +-- M3AP-Containers.asn +-- +-- 3GPP TS 36.444 V13.2.0 (2016-03) +-- http://www.3gpp.org/ftp/Specs/archive/36_series/36.444/36444-d20.zip +-- +-- 9.3.8 Container Definitions +-- + +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +M3AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs, + Criticality, + Presence, + PrivateIE-ID, + ProtocolIE-ID +FROM M3AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +M3AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +M3AP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +M3AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +M3AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Single-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field {M3AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id M3AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality M3AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value M3AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} + +ProtocolIE-FieldPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { + id M3AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality M3AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue M3AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality M3AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue M3AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container Lists for Protocol IE Containers +-- +-- ************************************************************** + +ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, M3AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-Container {{IEsSetParam}} + +ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-ContainerPair {{IEsSetParam}} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id M3AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality M3AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue M3AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container {M3AP-PRIVATE-IES : IEsSetParam} ::= + SEQUENCE (SIZE (1..maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field {M3AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id M3AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality M3AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value M3AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END + +-- M3AP-Constants.asn +-- +-- 3GPP TS 36.444 V13.2.0 (2016-03) +-- http://www.3gpp.org/ftp/Specs/archive/36_series/36.444/36444-d20.zip +-- +-- 9.3.7 Constant Definitions +-- + +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + +M3AP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + ProcedureCode, + ProtocolIE-ID +FROM M3AP-CommonDataTypes; + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-mBMSsessionStart ProcedureCode ::= 0 +id-mBMSsessionStop ProcedureCode ::= 1 +id-errorIndication ProcedureCode ::= 2 +id-privateMessage ProcedureCode ::= 3 +id-Reset ProcedureCode ::= 4 +id-mBMSsessionUpdate ProcedureCode ::= 5 +id-mCEConfigurationUpdate ProcedureCode ::= 6 +id-m3Setup ProcedureCode ::= 7 + + + +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + +maxnoofMBMSServiceAreaIdentitiesPerMCE INTEGER ::= 65536 +maxnooferrors INTEGER ::= 256 +maxNrOfIndividualM3ConnectionsToReset INTEGER ::= 256 +maxnoofCellsforMBMS INTEGER ::= 4096 + +-- ************************************************************** +-- +-- IEs +-- +-- ************************************************************** + +id-MME-MBMS-M3AP-ID ProtocolIE-ID ::= 0 +id-MCE-MBMS-M3AP-ID ProtocolIE-ID ::= 1 +id-TMGI ProtocolIE-ID ::= 2 +id-MBMS-Session-ID ProtocolIE-ID ::= 3 +id-MBMS-E-RAB-QoS-Parameters ProtocolIE-ID ::= 4 +id-MBMS-Session-Duration ProtocolIE-ID ::= 5 +id-MBMS-Service-Area ProtocolIE-ID ::= 6 +id-TNL-Information ProtocolIE-ID ::= 7 +id-CriticalityDiagnostics ProtocolIE-ID ::= 8 +id-Cause ProtocolIE-ID ::= 9 +id-MBMS-Service-Area-List ProtocolIE-ID ::= 10 +id-MBMS-Service-Area-List-Item ProtocolIE-ID ::= 11 +id-TimeToWait ProtocolIE-ID ::= 12 +id-ResetType ProtocolIE-ID ::= 13 +id-MBMS-Service-associatedLogicalM3-ConnectionItem ProtocolIE-ID ::= 14 +id-MBMS-Service-associatedLogicalM3-ConnectionListResAck ProtocolIE-ID ::= 15 +id-MinimumTimeToMBMSDataTransfer ProtocolIE-ID ::= 16 +id-AllocationAndRetentionPriority ProtocolIE-ID ::= 17 +id-Global-MCE-ID ProtocolIE-ID ::= 18 +id-MCEname ProtocolIE-ID ::= 19 +id-MBMSServiceAreaList ProtocolIE-ID ::= 20 +id-Time-ofMBMS-DataTransfer ProtocolIE-ID ::= 21 +id-Time-ofMBMS-DataStop ProtocolIE-ID ::= 22 +id-Reestablishment ProtocolIE-ID ::= 23 +id-Alternative-TNL-Information ProtocolIE-ID ::= 24 +id-MBMS-Cell-List ProtocolIE-ID ::= 25 +END diff --git a/openair3/M3AP/MESSAGES/ASN1/asn1tostruct.py b/openair3/M3AP/MESSAGES/ASN1/asn1tostruct.py new file mode 100644 index 0000000000..b5a141349b --- /dev/null +++ b/openair3/M3AP/MESSAGES/ASN1/asn1tostruct.py @@ -0,0 +1,732 @@ +import re, os, sys, string +import datetime +import getopt +import getpass + +version = "1.0.2" + +lines = "" +iesDefs = {} +ieofielist = {} +outdir = './' + +filenames = [] +verbosity = 0 +prefix = "" + +FAIL = '\033[91m' +WARN = '\033[93m' +ENDC = '\033[0m' + +fileprefix = "" +fileprefix_first_upper = "" + +def printFail(string): + sys.stderr.write(FAIL + string + ENDC + "\n") + +def printWarning(string): + print WARN + string + ENDC + +def printDebug(string): + if verbosity > 0: + print string + +def outputHeaderToFile(f, filename): + now = datetime.datetime.now() + f.write("""/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +""") + f.write("/*******************************************************************************\n") + f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version)) + f.write(" * Please do not modify this file but regenerate it via script.\n") + f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames)) + f.write(" ******************************************************************************/\n") + +def lowerFirstCamelWord(word): + """ puts the first word in a CamelCase Word in lowercase. + + I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest + """ + newstr = '' + swapped = word.swapcase() + idx = 0 + + # if it's all-caps, return an all-lowered version + lowered = word.lower() + + if swapped == lowered: + return lowered + + for c in swapped: + if c in string.lowercase: + newstr += c + idx += 1 + else: + break + if idx < 2: + newstr += word[idx:] + else: + newstr = newstr[:-1]+ word[idx-1:] + + return newstr + +def usage(): + print "Python parser for asn1 v%s" % (version) + print "Usage: python asn1tostruct.py [options]" + print "Available options:" + print "-d Enable script debug" + print "-f [file] Input file to parse" + print "-o [dir] Output files to given directory" + print "-h Print this help and return" + +try: + opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"]) +except getopt.GetoptError as err: + # print help information and exit: + usage() + sys.exit(2) + +for o, a in opts: + if o in ("-f", "--file"): + filenames.append(a) + if o in ("-d", "--debug"): + verbosity = 1 + if o in ("-o", "--outdir"): + outdir = a + if outdir.rfind('/') != len(outdir): + outdir += '/' + if o in ("-h", "--help"): + usage() + sys.exit(2) + +for filename in filenames: + file = open(filename, 'r') + for line in file: + # Removing any comment + if line.find('--') >= 0: + line = line[:line.find('--')] + # Removing any carriage return + lines += re.sub('\r', '', line) + + for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE): + ieofielist[m[0]] = m[1] + for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE): + ieofielist[m[0]] = m[1] + + for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n', lines, re.MULTILINE): + ies = [] + maxLength = 0 + # TODO: handle extensions + if i[1].find('EXTENSION') >= 0: + continue + if fileprefix == "": + fileprefix = i[1][:i[1].find('-')].lower() + for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE): + for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE): + printDebug("Got new ie for message " + i[0] + ": " + str(k)) + if len(k[2]) > maxLength: + maxLength = len(k[2]) + ies.append(k) + + if len(ies) > 0: + iesDefs[i[0]] = { "length": maxLength, "ies": ies } + else: + printWarning("Didn't find any information element for message: " + i[0]) + +if len(iesDefs) == 0: + printFail("No Information Element parsed, exiting") + sys.exit(0) + +fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:] + +f = open(outdir + fileprefix + '_ies_defs.h', 'w') +outputHeaderToFile(f, filename) +f.write("#include \"%s_common.h\"\n\n" % (fileprefix)) +f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper())) +f.write("/* Define the version of script used to generate this file */\n") +f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version))) + +for key in iesDefs: + + if key not in ieofielist.values(): + continue + + for (i, j) in ieofielist.items(): + if j == key: + break + + f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i))) + f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i]))))) + f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i))) + +for key in iesDefs: + keyupperunderscore = re.sub('-', '_', key.upper()) + keylowerunderscore = re.sub('-', '_', key.lower()) + shift = 0 + + if len(iesDefs[key]["ies"]) == 0: + continue + + # Presence mask + for ie in iesDefs[key]["ies"]: + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] == "optional" or ie[3] == "conditional": + f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift, + pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9)) + shift += 1 + if (shift > 0): + f.write("\n") + + f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key))) + if (shift > 0): + f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2)) + for ie in iesDefs[key]["ies"]: + ieunderscore = re.sub('-', '_', ie[2]) + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + if ie[2] in ieofielist: + f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore)) + else: + f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2)) + if ie[3] == "optional": + f.write(" ///< Optional field") + elif ie[3] == "conditional": + f.write(" ///< Conditional field") + f.write("\n") + + f.write("} %s_t;\n\n" % (re.sub('-', '_', key))) + +f.write("typedef struct %s_message_s {\n" % (fileprefix)) +f.write(" %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper)) +f.write(" %s_Criticality_t criticality;\n" % (fileprefix_first_upper)) +f.write(" uint8_t direction;\n") +f.write(" union {\n") + +messageList = iesDefs.keys() +messageList.sort() +for message in messageList: + if message in ieofielist.values(): + continue + if len(iesDefs[message]["ies"]) == 0: + continue + f.write(" %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message)))) +f.write(" } msg;\n") +f.write("} %s_message;\n\n" % (fileprefix)) + +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + keylowerunderscore = re.sub('-', '_', key.lower()) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key)) + f.write("/** \\brief Decode function for %s ies.\n" % (key)) + if len(iesDefs[key]["ies"]) != 0: + f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" * \\param any_p Pointer to the ANY value to decode.\n") + f.write(" **/\n") + f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore)) + if len(iesDefs[key]["ies"]) != 0: + f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" ANY_t *any_p);\n\n") + + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key)) + f.write("/** \\brief Encode function for %s ies.\n" % (key)) + f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" **/\n") + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) + f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + + +for key in iesDefs: + if key not in ieofielist.values(): + continue + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key)) + f.write("/** \\brief Encode function for %s ies.\n" % (key)) + f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" **/\n") + f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key)) + f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) + f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower)) + f.write("/** \\brief Decode function for %s ies.\n" % (key)) + f.write(" * \\param any_p Pointer to the ANY value to decode.\n") + f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n") + f.write(" **/\n") + f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key)) + f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower)) + f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct))) + + + +for key in iesDefs: + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + if key in ieofielist.values(): + f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" * \\param file File descriptor to write output.\n") + f.write(" **/\n") + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower()))) + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + f.write(" %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower)) + else: + f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct)) + f.write(" * \\param message_p Pointer to root message.\n") + f.write(" * \\param file File descriptor to write output.\n") + f.write(" **/\n") + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + f.write(" %s_message *message_p);\n\n" % (fileprefix)) + +f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower())) +f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower())) +f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower())) +f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper())) + +#Generate Decode functions +f = open(outdir + fileprefix + '_decoder.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix)) +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + ielistname = re.sub('UE', 'ue', asn1cStruct) + ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstlower) + + f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + if len(iesDefs[key]["ies"]) != 0: + f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" ANY_t *any_p) {\n\n") + + f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower)) + f.write(" int i, decoded = 0;\n") + if len(iesDefs[key]["ies"]) != 0: + f.write(" int tempDecoded = 0;\n") + + f.write(" assert(any_p != NULL);\n") + if len(iesDefs[key]["ies"]) != 0: + f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + + f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName))) + f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower)) + f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess)) + f.write(" %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:])) + f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess)) + f.write(" switch(ie_p->id) {\n") + for ie in iesDefs[key]["ies"]: + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore) + ietypesubst = re.sub('-', '', ie[2]) + ietypeunderscore = re.sub('-', '_', ie[2]) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" {\n") + f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + if ie[3] != "mandatory": + f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst))) + f.write(" %s_ERROR(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore)) + f.write(" if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" decoded += tempDecoded;\n") + f.write(" if (asn1_xer_print)\n") + f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + if ie[2] in ieofielist.keys(): + f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" %s_ERROR(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" }\n") + else: + f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore)) + #f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" } break;\n") + f.write(" default:\n") + f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower()))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return decoded;\n") + f.write("}\n\n") + +for key in iesDefs: + if key not in ieofielist.values(): + continue + + keyname = re.sub('IEs', '', re.sub('Item', 'List', key)) + + f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower())) + f.write(" %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" int i, decoded = 0;\n") + f.write(" int tempDecoded = 0;\n\n") + + f.write(" assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))); + f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))); + + f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" switch (ie_p->id) {\n") + for ie in iesDefs[key]["ies"]: + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" {\n") + f.write(" %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" %s_ERROR(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname))) + f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + #f.write(" free(%s_p);\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" decoded += tempDecoded;\n") + f.write(" if (asn1_xer_print)\n") + f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)), + re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" } break;\n") + f.write(" default:\n") + f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower()))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return decoded;\n") + f.write("}\n\n") + + +#Generate IES Encode functions +f = open(outdir + fileprefix + '_encoder.c', 'w') +outputHeaderToFile(f,filename) +f.write("#include \"%s_common.h\"\n" % (fileprefix)) +f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix)) +for key in iesDefs: + if key in ieofielist.values(): + continue + + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstwordlower) + + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + # No IE to encode... + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower)) + f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + + f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper)) + + f.write(" assert(%s != NULL);\n" % (firstwordlower)); + f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); + + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + ietypeunderscore = re.sub('-', '_', ie[2]) + + if ie[3] != "mandatory": + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + #f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore)) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess)) + f.write(" }\n\n") + else: + if ie[2] in ieofielist.keys(): + f.write(" %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower)) + f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore)) + f.write("\n") + f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + if ie[2] in ieofielist.keys(): + f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower)) + else: + f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess)) + if ie[2] in ieofielist.keys(): + f.write(" /* Free any dynamic allocation that is no more used */\n") + f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower)) + + f.write(" return 0;\n") + f.write("}\n\n") + +for (key, value) in iesDefs.items(): + if key not in ieofielist.values(): + continue + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + for (i, j) in ieofielist.items(): + if j == key: + break + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower())) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower)) + f.write(" %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) + f.write(" int i;\n") + + f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper)) + + f.write(" assert(%s != NULL);\n" % (firstwordlower)); + f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); + + f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower)) + f.write(" }\n") + f.write(" return 0;\n") + f.write("}\n\n") + +#Generate xer print functions +f = open(outdir + fileprefix + '_xer_print.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \n") +f.write("#include \n\n") +f.write("#include \n#include \n\n") +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix)) + +f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower())) +f.write("""int +%s_xer__print2fp(const void *buffer, size_t size, void *app_key) { + FILE *stream = (FILE *)app_key; + + if(fwrite(buffer, 1, size, stream) != size) + return -1; + + return 0; +} + +""" % (fileprefix.lower())) + +f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) { + char *string = (char *)app_key; + + /* Copy buffer to the formatted string */ + memcpy(&string[%s_string_total_size], buffer, size); + + %s_string_total_size += size; + + return 0; +} + +""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower())) + +f.write("""static asn_enc_rval_t +xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr, + asn_app_consume_bytes_f *cb, void *app_key, int indent) { + asn_enc_rval_t er, tmper; + const char *mname; + size_t mlen; + int xcan = 2; + + if(!td || !sptr) goto cb_failed; + + mname = td->xml_tag; + mlen = strlen(mname); + + ASN__TEXT_INDENT(0, indent); + ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); + + tmper = td->op->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key); + if(tmper.encoded == -1) return tmper; + + ASN__CALLBACK3("\\n", xcan); + + er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; + + ASN__ENCODED_OK(er); +cb_failed: + ASN__ENCODE_FAILED; +} +""") + +for (key, value) in iesDefs.items(): + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + iesStructName = lowerFirstCamelWord(re.sub('-', '_', key)) + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + + if key in ieofielist.values(): + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower())))) + else: + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower()))) + #f.write(" FILE *file,\n") + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + if key in ieofielist.values(): + iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key))) + f.write(" %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName)) + f.write(" int i;\n") + f.write(" asn_enc_rval_t er;\n") + else: + f.write(" %s_message *message_p)\n{\n" % (fileprefix)) + f.write(" %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName)) + f.write(" asn_enc_rval_t er;\n") + #f.write(" void *app_key = (void *)file;\n") + #f.write(" asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower())) + + f.write(" %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName)) + + if key in ieofielist.values(): + # Increase indentation level + f.write(" for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + #f.write(" xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" }\n") + else: + f.write(" cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key)))) + f.write(" xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper) + f.write(" xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper) + + f.write(" cb(\" <%s>\\n\", %d, app_key);\n" % (key, len(" <%s>\n" % (key)))) + + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ietypeunderscore = re.sub('-', '_', ie[2]) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] != "mandatory": + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s->presenceMask & %s_%s_PRESENT)\n " % (iesStructName, keyupperunderscore, ieupperunderscore)) + + # Is it an encapsulated IE ? + if ie[2] in ieofielist.keys(): + f.write(" %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower)) + else: + f.write(" xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower)) + f.write(" cb(\" \\n\", %d, app_key);\n" % (key, len(" \n" % (key)))) + f.write(" cb(\"\\n\", %d, app_key);\n" % (key, len("\n" % (key)))) + + f.write(" ASN__ENCODED_OK(er);\n") + #if key not in ieofielist.values(): + #f.write("cb_failed:\n") + #f.write(" return er;\n") + f.write("}\n\n") + + +#Generate xer print functions +f = open(outdir + fileprefix + '_compare.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \n") +f.write("#include \n\n") +f.write("#include \n#include \n\n") +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n" % (fileprefix, fileprefix)) +f.write("#include \"%s-ProtocolIE-ID.h\"\n\n" % (fileprefix_first_upper)) + + +for (key, value) in iesDefs.items(): + if key not in ieofielist.values(): + continue + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + for (i, j) in ieofielist.items(): + if j == key: + break + + f.write("extern asn_TYPE_descriptor_t asn_DEF_%s;\n" % (ietypeunderscore)) From 5f00b40e4523c66c59fa6f49447e2b2efc13aff9 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 14:17:58 +0200 Subject: [PATCH 002/134] asn1_msg.do_DrxConfig --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 61 ++++++++++++++-------------- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 3 +- openair2/RRC/LTE/rrc_eNB.c | 4 +- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9303fb79f1..375281057f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -625,10 +625,9 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, /* * Generate the configuration structure for CDRX feature */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, - int CC_id, - RrcConfigurationReq *configuration, - LTE_UE_EUTRA_Capability_t *UEcap) +LTE_DRX_Config_t *do_DrxConfig(int CC_id, + RrcConfigurationReq *configuration, + LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { LTE_DRX_Config_t *drxConfig = NULL; @@ -666,58 +665,60 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, if (drxConfig->present == LTE_DRX_Config_PR_release) { drxConfig->choice.release = (NULL_t) 0; } else { - drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - drxConfig->choice.setup.drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; - drxConfig->choice.setup.drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; - drxConfig->choice.setup.longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; - switch (drxConfig->choice.setup.longDRX_CycleStartOffset.present) { + struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; + choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + // drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; + choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; + choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; default: break; @@ -725,12 +726,12 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, /* Short DRX cycle configuration */ if (!ueSupportCdrxShortFlag || configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer == 0) { - drxConfig->choice.setup.shortDRX = NULL; + choiceSetup->shortDRX = NULL; } else { - drxConfig->choice.setup.shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); - memset(drxConfig->choice.setup.shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); - drxConfig->choice.setup.shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; - drxConfig->choice.setup.shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; + choiceSetup->shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); + memset(choiceSetup->shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); + choiceSetup->shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; + choiceSetup->shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 7ddf939e6d..29e2e8e389 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -81,12 +81,11 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFNSubframes, uint32_t frame); /** \brief Generate configuration structure for DRX_Config -@param Mod_id Instance of eNB @param CC_id Id of component to configure @param configuration Pointer Configuration Request structure @param UEcap Pointer Configuration UE capablities @return DRX_Config structure pointer or NULL => error */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); +LTE_DRX_Config_t *do_DrxConfig(int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); /** \brief Generate configuration for SIB1 (eNB). diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d93510ac5d..73a6ea1381 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3219,7 +3219,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } @@ -3951,7 +3951,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } From b01623f698344fe0e7246af3dee90396e2a4e7ea Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 15:42:45 +0200 Subject: [PATCH 003/134] cdrx_configured update --- openair2/LAYER2/MAC/config.c | 61 ++++++++++++++-------------- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 1 - openair2/RRC/LTE/rrc_eNB.c | 4 +- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ec2497d6ad..621dafe603 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1002,7 +1002,7 @@ void eNB_Config_Local_DRX( UE_list_t *UE_list_mac = NULL; int UE_id = -1; UE_sched_ctrl_t *UE_scheduling_control = NULL; - + UE_list_mac = &(RC.mac[Mod_id]->UE_list); UE_id = find_UE_id(Mod_id, rnti); @@ -1018,31 +1018,30 @@ void eNB_Config_Local_DRX( /* Get struct to modify */ UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]); + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; return; } - /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when ACK is received - UE_scheduling_control->cdrx_waiting_ack = TRUE; // set to true first, waiting for the UE to configure CDRX on its side + /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ + LOG_I(MAC, "Initial cdrx_waiting_ack state: %s\n", UE_scheduling_control->cdrx_waiting_ack ? "TRUE" : "FALSE"); + UE_scheduling_control->cdrx_configured = TRUE; // will be set to true + UE_scheduling_control->cdrx_waiting_ack = TRUE; // For debugging only UE_scheduling_control->in_active_time = FALSE; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; - switch (drx_Configuration->choice.setup.onDurationTimer) { + struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; + switch (choiceSetup->onDurationTimer) { case 0: UE_scheduling_control->on_duration_timer_thres = 1; break; @@ -1097,7 +1096,7 @@ void eNB_Config_Local_DRX( } UE_scheduling_control->drx_inactivity_timer = 0; - switch (drx_Configuration->choice.setup.drx_InactivityTimer) { + switch (choiceSetup->drx_InactivityTimer) { case 0: UE_scheduling_control->drx_inactivity_timer_thres = 1; break; @@ -1172,7 +1171,7 @@ void eNB_Config_Local_DRX( break; } - if (drx_Configuration->choice.setup.shortDRX == NULL) { + if (choiceSetup->shortDRX == NULL) { UE_scheduling_control->in_short_drx_cycle = FALSE; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; @@ -1180,8 +1179,8 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { UE_scheduling_control->in_short_drx_cycle = FALSE; - UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) drx_Configuration->choice.setup.shortDRX->drxShortCycleTimer; - switch (drx_Configuration->choice.setup.shortDRX->shortDRX_Cycle) { + UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; + switch (choiceSetup->shortDRX->shortDRX_Cycle) { case 0: UE_scheduling_control->short_drx_cycle_duration = 2; break; @@ -1241,70 +1240,70 @@ void eNB_Config_Local_DRX( UE_scheduling_control->in_long_drx_cycle = FALSE; UE_scheduling_control->drx_longCycle_timer = 0; - switch (drx_Configuration->choice.setup.longDRX_CycleStartOffset.present) { + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: UE_scheduling_control->drx_longCycle_timer_thres = 10; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf10; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf10; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: UE_scheduling_control->drx_longCycle_timer_thres = 20; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf20; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf20; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: UE_scheduling_control->drx_longCycle_timer_thres = 32; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf32; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf32; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: UE_scheduling_control->drx_longCycle_timer_thres = 40; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf40; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf40; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: UE_scheduling_control->drx_longCycle_timer_thres = 64; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf64; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf64; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: UE_scheduling_control->drx_longCycle_timer_thres = 80; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf80; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf80; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: UE_scheduling_control->drx_longCycle_timer_thres = 128; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf128; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf128; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: UE_scheduling_control->drx_longCycle_timer_thres = 160; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf160; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf160; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: UE_scheduling_control->drx_longCycle_timer_thres = 256; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf256; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf256; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: UE_scheduling_control->drx_longCycle_timer_thres = 320; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf320; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf320; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: UE_scheduling_control->drx_longCycle_timer_thres = 512; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf512; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf512; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: UE_scheduling_control->drx_longCycle_timer_thres = 640; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf640; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf640; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: UE_scheduling_control->drx_longCycle_timer_thres = 1024; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1024; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1024; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: UE_scheduling_control->drx_longCycle_timer_thres = 1280; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1280; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1280; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: UE_scheduling_control->drx_longCycle_timer_thres = 2048; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2048; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2048; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: UE_scheduling_control->drx_longCycle_timer_thres = 2560; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2560; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560; break; default: LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n"); @@ -1312,7 +1311,7 @@ void eNB_Config_Local_DRX( } memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer)); - switch (drx_Configuration->choice.setup.drx_RetransmissionTimer) { + switch (choiceSetup->drx_RetransmissionTimer) { case 0: memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 375281057f..f38720f56c 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -667,7 +667,6 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } else { struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - // drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 73a6ea1381..068f24d5ab 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6503,8 +6503,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; - LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + // UE_scheduling_control->cdrx_configured = TRUE; + LOG_I(RRC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); } } // No CDRX with the CU/DU split in this version of the code From 8ba41e82a2d777bef5545f3565cbff59b35a9c37 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Thu, 5 Sep 2019 15:27:26 +0200 Subject: [PATCH 004/134] Status RRC-RECONFIGURED update --- openair2/RRC/LTE/L2_interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 219c905c42..522f42d5fd 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -312,10 +312,8 @@ mac_rrc_data_ind( if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) { LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status); return (-1); - } else { - rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - } + } + rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); } } From 0fe0dd89bb930106cbedcede26ca99da93b3c412 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 5 Sep 2019 15:53:01 +0200 Subject: [PATCH 005/134] CI: CDRX testing was limited to 1 UE due to instability. Back to normal testing Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml index f62c31dd5a..a76f188bc4 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml @@ -56,7 +56,6 @@ Attach_UE Attach UE - 1 From 2a35715c9ebe45571eb63e9660b783bb038119cb Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sun, 8 Sep 2019 21:53:13 +0200 Subject: [PATCH 006/134] M2AP, M3AP ITTI message defs/types --- openair2/COMMON/m2ap_messages_def.h | 93 ++++ openair2/COMMON/m2ap_messages_types.h | 665 ++++++++++++++++++++++++++ openair2/COMMON/m3ap_messages_def.h | 71 +++ openair2/COMMON/m3ap_messages_types.h | 330 +++++++++++++ 4 files changed, 1159 insertions(+) create mode 100644 openair2/COMMON/m2ap_messages_def.h create mode 100644 openair2/COMMON/m2ap_messages_types.h create mode 100644 openair2/COMMON/m3ap_messages_def.h create mode 100644 openair2/COMMON/m3ap_messages_types.h diff --git a/openair2/COMMON/m2ap_messages_def.h b/openair2/COMMON/m2ap_messages_def.h new file mode 100644 index 0000000000..f4273573cd --- /dev/null +++ b/openair2/COMMON/m2ap_messages_def.h @@ -0,0 +1,93 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* eNB application layer -> M2AP messages */ +/* ITTI LOG messages */ +/* ENCODER */ +MESSAGE_DEF(M2AP_RESET_REQUST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_reset_request_log) +MESSAGE_DEF(M2AP_RESOURCE_STATUS_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_resource_status_response_log) +MESSAGE_DEF(M2AP_RESOURCE_STATUS_FAILURE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_resource_status_failure_log) + +/* Messages for M2AP logging */ +MESSAGE_DEF(M2AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_setup_request_log) + + +/* eNB application layer -> M2AP messages */ +MESSAGE_DEF(M2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, m2ap_register_enb_req_t , m2ap_register_enb_req) +MESSAGE_DEF(M2AP_SUBFRAME_PROCESS , MESSAGE_PRIORITY_MED, m2ap_subframe_process_t , m2ap_subframe_process) + +/* M2AP -> eNB application layer messages */ +MESSAGE_DEF(M2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, m2ap_register_enb_cnf_t , m2ap_register_enb_cnf) +MESSAGE_DEF(M2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, m2ap_deregistered_enb_ind_t , m2ap_deregistered_enb_ind) + +/* handover messages M2AP <-> RRC */ +//MESSAGE_DEF(M2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, m2ap_handover_req_t , m2ap_handover_req) +//MESSAGE_DEF(M2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, m2ap_handover_req_ack_t , m2ap_handover_req_ack) +//MESSAGE_DEF(M2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, m2ap_handover_cancel_t , m2ap_handover_cancel) + +/* handover messages M2AP <-> S1AP */ +//MESSAGE_DEF(M2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, m2ap_ue_context_release_t , m2ap_ue_context_release) + +/* M2AP -> SCTP */ + +MESSAGE_DEF(M2AP_MCE_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_mce_sctp_req_t , m2ap_mce_sctp_req) +//MESSAGE_DEF(M2AP_ENB_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_enb_setup_req_t , f1ap_enb_setup_req) + +/* eNB_DU application layer -> M2AP messages or CU M2AP -> RRC*/ +MESSAGE_DEF(M2AP_SETUP_REQ , MESSAGE_PRIORITY_MED, m2ap_setup_req_t , m2ap_setup_req) + +MESSAGE_DEF(M2AP_SETUP_RESP , MESSAGE_PRIORITY_MED, m2ap_setup_resp_t , m2ap_setup_resp) +MESSAGE_DEF(M2AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED, m2ap_setup_failure_t , m2ap_setup_failure) + +MESSAGE_DEF(M2AP_RESET , MESSAGE_PRIORITY_MED, m2ap_reset_t , m2ap_reset) + +MESSAGE_DEF(M2AP_REGISTER_MCE_REQ , MESSAGE_PRIORITY_MED, m2ap_register_mce_req_t , m2ap_register_mce_req) + +MESSAGE_DEF(M2AP_MBMS_SCHEDULING_INFORMATION , MESSAGE_PRIORITY_MED, m2ap_mbms_scheduling_information_t , m2ap_mbms_scheduling_information) +MESSAGE_DEF(M2AP_MBMS_SCHEDULING_INFORMATION_RESP , MESSAGE_PRIORITY_MED, m2ap_mbms_scheduling_information_resp_t , m2ap_mbms_scheduling_information_resp) + +MESSAGE_DEF(M2AP_MBMS_SESSION_START_REQ , MESSAGE_PRIORITY_MED, m2ap_session_start_req_t ,m2ap_session_start_req ) +MESSAGE_DEF(M2AP_MBMS_SESSION_START_RESP , MESSAGE_PRIORITY_MED, m2ap_session_start_resp_t ,m2ap_session_start_resp ) +MESSAGE_DEF(M2AP_MBMS_SESSION_START_FAILURE , MESSAGE_PRIORITY_MED, m2ap_session_start_failure_t ,m2ap_session_start_failure ) + +MESSAGE_DEF(M2AP_MBMS_SESSION_STOP_REQ , MESSAGE_PRIORITY_MED, m2ap_session_stop_req_t ,m2ap_session_stop_req ) +MESSAGE_DEF(M2AP_MBMS_SESSION_STOP_RESP , MESSAGE_PRIORITY_MED, m2ap_session_stop_resp_t ,m2ap_session_stop_resp ) + + +MESSAGE_DEF(M2AP_ENB_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, m2ap_enb_configuration_update_t, m2ap_enb_configuration_update ) +MESSAGE_DEF(M2AP_ENB_CONFIGURATION_UPDATE_ACK , MESSAGE_PRIORITY_MED, m2ap_enb_configuration_update_ack_t, m2ap_enb_configuration_update_ack ) +MESSAGE_DEF(M2AP_ENB_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, m2ap_enb_configuration_update_failure_t, m2ap_enb_configuration_update_failure ) + +MESSAGE_DEF(M2AP_MCE_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, m2ap_mce_configuration_update_t, m2ap_mce_configuration_update ) +MESSAGE_DEF(M2AP_MCE_CONFIGURATION_UPDATE_ACK , MESSAGE_PRIORITY_MED, m2ap_mce_configuration_update_ack_t, m2ap_mce_configuration_update_ack ) +MESSAGE_DEF(M2AP_MCE_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, m2ap_mce_configuration_update_failure_t, m2ap_mce_configuration_update_failure ) + + +MESSAGE_DEF(M2AP_ERROR_INDICATION , MESSAGE_PRIORITY_MED, m2ap_error_indication_t, m2ap_error_indication ) +MESSAGE_DEF(M2AP_MBMS_SESSION_UPDATE_REQ , MESSAGE_PRIORITY_MED, m2ap_mbms_session_update_req_t, m2ap_mbms_session_update_req ) +MESSAGE_DEF(M2AP_MBMS_SESSION_UPDATE_RESP , MESSAGE_PRIORITY_MED, m2ap_mbms_session_update_resp_t, m2ap_mbms_session_update_resp ) +MESSAGE_DEF(M2AP_MBMS_SESSION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, m2ap_mbms_session_update_failure_t, m2ap_mbms_session_update_failure ) +MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_REPORT , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_report_t, m2ap_mbms_service_counting_report ) +MESSAGE_DEF(M2AP_MBMS_OVERLOAD_NOTIFICATION , MESSAGE_PRIORITY_MED, m2ap_mbms_overload_notification_t, m2ap_mbms_overload_notification ) +MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_REQ , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_req_t, m2ap_mbms_service_counting_req ) +MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_RESP , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_resp_t, m2ap_mbms_service_counting_resp ) +MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_FAILURE , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_failure_t, m2ap_mbms_service_counting_failure ) + diff --git a/openair2/COMMON/m2ap_messages_types.h b/openair2/COMMON/m2ap_messages_types.h new file mode 100644 index 0000000000..f2ee1de43e --- /dev/null +++ b/openair2/COMMON/m2ap_messages_types.h @@ -0,0 +1,665 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef M2AP_MESSAGES_TYPES_H_ +#define M2AP_MESSAGES_TYPES_H_ + +#include "s1ap_messages_types.h" +#include "LTE_PhysCellId.h" + +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. + +#define M2AP_MCE_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_sctp_req + +#define M2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_register_enb_req +//#define M2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_handover_req +//#define M2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.m2ap_handover_req_ack +#define M2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.m2ap_register_enb_cnf +#define M2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.m2ap_deregistered_enb_ind +//#define M2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_ue_context_release +//#define M2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.m2ap_handover_cancel + +#define M2AP_ENB_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_sctp_req +#define M2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_setup_req +#define M2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_setup_resp +#define M2AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_setup_failure + + +#define M2AP_REGISTER_MCE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_register_mce_req + + + +#define M2AP_MBMS_SCHEDULING_INFORMATION(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_scheduling_information +#define M2AP_MBMS_SCHEDULING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_scheduling_information_resp +#define M2AP_MBMS_SESSION_START_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_start_req +#define M2AP_MBMS_SESSION_START_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_start_resp +#define M2AP_MBMS_SESSION_START_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_start_failure +#define M2AP_MBMS_SESSION_STOP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_stop_req +#define M2AP_MBMS_SESSION_STOP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_stop_resp + +#define M2AP_RESET(mSGpTR) (mSGpTR)->ittiMsg.m2ap_reset +#define M2AP_ENB_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_configuration_update +#define M2AP_ENB_CONFIGURATION_UPDATE_ACK(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_configuration_update_ack +#define M2AP_ENB_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_configuration_update_failure +#define M2AP_MCE_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_configuration_update +#define M2AP_MCE_CONFIGURATION_UPDATE_ACK(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_configuration_update_ack +#define M2AP_MCE_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_configuration_update_failure + +#define M2AP_ERROR_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.m2ap_error_indication +#define M2AP_MBMS_SESSION_UPDATE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_session_update_req +#define M2AP_MBMS_SESSION_UPDATE_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_session_update_resp +#define M2AP_MBMS_SESSION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_session_update_failure +#define M2AP_MBMS_SERVICE_COUNTING_REPORT(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_report +#define M2AP_MBMS_OVERLOAD_NOTIFICATION(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_overload_notification +#define M2AP_MBMS_SERVICE_COUNTING_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_req +#define M2AP_MBMS_SERVICE_COUNTING_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_resp +#define M2AP_MBMS_SERVICE_COUNTING_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_failure + +#define M2AP_MAX_NB_ENB_IP_ADDRESS 2 +#define M2AP_MAX_NB_MCE_IP_ADDRESS 2 + +#define M2AP_MAX_NB_CELLS 2 + + + +typedef struct m2ap_net_ip_address_s { + unsigned ipv4:1; + unsigned ipv6:1; + char ipv4_address[16]; + char ipv6_address[46]; +} m2ap_net_ip_address_t; + +typedef struct m2ap_enb_setup_req_s { + // +} m2ap_enb_setup_req_t; + + +typedef struct m2ap_setup_req_s { + + // Midhaul networking parameters + + /* Connexion id used between SCTP/M2AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* The eNB IP address to bind */ + m2ap_net_ip_address_t MCE_M2_ip_address; + m2ap_net_ip_address_t ENB_M2_ip_address; + + /* Number of SCTP streams used for a mme association */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + uint16_t default_sctp_stream_id; + + // M2_Setup_Req payload + uint64_t eNB_id; + char *eNB_name; + + uint64_t GlobalENB_ID; + char * ENBname; + + uint16_t num_mbms_available; + + /* M2AP_MBSFN_SynchronisationArea_ID_t */ + long mbsfn_synchronization_area[M2AP_MAX_NB_CELLS]; + + /* eCGI->eCGI.pLMN_Identity */ + uint16_t plmn_identity[M2AP_MAX_NB_CELLS]; + /* eCGI->eCGI.eUTRANcellIdentifier */ + uint16_t eutran_cell_identifier[M2AP_MAX_NB_CELLS]; + + struct{ + uint16_t mbsfn_sync_area; + uint16_t mbms_service_area_list[8]; + uint16_t num_mbms_service_area_list; + }mbms_configuration_data_list[8]; + uint16_t num_mbms_configuration_data_list; + + +// +// /* The type of the cell */ +// enum cell_type_e cell_type; +// +// /// number of DU cells available +// uint16_t num_cells_available; //0< num_cells_available <= 512; +// +// // +// uint16_t num_mbms_available; +// +// // Served Cell Information +// /* Tracking area code */ +// uint16_t tac[M2AP_MAX_NB_CELLS]; +// +// /* Mobile Country Codes +// * Mobile Network Codes +// */ +// uint16_t mcc[M2AP_MAX_NB_CELLS];//[6]; +// uint16_t mnc[M2AP_MAX_NB_CELLS];//[6]; +// uint8_t mnc_digit_length[M2AP_MAX_NB_CELLS];//[6]; +// +// // NR Global Cell Id +// uint64_t nr_cellid[M2AP_MAX_NB_CELLS]; +// // NR Physical Cell Ids +// uint16_t nr_pci[M2AP_MAX_NB_CELLS]; +// // Number of slide support items (max 16, could be increased to as much as 1024) +// uint16_t num_ssi[M2AP_MAX_NB_CELLS];//[6]; +// uint8_t sst[M2AP_MAX_NB_CELLS];//[16][6]; +// uint8_t sd[M2AP_MAX_NB_CELLS];//[16][6]; +// // fdd_flag = 1 means FDD, 0 means TDD +// int fdd_flag; +// +// /* eCGI->eCGI.pLMN_Identity */ +// uint16_t plmn_identity[M2AP_MAX_NB_CELLS]; +// /* eCGI->eCGI.eUTRANcellIdentifier */ +// uint16_t eutran_cell_identifier[M2AP_MAX_NB_CELLS]; +// +// /* M2AP_MBSFN_SynchronisationArea_ID_t */ +// long mbsfn_synchronization_area[M2AP_MAX_NB_CELLS]; +// +// uint16_t service_area_id[M2AP_MAX_NB_CELLS][4]; +// +// union { +// struct { +// uint32_t ul_nr_arfcn; +// uint8_t ul_scs; +// uint8_t ul_nrb; +// +// uint32_t dl_nr_arfcn; +// uint8_t dl_scs; +// uint8_t dl_nrb; +// +// uint32_t sul_active; +// uint32_t sul_nr_arfcn; +// uint8_t sul_scs; +// uint8_t sul_nrb; +// +// uint8_t ul_num_frequency_bands; +// uint16_t ul_nr_band[32]; +// uint8_t ul_num_sul_frequency_bands; +// uint16_t ul_nr_sul_band[32]; +// +// uint8_t dl_num_frequency_bands; +// uint16_t dl_nr_band[32]; +// uint8_t dl_num_sul_frequency_bands; +// uint16_t dl_nr_sul_band[32]; +// } fdd; +// struct { +// +// uint32_t nr_arfcn; +// uint8_t scs; +// uint8_t nrb; +// +// uint32_t sul_active; +// uint32_t sul_nr_arfcn; +// uint8_t sul_scs; +// uint8_t sul_nrb; +// +// uint8_t num_frequency_bands; +// uint16_t nr_band[32]; +// uint8_t num_sul_frequency_bands; +// uint16_t nr_sul_band[32]; +// +// } tdd; +// } nr_mode_info[M2AP_MAX_NB_CELLS]; +// +// char *measurement_timing_information[M2AP_MAX_NB_CELLS]; +// uint8_t ranac[M2AP_MAX_NB_CELLS]; +// +// // System Information +// uint8_t *mib[M2AP_MAX_NB_CELLS]; +// int mib_length[M2AP_MAX_NB_CELLS]; +// uint8_t *sib1[M2AP_MAX_NB_CELLS]; +// int sib1_length[M2AP_MAX_NB_CELLS]; + + +} m2ap_setup_req_t; + + +typedef struct m2ap_setup_resp_s { + + + + struct { + uint8_t mbsfn_area; + uint8_t pdcch_length; + uint8_t repetition_period; + uint8_t offset; + uint8_t modification_period; + uint8_t subframe_allocation_info; + uint8_t mcs; + } mcch_config_per_mbsfn[8]; + + /* Connexion id used between SCTP/M2AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Number of SCTP streams used for a mme association */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + + uint64_t MCE_id; + char *MCE_name; + + uint8_t num_mcch_config_per_mbsfn; + + +// /// string holding gNB_CU_name +// char *gNB_CU_name; +// /// number of DU cells to activate +// uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512; +// /// mcc of DU cells +// //uint16_t mcc[M2AP_MAX_NB_CELLS]; + uint16_t mcc;//[M2AP_MAX_NB_CELLS]; + /// mnc of DU cells + //uint16_t mnc[M2AP_MAX_NB_CELLS]; + uint16_t mnc;//[M2AP_MAX_NB_CELLS]; + /// mnc digit length of DU cells + //uint8_t mnc_digit_length[M2AP_MAX_NB_CELLS]; + uint8_t mnc_digit_length;//[M2AP_MAX_NB_CELLS]; + // NR Global Cell Id +// uint64_t nr_cellid[M2AP_MAX_NB_CELLS]; +// /// NRPCI +// uint16_t nrpci[M2AP_MAX_NB_CELLS]; +// /// num SI messages per DU cell +// uint8_t num_SI[M2AP_MAX_NB_CELLS]; +// /// SI message containers (up to 21 messages per cell) +// uint8_t *SI_container[M2AP_MAX_NB_CELLS][21]; +// int SI_container_length[M2AP_MAX_NB_CELLS][21]; + +} m2ap_setup_resp_t; + +typedef struct m2ap_setup_failure_s { + uint16_t cause; + uint16_t time_to_wait; + uint16_t criticality_diagnostics; +} m2ap_setup_failure_t; + + + +// eNB application layer -> M2AP messages + +/* M2AP UE CONTEXT RELEASE */ +//typedef struct m2ap_ue_context_release_s { +// /* used for M2AP->RRC in source and RRC->M2AP in target */ +// int rnti; +// +// int source_assoc_id; +//} m2ap_ue_context_release_t; + +//typedef enum { +// M2AP_T_RELOC_PREP_TIMEOUT, +// M2AP_TX2_RELOC_OVERALL_TIMEOUT +//} m2ap_handover_cancel_cause_t; + +//typedef struct m2ap_handover_cancel_s { +// int rnti; +// m2ap_handover_cancel_cause_t cause; +//} m2ap_handover_cancel_t; +typedef struct m2ap_register_mce_req_s { + /* Unique eNB_id to identify the eNB within EPC. + * For macro eNB ids this field should be 20 bits long. + * For home eNB ids this field should be 28 bits long. + */ + uint32_t MCE_id; + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Optional name for the cell + * NOTE: the name can be NULL (i.e no name) and will be cropped to 150 + * characters. + */ + char *MCE_name; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* + * CC Params + */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + /* To be considered for TDD */ + //uint16_t tdd_EARFCN; + //uint16_t tdd_Transmission_Bandwidth; + + /* The local eNB IP address to bind */ + net_ip_address_t mce_m2_ip_address; + + /* Nb of MME to connect to */ + uint8_t nb_m2; + + /* List of target eNB to connect to for M2*/ + net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS]; + + /* Number of SCTP streams used for associations */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + /* eNB port for M2C*/ + uint32_t mce_port_for_M2C; + + /* timers (unit: millisecond) */ + int t_reloc_prep; + int tm2_reloc_overall; +} m2ap_register_mce_req_t; + + +typedef struct m2ap_register_enb_req_s { + /* Unique eNB_id to identify the eNB within EPC. + * For macro eNB ids this field should be 20 bits long. + * For home eNB ids this field should be 28 bits long. + */ + uint32_t eNB_id; + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Optional name for the cell + * NOTE: the name can be NULL (i.e no name) and will be cropped to 150 + * characters. + */ + char *eNB_name; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + struct{ + uint16_t mbsfn_sync_area; + uint16_t mbms_service_area_list[8]; + uint16_t num_mbms_service_area_list; + }mbms_configuration_data_list[8]; + uint16_t num_mbms_configuration_data_list; + + + + /* + * CC Params + */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + /* To be considered for TDD */ + //uint16_t tdd_EARFCN; + //uint16_t tdd_Transmission_Bandwidth; + + /* The local eNB IP address to bind */ + net_ip_address_t enb_m2_ip_address; + + /* Nb of MME to connect to */ + uint8_t nb_m2; + + /* List of target eNB to connect to for M2*/ + net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS]; + + /* Number of SCTP streams used for associations */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + /* eNB port for M2C*/ + uint32_t enb_port_for_M2C; + + /* timers (unit: millisecond) */ + int t_reloc_prep; + int tm2_reloc_overall; +} m2ap_register_enb_req_t; + +typedef struct m2ap_subframe_process_s { + /* nothing, we simply use the module ID in the header */ +} m2ap_subframe_process_t; + +//-------------------------------------------------------------------------------------------// +// M2AP -> eNB application layer messages +typedef struct m2ap_register_enb_cnf_s { + /* Nb of connected eNBs*/ + uint8_t nb_m2; +} m2ap_register_enb_cnf_t; + +typedef struct m2ap_deregistered_enb_ind_s { + /* Nb of connected eNBs */ + uint8_t nb_m2; +} m2ap_deregistered_enb_ind_t; + + +typedef struct m2ap_mbms_scheduling_information_s { + uint16_t mcch_update_time; + struct{ + uint8_t common_sf_allocation_period; + uint8_t mbms_area_id; + struct{ + uint8_t allocated_sf_end; + uint8_t data_mcs; + uint8_t mch_scheduling_period; + struct{ + //struct{ + uint32_t service_id; + uint16_t lcid; + uint8_t mcc; + uint8_t mnc; + uint8_t mnc_length; + //}mbms_session_per_pmch[8]; + //int num_mbms_session_per_pmch; + }mbms_session_list[8]; + int num_mbms_session_list; + }pmch_config_list[8]; + int num_pmch_config_list; + + struct{ + uint8_t radioframe_allocation_period; + uint8_t radioframe_allocation_offset; + uint8_t is_four_sf; + uint32_t subframe_allocation; + }mbms_sf_config_list[8]; + int num_mbms_sf_config_list; + + }mbms_area_config_list[8]; + uint8_t num_mbms_area_config_list; + + + + + + uint16_t mcc[M2AP_MAX_NB_CELLS];//[6]; + uint16_t mnc[M2AP_MAX_NB_CELLS];//[6]; + uint8_t mnc_digit_length[M2AP_MAX_NB_CELLS];//[6]; + uint8_t TMGI[5]; // {4,3,2,1,0}; + uint8_t is_one_frame; + uint8_t buf1; //i.e 0x38<<2 + uint8_t buf2; //i.e 0x38<<2 + uint8_t buf3; //i.e 0x38<<2 + uint16_t common_subframe_allocation_period; + +} m2ap_mbms_scheduling_information_t; + + +typedef struct m2ap_mce_sctp_req_s { + /* The local MCE IP address to bind */ + net_ip_address_t mce_m2_ip_address; + + /* eNB port for M2C*/ + uint32_t mce_port_for_M2C; +}m2ap_mce_sctp_req_t; + +typedef struct m2ap_mbms_scheduling_information_resp_s { +} m2ap_mbms_scheduling_information_resp_t; +typedef struct m2ap_session_start_req_s { +} m2ap_session_start_req_t; +typedef struct m2ap_session_start_resp_s { +} m2ap_session_start_resp_t; +typedef struct m2ap_session_start_failure_s { +} m2ap_session_start_failure_t; +typedef struct m2ap_session_stop_req_s { +} m2ap_session_stop_req_t; +typedef struct m2ap_session_stop_resp_s { +} m2ap_session_stop_resp_t; +typedef struct m2ap_reset_s { +} m2ap_reset_t; +typedef struct m2ap_enb_configuration_update_s { +} m2ap_enb_configuration_update_t; +typedef struct m2ap_enb_configuration_update_ack_s { +} m2ap_enb_configuration_update_ack_t; +typedef struct m2ap_enb_configuration_update_failure_s { +} m2ap_enb_configuration_update_failure_t; +typedef struct m2ap_mce_configuration_update_s { +} m2ap_mce_configuration_update_t; +typedef struct m2ap_mce_configuration_update_ack_s { +} m2ap_mce_configuration_update_ack_t; +typedef struct m2ap_mce_configuration_update_failure_s { +} m2ap_mce_configuration_update_failure_t; +typedef struct m2ap_error_indication_s { +}m2ap_error_indication_t; +typedef struct m2ap_mbms_session_update_req_s { +} m2ap_mbms_session_update_req_t; +typedef struct m2ap_mbms_session_update_resp_s { +} m2ap_mbms_session_update_resp_t; +typedef struct m2ap_mbms_session_update_failure_s { +} m2ap_mbms_session_update_failure_t; +typedef struct m2ap_mbms_service_counting_report_s { +} m2ap_mbms_service_counting_report_t; +typedef struct m2ap_mbms_overload_notification_s { +} m2ap_mbms_overload_notification_t; +typedef struct m2ap_mbms_service_counting_req_s { +} m2ap_mbms_service_counting_req_t; +typedef struct m2ap_mbms_service_counting_resp_s { +} m2ap_mbms_service_counting_resp_t; +typedef struct m2ap_mbms_service_counting_failure_s { +} m2ap_mbms_service_counting_failure_t; + + +//-------------------------------------------------------------------------------------------// +// M2AP <-> RRC +//typedef struct m2ap_gummei_s { +// uint16_t mcc; +// uint16_t mnc; +// uint8_t mnc_len; +// uint8_t mme_code; +// uint16_t mme_group_id; +//} m2ap_gummei_t; +// +//typedef struct m2ap_lastvisitedcell_info_s { +// uint16_t mcc; +// uint16_t mnc; +// uint8_t mnc_len; +// LTE_PhysCellId_t target_physCellId; +// cell_type_t cell_type; +// uint64_t time_UE_StayedInCell; +//}m2ap_lastvisitedcell_info_t; +// +//typedef struct m2ap_handover_req_s { +// /* used for RRC->M2AP in source eNB */ +// int rnti; +// +// /* used for M2AP->RRC in target eNB */ +// int x2_id; +// +// LTE_PhysCellId_t target_physCellId; +// +// m2ap_gummei_t ue_gummei; +// +// /*UE-ContextInformation */ +// +// /* MME UE id */ +// uint32_t mme_ue_s1ap_id; +// +// security_capabilities_t security_capabilities; +// +// uint8_t kenb[32]; // keNB or keNB* +// +// /*next_hop_chaining_coun */ +// long int kenb_ncc; +// +// /* UE aggregate maximum bitrate */ +// ambr_t ue_ambr; +// +// uint8_t nb_e_rabs_tobesetup; +// +// /* list of e_rab setup-ed by RRC layers */ +// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB]; +// +// /* list of e_rab to be setup by RRC layers */ +// e_rab_t e_rab_param[S1AP_MAX_E_RAB]; +// +// m2ap_lastvisitedcell_info_t lastvisitedcell_info; +// +// uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; +// int rrc_buffer_size; +// +// int target_assoc_id; +//} m2ap_handover_req_t; +// +//typedef struct m2ap_handover_req_ack_s { +// /* used for RRC->M2AP in target and M2AP->RRC in source */ +// int rnti; +// +// /* used for RRC->M2AP in target */ +// int x2_id_target; +// +// int source_assoc_id; +// +// uint8_t nb_e_rabs_tobesetup; +// +// /* list of e_rab setup-ed by RRC layers */ +// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB]; +// +// /* list of e_rab to be setup by RRC layers */ +// e_rab_t e_rab_param[S1AP_MAX_E_RAB]; +// +// uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; +// int rrc_buffer_size; +// +// uint32_t mme_ue_s1ap_id; +//} m2ap_handover_req_ack_t; +// +#endif /* M2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/m3ap_messages_def.h b/openair2/COMMON/m3ap_messages_def.h new file mode 100644 index 0000000000..9ee725447d --- /dev/null +++ b/openair2/COMMON/m3ap_messages_def.h @@ -0,0 +1,71 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* eNB application layer -> M3AP messages */ +/* ITTI LOG messages */ +/* ENCODER */ +MESSAGE_DEF(M3AP_RESET_REQUST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_reset_request_log) +MESSAGE_DEF(M3AP_RESOURCE_STATUS_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_resource_status_response_log) +MESSAGE_DEF(M3AP_RESOURCE_STATUS_FAILURE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_resource_status_failure_log) + +/* Messages for M3AP logging */ +MESSAGE_DEF(M3AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_setup_request_log) + + +/* eNB application layer -> M3AP messages */ +MESSAGE_DEF(M3AP_REGISTER_MCE_REQ , MESSAGE_PRIORITY_MED, m3ap_register_mce_req_t , m3ap_register_mce_req) +MESSAGE_DEF(M3AP_SUBFRAME_PROCESS , MESSAGE_PRIORITY_MED, m3ap_subframe_process_t , m3ap_subframe_process) + +/* M3AP -> eNB application layer messages */ +MESSAGE_DEF(M3AP_REGISTER_MCE_CNF , MESSAGE_PRIORITY_MED, m3ap_register_mce_cnf_t , m3ap_register_mce_cnf) +MESSAGE_DEF(M3AP_DEREGISTERED_MCE_IND , MESSAGE_PRIORITY_MED, m3ap_deregistered_mce_ind_t , m3ap_deregistered_mce_ind) + +/* handover messages M3AP <-> RRC */ +//MESSAGE_DEF(M3AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, m3ap_handover_req_t , m3ap_handover_req) +//MESSAGE_DEF(M3AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, m3ap_handover_req_ack_t , m3ap_handover_req_ack) +//MESSAGE_DEF(M3AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, m3ap_handover_cancel_t , m3ap_handover_cancel) + +/* handover messages M3AP <-> S1AP */ +//MESSAGE_DEF(M3AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, m3ap_ue_context_release_t , m3ap_ue_context_release) + +MESSAGE_DEF(M3AP_MME_SCTP_REQ , MESSAGE_PRIORITY_MED, m3ap_mme_sctp_req_t , m3ap_mme_sctp_req) + + +MESSAGE_DEF(M3AP_MBMS_SESSION_START_REQ , MESSAGE_PRIORITY_MED ,m3ap_session_start_req_t ,m3ap_session_start_req) +MESSAGE_DEF(M3AP_MBMS_SESSION_START_RESP , MESSAGE_PRIORITY_MED ,m3ap_session_start_resp_t ,m3ap_session_start_resp) +MESSAGE_DEF(M3AP_MBMS_SESSION_START_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_session_start_failure_t ,m3ap_session_start_failure) +MESSAGE_DEF(M3AP_MBMS_SESSION_STOP_REQ , MESSAGE_PRIORITY_MED ,m3ap_session_stop_req_t ,m3ap_session_stop_req) +MESSAGE_DEF(M3AP_MBMS_SESSION_STOP_RESP , MESSAGE_PRIORITY_MED ,m3ap_session_stop_resp_t ,m3ap_session_stop_resp) +MESSAGE_DEF(M3AP_MBMS_SESSION_STOP_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_session_stop_failure_t ,m3ap_session_stop_failure) +MESSAGE_DEF(M3AP_ERROR_INDICATION , MESSAGE_PRIORITY_MED ,m3ap_error_indication_t ,m3ap_error_indication) +MESSAGE_DEF(M3AP_RESET , MESSAGE_PRIORITY_MED ,m3ap_reset_t ,m3ap_reset) +MESSAGE_DEF(M3AP_RESET_ACK , MESSAGE_PRIORITY_MED ,m3ap_reset_ack_t ,m3ap_reset_ack) +MESSAGE_DEF(M3AP_MBMS_SESSION_UPDATE_REQ , MESSAGE_PRIORITY_MED ,m3ap_mbms_session_update_req_t ,m3ap_mbms_session_update_req) +MESSAGE_DEF(M3AP_MBMS_SESSION_UPDATE_RESP , MESSAGE_PRIORITY_MED ,m3ap_mbms_session_update_resp_t ,m3ap_mbms_session_update_resp) +MESSAGE_DEF(M3AP_MBMS_SESSION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_mbms_session_update_failure_t ,m3ap_mbms_session_update_failure) +MESSAGE_DEF(M3AP_SETUP_REQ , MESSAGE_PRIORITY_MED ,m3ap_setup_req_t ,m3ap_setup_req) +MESSAGE_DEF(M3AP_SETUP_RESP , MESSAGE_PRIORITY_MED ,m3ap_setup_resp_t ,m3ap_setup_resp) +MESSAGE_DEF(M3AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_setup_failure_t ,m3ap_setup_failure) +MESSAGE_DEF(M3AP_MCE_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED ,m3ap_mce_configuration_update_t ,m3ap_mce_configuration_update) +MESSAGE_DEF(M3AP_MCE_CONFIGURATION_UPDATE_ACK , MESSAGE_PRIORITY_MED ,m3ap_mce_configuration_update_ack_t ,m3ap_mce_configuration_update_ack) +MESSAGE_DEF(M3AP_MCE_CONFIGURATION_UPDATE_FAILURE, MESSAGE_PRIORITY_MED ,m3ap_mce_configuration_update_failure_t ,m3ap_mce_configuration_update_failure) + + diff --git a/openair2/COMMON/m3ap_messages_types.h b/openair2/COMMON/m3ap_messages_types.h new file mode 100644 index 0000000000..21e24dd449 --- /dev/null +++ b/openair2/COMMON/m3ap_messages_types.h @@ -0,0 +1,330 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef M3AP_MESSAGES_TYPES_H_ +#define M3AP_MESSAGES_TYPES_H_ + +#include "s1ap_messages_types.h" +#include "LTE_PhysCellId.h" + +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. +#define M3AP_MME_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mme_sctp_req + +#define M3AP_REGISTER_MCE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_register_mce_req +//#define M3AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_handover_req +//#define M3AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.m3ap_handover_req_ack +#define M3AP_REGISTER_MCE_CNF(mSGpTR) (mSGpTR)->ittiMsg.m3ap_register_mce_cnf +#define M3AP_DEREGISTERED_MCE_IND(mSGpTR) (mSGpTR)->ittiMsg.m3ap_deregistered_mce_ind +//#define M3AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_ue_context_release +//#define M3AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.m3ap_handover_cancel + + +#define M3AP_MBMS_SESSION_START_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_start_req +#define M3AP_MBMS_SESSION_START_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_start_resp +#define M3AP_MBMS_SESSION_START_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_start_failure +#define M3AP_MBMS_SESSION_STOP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_stop_req +#define M3AP_MBMS_SESSION_STOP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_stop_resp +#define M3AP_MBMS_SESSION_STOP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_stop_failure +#define M3AP_ERROR_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.m3ap_error_indication +#define M3AP_RESET(mSGpTR) (mSGpTR)->ittiMsg.m3ap_reset +#define M3AP_RESET_ACK(mSGpTR) (mSGpTR)->ittiMsg.m3ap_reset_ack +#define M3AP_MBMS_SESSION_UPDATE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mbms_session_update_req +#define M3AP_MBMS_SESSION_UPDATE_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mbms_session_update_resp +#define M3AP_MBMS_SESSION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mbms_session_update_failure +#define M3AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_setup_req +#define M3AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_setup_resp +#define M3AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_setup_failure +#define M3AP_MCE_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mce_configuration_update +#define M3AP_MCE_CONFIGURATION_UPDATE_ACK(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mce_configuration_update_ack +#define M3AP_MCE_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mce_configuration_update_failure + + +#define M3AP_MAX_NB_MCE_IP_ADDRESS 2 + +#define M3AP_MAX_NB_MME_IP_ADDRESS 2 + + +typedef struct m3ap_net_ip_address_s { + unsigned ipv4:1; + unsigned ipv6:1; + char ipv4_address[16]; + char ipv6_address[46]; +} m3ap_net_ip_address_t; + +// eNB application layer -> M3AP messages + +/* M3AP UE CONTEXT RELEASE */ +//typedef struct m3ap_ue_context_release_s { +// /* used for M3AP->RRC in source and RRC->M3AP in target */ +// int rnti; +// +// int source_assoc_id; +//} m3ap_ue_context_release_t; + +//typedef enum { +// M3AP_T_RELOC_PREP_TIMEOUT, +// M3AP_TX2_RELOC_OVERALL_TIMEOUT +//} m3ap_handover_cancel_cause_t; + +//typedef struct m3ap_handover_cancel_s { +// int rnti; +// m3ap_handover_cancel_cause_t cause; +//} m3ap_handover_cancel_t; + +typedef struct m3ap_register_mce_req_s { + /* Unique eNB_id to identify the eNB within EPC. + * For macro eNB ids this field should be 20 bits long. + * For home eNB ids this field should be 28 bits long. + */ + uint32_t MCE_id; + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Optional name for the cell + * NOTE: the name can be NULL (i.e no name) and will be cropped to 150 + * characters. + */ + char *MCE_name; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* + * CC Params + */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + /* To be considered for TDD */ + //uint16_t tdd_EARFCN; + //uint16_t tdd_Transmission_Bandwidth; + + /* The local eNB IP address to bind */ + net_ip_address_t mme_m3_ip_address; + + /* Nb of MME to connect to */ + uint8_t nb_m3; + + /* List of target eNB to connect to for M3*/ + net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MCE_IP_ADDRESS]; + + /* Number of SCTP streams used for associations */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + /* eNB port for M3C*/ + uint32_t mme_port_for_M3C; + + /* timers (unit: millisecond) */ + int t_reloc_prep; + int tm3_reloc_overall; + + /* Nb of MME to connect to */ + uint8_t nb_mme; + /* List of MME to connect to */ + net_ip_address_t mme_ip_address[M3AP_MAX_NB_MME_IP_ADDRESS]; +} m3ap_register_mce_req_t; + +typedef struct m3ap_subframe_process_s { + /* nothing, we simply use the module ID in the header */ +} m3ap_subframe_process_t; + +//-------------------------------------------------------------------------------------------// +// M3AP -> eNB application layer messages +typedef struct m3ap_register_mce_cnf_s { + /* Nb of connected eNBs*/ + uint8_t nb_mme; +} m3ap_register_mce_cnf_t; + +typedef struct m3ap_deregistered_mce_ind_s { + /* Nb of connected eNBs */ + uint8_t nb_mme; +} m3ap_deregistered_mce_ind_t; + +//-------------------------------------------------------------------------------------------// +// M3AP <-> RRC +//typedef struct m3ap_gummei_s { +// uint16_t mcc; +// uint16_t mnc; +// uint8_t mnc_len; +// uint8_t mme_code; +// uint16_t mme_group_id; +//} m3ap_gummei_t; +// +//typedef struct m3ap_lastvisitedcell_info_s { +// uint16_t mcc; +// uint16_t mnc; +// uint8_t mnc_len; +// LTE_PhysCellId_t target_physCellId; +// cell_type_t cell_type; +// uint64_t time_UE_StayedInCell; +//}m3ap_lastvisitedcell_info_t; +// +//typedef struct m3ap_handover_req_s { +// /* used for RRC->M3AP in source eNB */ +// int rnti; +// +// /* used for M3AP->RRC in target eNB */ +// int x2_id; +// +// LTE_PhysCellId_t target_physCellId; +// +// m3ap_gummei_t ue_gummei; +// +// /*UE-ContextInformation */ +// +// /* MME UE id */ +// uint32_t mme_ue_s1ap_id; +// +// security_capabilities_t security_capabilities; +// +// uint8_t kenb[32]; // keNB or keNB* +// +// /*next_hop_chaining_coun */ +// long int kenb_ncc; +// +// /* UE aggregate maximum bitrate */ +// ambr_t ue_ambr; +// +// uint8_t nb_e_rabs_tobesetup; +// +// /* list of e_rab setup-ed by RRC layers */ +// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB]; +// +// /* list of e_rab to be setup by RRC layers */ +// e_rab_t e_rab_param[S1AP_MAX_E_RAB]; +// +// m3ap_lastvisitedcell_info_t lastvisitedcell_info; +// +// uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; +// int rrc_buffer_size; +// +// int target_assoc_id; +//} m3ap_handover_req_t; +// +//typedef struct m3ap_handover_req_ack_s { +// /* used for RRC->M3AP in target and M3AP->RRC in source */ +// int rnti; +// +// /* used for RRC->M3AP in target */ +// int x2_id_target; +// +// int source_assoc_id; +// +// uint8_t nb_e_rabs_tobesetup; +// +// /* list of e_rab setup-ed by RRC layers */ +// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB]; +// +// /* list of e_rab to be setup by RRC layers */ +// e_rab_t e_rab_param[S1AP_MAX_E_RAB]; +// +// uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; +// int rrc_buffer_size; +// +// uint32_t mme_ue_s1ap_id; +//} m3ap_handover_req_ack_t; +// + +typedef struct m3ap_mme_sctp_req_s { + /* the local mce ip address to bind */ + net_ip_address_t mme_m3_ip_address; + + /* enb port for m2c*/ + uint32_t mme_port_for_M3C; +}m3ap_mme_sctp_req_t; + + + +typedef struct m3ap_session_start_req_s{ +}m3ap_session_start_req_t; +typedef struct m3ap_session_start_resp_s{ +}m3ap_session_start_resp_t; +typedef struct m3ap_session_start_failure_s{ +}m3ap_session_start_failure_t; +typedef struct m3ap_session_stop_req_s{ +}m3ap_session_stop_req_t; +typedef struct m3ap_session_stop_resp_s{ +}m3ap_session_stop_resp_t; +typedef struct m3ap_session_stop_failure_s{ +}m3ap_session_stop_failure_t; +typedef struct m3ap_error_indication_s{ +}m3ap_error_indication_t; +typedef struct m3ap_reset_s{ +}m3ap_reset_t; +typedef struct m3ap_reset_ack_s{ +}m3ap_reset_ack_t; +typedef struct m3ap_mbms_session_update_req_s{ +}m3ap_mbms_session_update_req_t; +typedef struct m3ap_mbms_session_update_resp_s{ +}m3ap_mbms_session_update_resp_t; +typedef struct m3ap_mbms_session_update_failure_s{ +}m3ap_mbms_session_update_failure_t; +typedef struct m3ap_setup_req_s{ + /* Connexion id used between SCTP/M3AP */ + uint16_t cnx_id; + /* SCTP association id */ + int32_t assoc_id; + + /* Number of SCTP streams used for a mme association */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + uint16_t default_sctp_stream_id; +}m3ap_setup_req_t; +typedef struct m3ap_setup_resp_s{ +}m3ap_setup_resp_t; +typedef struct m3ap_setup_failure_s{ +}m3ap_setup_failure_t; +typedef struct m3ap_mce_configuration_update_s{ +}m3ap_mce_configuration_update_t; +typedef struct m3ap_mce_configuration_update_ack_s{ +}m3ap_mce_configuration_update_ack_t; +typedef struct m3ap_mce_configuration_update_failure_s{ +}m3ap_mce_configuration_update_failure_t; + + + + + + + + + + + + +#endif /* M3AP_MESSAGES_TYPES_H_ */ From de46db5f6eaa4003c815f33a35efb4826bda2dc2 Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sun, 8 Sep 2019 21:59:38 +0200 Subject: [PATCH 007/134] M2AP, M3AP common defs --- openair2/M2AP/m2ap_common.c | 124 ++++++++++++++++++++++++ openair2/M2AP/m2ap_common.h | 180 +++++++++++++++++++++++++++++++++++ openair3/M3AP/m3ap_common.c | 124 ++++++++++++++++++++++++ openair3/M3AP/m3ap_common.h | 183 ++++++++++++++++++++++++++++++++++++ 4 files changed, 611 insertions(+) create mode 100644 openair2/M2AP/m2ap_common.c create mode 100644 openair2/M2AP/m2ap_common.h create mode 100644 openair3/M3AP/m3ap_common.c create mode 100644 openair3/M3AP/m3ap_common.h diff --git a/openair2/M2AP/m2ap_common.c b/openair2/M2AP/m2ap_common.c new file mode 100644 index 0000000000..d288a0a114 --- /dev/null +++ b/openair2/M2AP/m2ap_common.c @@ -0,0 +1,124 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_common.c + * \brief m2ap procedures for both eNB and MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "m2ap_common.h" +#include "M2AP_M2AP-PDU.h" + +int asn_debug = 0; +int asn1_xer_print = 0; + +#if defined(EMIT_ASN_DEBUG_EXTERN) +inline void ASN_DEBUG(const char *fmt, ...) +{ + if (asn_debug) { + int adi = asn_debug_indent; + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "[ASN1]"); + + while(adi--) fprintf(stderr, " "); + + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + } +} +#endif + +ssize_t m2ap_generate_initiating_message( + uint8_t **buffer, + uint32_t *length, + M2AP_ProcedureCode_t procedureCode, + M2AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr) +{ + M2AP_M2AP_PDU_t pdu; + ssize_t encoded; + memset(&pdu, 0, sizeof(M2AP_M2AP_PDU_t)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = procedureCode; + pdu.choice.initiatingMessage.criticality = criticality; + ANY_fromType_aper((ANY_t *)&pdu.choice.initiatingMessage.value, td, sptr); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, (void *)&pdu); + } + + /* We can safely free list of IE from sptr */ + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr); + + if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M2AP_M2AP_PDU, 0, &pdu, + (void **)buffer)) < 0) { + return -1; + } + + *length = encoded; + return encoded; +} + + +ssize_t m2ap_generate_unsuccessfull_outcome( + uint8_t **buffer, + uint32_t *length, + M2AP_ProcedureCode_t procedureCode, + M2AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr) +{ + M2AP_M2AP_PDU_t pdu; + ssize_t encoded; + memset(&pdu, 0, sizeof(M2AP_M2AP_PDU_t)); + pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.successfulOutcome.procedureCode = procedureCode; + pdu.choice.successfulOutcome.criticality = criticality; + ANY_fromType_aper((ANY_t *)&pdu.choice.successfulOutcome.value, td, sptr); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, (void *)&pdu); + } + + /* We can safely free list of IE from sptr */ + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr); + + if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M2AP_M2AP_PDU, 0, &pdu, + (void **)buffer)) < 0) { + return -1; + } + + *length = encoded; + return encoded; +} + +void m2ap_handle_criticality(M2AP_Criticality_t criticality) +{ + +} + diff --git a/openair2/M2AP/m2ap_common.h b/openair2/M2AP/m2ap_common.h new file mode 100644 index 0000000000..3c8fcbc462 --- /dev/null +++ b/openair2/M2AP/m2ap_common.h @@ -0,0 +1,180 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#if HAVE_CONFIG_H_ +# include "config.h" +#endif + +#include "M2AP_ProtocolIE-Field.h" +#include "M2AP_M2AP-PDU.h" +#include "M2AP_InitiatingMessage.h" +#include "M2AP_SuccessfulOutcome.h" +#include "M2AP_UnsuccessfulOutcome.h" +#include "M2AP_ProtocolIE-FieldPair.h" +#include "M2AP_ProtocolIE-ContainerPair.h" +#include "M2AP_ProtocolExtensionField.h" +#include "M2AP_ProtocolExtensionContainer.h" +#include "M2AP_PMCH-Configuration-Item.h" +#include "M2AP_asn_constant.h" +#include "intertask_interface.h" + +#include "common/ran_context.h" + +#ifndef M2AP_COMMON_H_ +#define M2AP_COMMON_H_ + +/*! \file m2ap_common.h + * \brief m2ap procedures for both eNB and MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +/* Checking version of ASN1C compiler */ +#if (ASN1C_ENVIRONMENT_VERSION < 923) +# error "You are compiling m2ap with the wrong version of ASN1C" +#endif + +#ifndef M2AP_PORT +# define M2AP_PORT 36423 +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +extern int asn1_xer_print; + +#if defined(ENB_MODE) +# include "common/utils/LOG/log.h" +# include "m2ap_default_values.h" +# define M2AP_INFO(x, args...) LOG_I(M2AP, x, ##args) +# define M2AP_ERROR(x, args...) LOG_E(M2AP, x, ##args) +# define M2AP_WARN(x, args...) LOG_W(M2AP, x, ##args) +# define M2AP_DEBUG(x, args...) LOG_D(M2AP, x, ##args) +#else +# define M2AP_INFO(x, args...) do { fprintf(stdout, "[M2AP][I]"x, ##args); } while(0) +# define M2AP_ERROR(x, args...) do { fprintf(stdout, "[M2AP][E]"x, ##args); } while(0) +# define M2AP_WARN(x, args...) do { fprintf(stdout, "[M2AP][W]"x, ##args); } while(0) +# define M2AP_DEBUG(x, args...) do { fprintf(stdout, "[M2AP][D]"x, ##args); } while(0) +#endif + +#define M2AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do {\ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; \ + ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (mandatory) DevAssert(ie != NULL); \ + } while(0) + +/** \brief Function callback prototype. + **/ +typedef int (*m2ap_message_decoded_callback)( + instance_t instance, + uint32_t assocId, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +typedef int (*m2ap_MCE_message_decoded_callback)( + instance_t instance, + uint32_t assocId, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +typedef int (*m2ap_eNB_message_decoded_callback)( + instance_t instance, + uint32_t assocId, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + + + +/** \brief Encode a successfull outcome message + \param buffer pointer to buffer in which data will be encoded + \param length pointer to the length of buffer + \param procedureCode Procedure code for the message + \param criticality Criticality of the message + \param td ASN1C type descriptor of the sptr + \param sptr Deferenced pointer to the structure to encode + @returns size in bytes encded on success or 0 on failure + **/ +ssize_t m2ap_generate_successfull_outcome( + uint8_t **buffer, + uint32_t *length, + M2AP_ProcedureCode_t procedureCode, + M2AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr); + +/** \brief Encode an initiating message + \param buffer pointer to buffer in which data will be encoded + \param length pointer to the length of buffer + \param procedureCode Procedure code for the message + \param criticality Criticality of the message + \param td ASN1C type descriptor of the sptr + \param sptr Deferenced pointer to the structure to encode + @returns size in bytes encded on success or 0 on failure + **/ +ssize_t m2ap_generate_initiating_message( + uint8_t **buffer, + uint32_t *length, + M2AP_ProcedureCode_t procedureCode, + M2AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr); + +/** \brief Encode an unsuccessfull outcome message + \param buffer pointer to buffer in which data will be encoded + \param length pointer to the length of buffer + \param procedureCode Procedure code for the message + \param criticality Criticality of the message + \param td ASN1C type descriptor of the sptr + \param sptr Deferenced pointer to the structure to encode + @returns size in bytes encded on success or 0 on failure + **/ +ssize_t m2ap_generate_unsuccessfull_outcome( + uint8_t **buffer, + uint32_t *length, + M2AP_ProcedureCode_t procedureCode, + M2AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr); + +/** \brief Handle criticality + \param criticality Criticality of the IE + @returns void + **/ +void m2ap_handle_criticality(M2AP_Criticality_t criticality); + +#endif /* M2AP_COMMON_H_ */ diff --git a/openair3/M3AP/m3ap_common.c b/openair3/M3AP/m3ap_common.c new file mode 100644 index 0000000000..d61ead3580 --- /dev/null +++ b/openair3/M3AP/m3ap_common.c @@ -0,0 +1,124 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_common.c + * \brief m3ap procedures for both MCE and MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "m3ap_common.h" +#include "M3AP_M3AP-PDU.h" + +int asn_debug = 0; +int asn1_xer_print = 0; + +#if defined(EMIT_ASN_DEBUG_EXTERN) +inline void ASN_DEBUG(const char *fmt, ...) +{ + if (asn_debug) { + int adi = asn_debug_indent; + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "[ASN1]"); + + while(adi--) fprintf(stderr, " "); + + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + } +} +#endif + +ssize_t m3ap_generate_initiating_message( + uint8_t **buffer, + uint32_t *length, + M3AP_ProcedureCode_t procedureCode, + M3AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr) +{ + M3AP_M3AP_PDU_t pdu; + ssize_t encoded; + memset(&pdu, 0, sizeof(M3AP_M3AP_PDU_t)); + pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = procedureCode; + pdu.choice.initiatingMessage.criticality = criticality; + ANY_fromType_aper((ANY_t *)&pdu.choice.initiatingMessage.value, td, sptr); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)&pdu); + } + + /* We can safely free list of IE from sptr */ + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr); + + if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, &pdu, + (void **)buffer)) < 0) { + return -1; + } + + *length = encoded; + return encoded; +} + + +ssize_t m3ap_generate_unsuccessfull_outcome( + uint8_t **buffer, + uint32_t *length, + M3AP_ProcedureCode_t procedureCode, + M3AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr) +{ + M3AP_M3AP_PDU_t pdu; + ssize_t encoded; + memset(&pdu, 0, sizeof(M3AP_M3AP_PDU_t)); + pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.successfulOutcome.procedureCode = procedureCode; + pdu.choice.successfulOutcome.criticality = criticality; + ANY_fromType_aper((ANY_t *)&pdu.choice.successfulOutcome.value, td, sptr); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)&pdu); + } + + /* We can safely free list of IE from sptr */ + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr); + + if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, &pdu, + (void **)buffer)) < 0) { + return -1; + } + + *length = encoded; + return encoded; +} + +void m3ap_handle_criticality(M3AP_Criticality_t criticality) +{ + +} + diff --git a/openair3/M3AP/m3ap_common.h b/openair3/M3AP/m3ap_common.h new file mode 100644 index 0000000000..83969bf9ef --- /dev/null +++ b/openair3/M3AP/m3ap_common.h @@ -0,0 +1,183 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#if HAVE_CONFIG_H_ +# include "config.h" +#endif + +#include "M3AP_ProtocolIE-Field.h" +#include "M3AP_M3AP-PDU.h" +#include "M3AP_InitiatingMessage.h" +#include "M3AP_SuccessfulOutcome.h" +#include "M3AP_UnsuccessfulOutcome.h" +#include "M3AP_ProtocolIE-FieldPair.h" +#include "M3AP_ProtocolIE-ContainerPair.h" +#include "M3AP_ProtocolExtensionField.h" +#include "M3AP_ProtocolExtensionContainer.h" +#include "M3AP_asn_constant.h" +#include "intertask_interface.h" + +#ifndef M3AP_COMMON_H_ +#define M3AP_COMMON_H_ + +/*! \file m3ap_common.h + * \brief m3ap procedures for both MCE and MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + + +/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +/* Checking version of ASN1C compiler */ +#if (ASN1C_ENVIRONMENT_VERSION < 923) +# error "You are compiling m3ap with the wrong version of ASN1C" +#endif + +#ifndef M3AP_PORT +# define M3AP_PORT 36444 +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +extern int asn1_xer_print; + +#if defined(ENB_MODE) +# include "common/utils/LOG/log.h" +# include "m3ap_default_values.h" +# define M3AP_INFO(x, args...) LOG_I(M3AP, x, ##args) +# define M3AP_ERROR(x, args...) LOG_E(M3AP, x, ##args) +# define M3AP_WARN(x, args...) LOG_W(M3AP, x, ##args) +# define M3AP_DEBUG(x, args...) LOG_D(M3AP, x, ##args) +#else +# define M3AP_INFO(x, args...) do { fprintf(stdout, "[M3AP][I]"x, ##args); } while(0) +# define M3AP_ERROR(x, args...) do { fprintf(stdout, "[M3AP][E]"x, ##args); } while(0) +# define M3AP_WARN(x, args...) do { fprintf(stdout, "[M3AP][W]"x, ##args); } while(0) +# define M3AP_DEBUG(x, args...) do { fprintf(stdout, "[M3AP][D]"x, ##args); } while(0) +#endif + +#define M3AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do {\ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; \ + ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (mandatory) DevAssert(ie != NULL); \ + } while(0) + +/** \brief Function callback prototype. + **/ +typedef int (*m3ap_message_decoded_callback)( + instance_t instance, + uint32_t assocId, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + + +/** \brief Function callback prototype. + **/ +typedef int (*m3ap_MCE_message_decoded_callback)( + instance_t instance, + uint32_t assocId, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +/** \brief Function callback prototype. + **/ +typedef int (*m3ap_MME_message_decoded_callback)( + instance_t instance, + uint32_t assocId, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + + + +/** \brief Encode a successfull outcome message + \param buffer pointer to buffer in which data will be encoded + \param length pointer to the length of buffer + \param procedureCode Procedure code for the message + \param criticality Criticality of the message + \param td ASN1C type descriptor of the sptr + \param sptr Deferenced pointer to the structure to encode + @returns size in bytes encded on success or 0 on failure + **/ +ssize_t m3ap_generate_successfull_outcome( + uint8_t **buffer, + uint32_t *length, + M3AP_ProcedureCode_t procedureCode, + M3AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr); + +/** \brief Encode an initiating message + \param buffer pointer to buffer in which data will be encoded + \param length pointer to the length of buffer + \param procedureCode Procedure code for the message + \param criticality Criticality of the message + \param td ASN1C type descriptor of the sptr + \param sptr Deferenced pointer to the structure to encode + @returns size in bytes encded on success or 0 on failure + **/ +ssize_t m3ap_generate_initiating_message( + uint8_t **buffer, + uint32_t *length, + M3AP_ProcedureCode_t procedureCode, + M3AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr); + +/** \brief Encode an unsuccessfull outcome message + \param buffer pointer to buffer in which data will be encoded + \param length pointer to the length of buffer + \param procedureCode Procedure code for the message + \param criticality Criticality of the message + \param td ASN1C type descriptor of the sptr + \param sptr Deferenced pointer to the structure to encode + @returns size in bytes encded on success or 0 on failure + **/ +ssize_t m3ap_generate_unsuccessfull_outcome( + uint8_t **buffer, + uint32_t *length, + M3AP_ProcedureCode_t procedureCode, + M3AP_Criticality_t criticality, + asn_TYPE_descriptor_t *td, + void *sptr); + +/** \brief Handle criticality + \param criticality Criticality of the IE + @returns void + **/ +void m3ap_handle_criticality(M3AP_Criticality_t criticality); + +#endif /* M3AP_COMMON_H_ */ From 33d7dedd056727d2eba24501d30aa49f46fedeb2 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 10 Sep 2019 15:46:25 +0200 Subject: [PATCH 008/134] rrc_eNB update 10/09 --- openair2/RRC/LTE/rrc_eNB.c | 84 +++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 068f24d5ab..41c5cb9212 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3201,45 +3201,47 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB + mac_MainConfig->drx_Config = NULL; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); if (UE_id != -1) { + eNB_MAC_INST *mac = RC.mac[module_id]; + UE_list_t *UE_list = &(mac->UE_list); + if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); - - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + // CDRX can be only configured in case of FDD and non BR UE (09/04/19) + + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + /* Process the IE drx_Config */ + if (cc_id < MAX_NUM_CCs) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } + } else { + LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); + } } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - mac_MainConfig->drx_Config = NULL; + LOG_D(RRC, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); - mac_MainConfig->drx_Config = NULL; } } else { // No CDRX with the CU/DU split in this version LOG_E(RRC, "CU/DU split activated\n"); - mac_MainConfig->drx_Config = NULL; } + if (mac_MainConfig->drx_Config != NULL) { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -6691,16 +6693,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif - ); - } + ); + } } else { // remove LCHAN from MAC/PHY if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB @@ -6709,11 +6711,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_req(ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - DRB2LCHAN[i], - Rlc_info_um); + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + DRB2LCHAN[i], + Rlc_info_um); } } @@ -6765,13 +6767,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); } From ac1347843f93011e0b3763fd7fd3e18d744e94d2 Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sat, 14 Sep 2019 12:55:32 +0200 Subject: [PATCH 009/134] COMMON types updated: VCD,FAPI ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: javier.morgade@ieee.org --- common/ngran_types.h | 4 +- common/utils/LOG/log.c | 4 + common/utils/LOG/log.h | 4 + common/utils/LOG/vcd_signal_dumper.c | 2 + common/utils/LOG/vcd_signal_dumper.h | 2 + common/utils/T/T_defs.h | 2 +- common/utils/T/T_messages.txt | 94 +++++++++++++++ common/utils/ocp_itti/all_msg.h | 2 + common/utils/ocp_itti/intertask_interface.h | 10 ++ nfapi/open-nFAPI/nfapi/inc/nfapi.h | 4 + .../nfapi/public_inc/nfapi_interface.h | 23 ++++ nfapi/open-nFAPI/nfapi/src/nfapi.c | 109 ++++++++++++++++++ nfapi/open-nFAPI/nfapi/src/nfapi_p5.c | 26 ++++- 13 files changed, 283 insertions(+), 3 deletions(-) diff --git a/common/ngran_types.h b/common/ngran_types.h index 224a85def5..3dfa7aa01a 100644 --- a/common/ngran_types.h +++ b/common/ngran_types.h @@ -41,11 +41,13 @@ typedef enum { ngran_ng_eNB_CU = 4, ngran_gNB_CU = 5, ngran_eNB_DU = 6, - ngran_gNB_DU = 7 + ngran_gNB_DU = 7, + ngran_eNB_MBMS_STA = 8 } ngran_node_t; #define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB || (nOdE_TyPe) == ngran_ng_eNB || (nOdE_TyPe) == ngran_gNB) #define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU) #define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU) +#define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA) #endif diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 857a83deab..82de71538e 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -404,6 +404,8 @@ int logInit (void) { register_log_component("eRAL","",RAL_ENB); register_log_component("mRAL","",RAL_UE); register_log_component("ENB_APP","log",ENB_APP); + register_log_component("MCE_APP","log",MCE_APP); + register_log_component("MME_APP","log",MME_APP); register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT); register_log_component("PROTO_AGENT","log",PROTO_AGENT); register_log_component("TMR","",TMR); @@ -418,6 +420,8 @@ int logInit (void) { register_log_component("S1AP","",S1AP); register_log_component("F1AP","",F1AP); register_log_component("X2AP","",X2AP); + register_log_component("M2AP","",M2AP); + register_log_component("M3AP","",M3AP); register_log_component("SCTP","",SCTP); register_log_component("X2AP","",X2AP); register_log_component("LOADER","log",LOADER); diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index be7db5470e..2dc2474642 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -213,6 +213,8 @@ typedef enum { RAL_ENB, RAL_UE, ENB_APP, + MCE_APP, + MME_APP, FLEXRAN_AGENT, TMR, USIM, @@ -220,6 +222,8 @@ typedef enum { PROTO_AGENT, F1U, X2AP, + M2AP, + M3AP, LOADER, ASN, NFAPI_VNF, diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index cc0296cb44..55d6c71d71 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -452,6 +452,8 @@ const char* eurecomFunctionsNames[] = { "pdcp_fifo_read_buffer", "pdcp_fifo_flush", "pdcp_fifo_flush_buffer", + "pdcp_mbms_fifo_read", + "pdcp_mbms_fifo_read_buffer", /* RRC signals */ "rrc_rx_tx", "rrc_mac_config_req", diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 45525f8543..f8d3cd8387 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -428,6 +428,8 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, /* RRC signals */ VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 3e4939ade0..8e93ffd71c 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -41,7 +41,7 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (228) +#define VCD_NUM_FUNCTIONS (230) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ #define VCD_NUM_VARIABLES (177) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 348d4837b7..d73788934b 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -359,6 +359,48 @@ ID = LEGACY_X2AP_TRACE GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_M2AP_INFO + DESC = M2AP legacy logs - info level + GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_M2AP_ERROR + DESC = M2AP legacy logs - error level + GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_M2AP_WARNING + DESC = M2AP legacy logs - warning level + GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_M2AP_DEBUG + DESC = M2AP legacy logs - debug level + GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_M2AP_TRACE + DESC = M2AP legacy logs - trace level + GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + +ID = LEGACY_M3AP_INFO + DESC = M3AP legacy logs - info level + GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_M3AP_ERROR + DESC = M3AP legacy logs - error level + GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_M3AP_WARNING + DESC = M3AP legacy logs - warning level + GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_M3AP_DEBUG + DESC = M3AP legacy logs - debug level + GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_M3AP_TRACE + DESC = M3AP legacy logs - trace level + GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_RRC_INFO DESC = RRC legacy logs - info level GROUP = ALL:LEGACY_RRC:LEGACY_GROUP_INFO:LEGACY @@ -443,6 +485,48 @@ ID = LEGACY_ENB_APP_TRACE GROUP = ALL:LEGACY_ENB_APP:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_MCE_APP_INFO + DESC = MCE_APP legacy logs - info level + GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_MCE_APP_ERROR + DESC = MCE_APP legacy logs - error level + GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_MCE_APP_WARNING + DESC = MCE_APP legacy logs - warning level + GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_MCE_APP_DEBUG + DESC = MCE_APP legacy logs - debug level + GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_MCE_APP_TRACE + DESC = MCE_APP legacy logs - trace level + GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + +ID = LEGACY_MME_APP_INFO + DESC = MME_APP legacy logs - info level + GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_MME_APP_ERROR + DESC = MME_APP legacy logs - error level + GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_MME_APP_WARNING + DESC = MME_APP legacy logs - warning level + GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_MME_APP_DEBUG + DESC = MME_APP legacy logs - debug level + GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_MME_APP_TRACE + DESC = MME_APP legacy logs - trace level + GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_FLEXRAN_AGENT_INFO DESC = FLEXRAN_AGENT legacy logs - info level GROUP = ALL:LEGACY_FLEXRAN_AGENT:LEGACY_GROUP_INFO:LEGACY @@ -2893,6 +2977,16 @@ ID = VCD_FUNCTION_PDCP_FIFO_FLUSH_BUFFER GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = pdcp_fifo_flush_buffer +ID = VCD_FUNCTION_PDCP_MBMS_FIFO_READ + DESC = VCD function PDCP_MBMS_FIFO_READ + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = pdcp_mbms_fifo_read +ID = VCD_FUNCTION_PDCP_MBMS_FIFO_READ_BUFFER + DESC = VCD function PDCP_MBMS_FIFO_READ_BUFFER + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = pdcp_mbms_fifo_read_buffer ID = VCD_FUNCTION_RRC_RX_TX DESC = VCD function RRC_RX_TX GROUP = ALL:VCD:ENB:VCD_FUNCTION diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index bbbe576e1b..a2add514e1 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -9,6 +9,8 @@ #endif #include "openair2/COMMON/s1ap_messages_def.h" #include "openair2/COMMON/x2ap_messages_def.h" +#include "openair2/COMMON/m2ap_messages_def.h" +#include "openair2/COMMON/m3ap_messages_def.h" #include "openair2/COMMON/sctp_messages_def.h" #include "openair2/COMMON/udp_messages_def.h" #include "openair2/COMMON/gtpv1_u_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 956d90072d..8a313dba81 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -206,6 +206,8 @@ typedef struct IttiMsgText_s { #endif #include #include +#include +#include #include #include #include @@ -231,6 +233,7 @@ typedef struct IttiMsgText_s { #include #include #include +#include //#include #include @@ -289,8 +292,15 @@ typedef struct { TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_M3AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_M3AP_MME, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_M3AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MCE_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MME_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_FLEXRAN_AGENT,TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PHY_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MAC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ diff --git a/nfapi/open-nFAPI/nfapi/inc/nfapi.h b/nfapi/open-nFAPI/nfapi/inc/nfapi.h index 29a0e50438..0f09efa78a 100644 --- a/nfapi/open-nFAPI/nfapi/inc/nfapi.h +++ b/nfapi/open-nFAPI/nfapi/inc/nfapi.h @@ -44,10 +44,14 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end); uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end); uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end); uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end); +uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end); +uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end); uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); +uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); +uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); typedef uint8_t (*pack_array_elem_fn)(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end); uint8_t packarray(void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t **ppWritePackedMsg, uint8_t *end, pack_array_elem_fn fn); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index a1a0b6e724..0b27fe6f4f 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -704,6 +704,23 @@ typedef struct { #define NFAPI_PUCCH_CONFIG_N_AN_CS_TAG 0x003E #define NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG 0x003F +typedef struct{ + nfapi_uint8_tlv_t mbsfn_area_idx; + nfapi_uint16_tlv_t mbsfn_area_id_r9; +} nfapi_embms_sib13_config_t; +#define NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG 0x0039 +#define NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG 0x0040 + +typedef struct { + nfapi_tl_t tl; + uint16_t num_mbsfn_config; + uint16_t radioframe_allocation_period[8]; + uint16_t radioframe_allocation_offset[8]; + uint8_t fourframes_flag[8]; + int32_t mbsfn_subframeconfig[8]; +} nfapi_embms_mbsfn_config_t; +#define NFAPI_EMBMS_MBSFN_CONFIG_TAG 0x0041 + typedef struct { nfapi_uint8_tlv_t radioframe_allocation_period; nfapi_uint8_tlv_t radioframe_allocation_offset; @@ -1111,6 +1128,9 @@ typedef struct { nfapi_prach_config_t prach_config; nfapi_pusch_config_t pusch_config; nfapi_pucch_config_t pucch_config; + // addition nfpai tlvs for embms MBSFN config //TOBE REVIEWED + nfapi_embms_sib13_config_t embms_sib13_config; + nfapi_embms_mbsfn_config_t embms_mbsfn_config; nfapi_fembms_config_t fembms_config; nfapi_srs_config_t srs_config; nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; @@ -1133,6 +1153,9 @@ typedef struct { nfapi_prach_config_t prach_config; nfapi_pusch_config_t pusch_config; nfapi_pucch_config_t pucch_config; + // addition nfpai tlvs for embms MBSFN config //TOBE REVIEWED + nfapi_embms_sib13_config_t embms_sib13_config; + nfapi_embms_mbsfn_config_t embms_mbsfn_config; nfapi_fembms_config_t fembms_config; nfapi_srs_config_t srs_config; nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c index 3f017bc9a4..156a48ec05 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c @@ -405,7 +405,116 @@ uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **ou return 0; } } +uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) +{ + if(len == 0) + return 1; + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint32_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + if(!pull32(in, &out[idx], end)) + return 0; + } + + return sizeof(uint32_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint32_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + if(!pulls32(in, &out[idx], end)) + return 0; + } + + return sizeof(uint32_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint32_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + if(!push32(in[idx], out, end)) + return 0; + } + return sizeof(uint32_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint32_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + pushs32(in[idx], out, end); + } + return sizeof(uint32_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { if(len == 0) diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c index 54e27123d9..a8ac0f0a65 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -404,7 +404,26 @@ static uint8_t unpack_nmm_frequency_bands_value(void* tlv, uint8_t **ppReadPacke return ( pull16(ppReadPackedMsg, &value->number_of_rf_bands, end) && pullarray16(ppReadPackedMsg, value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, end)); } - +static uint8_t pack_embms_mbsfn_config_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv; + + return ( push16(value->num_mbsfn_config, ppWritePackedMsg, end) && + pusharray16(value->radioframe_allocation_period, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) && + pusharray16(value->radioframe_allocation_offset, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) && + pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) && + pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end)); +} +//static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end) +//{ +// nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv; +// +// return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) && +// pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) && +// pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) && +// pull8(ppReadPackedMsg, &value->fourframes_flag, end) && +// pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end)); +//} static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg; @@ -461,6 +480,11 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) && From 1f50bea34a417dd5742923b453961f108a5f7a31 Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sat, 14 Sep 2019 13:00:06 +0200 Subject: [PATCH 010/134] PMCH L1 Procedures updated ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: javier.morgade@ieee.org --- openair1/PHY/INIT/lte_init.c | 49 ++++++++++++++ openair1/PHY/INIT/lte_init_ue.c | 67 +++++++++++++++++-- openair1/PHY/INIT/phy_init.h | 15 +++++ openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 12 ++-- openair1/PHY/LTE_TRANSPORT/pmch.c | 2 + openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c | 17 ++--- openair1/PHY/defs_UE.h | 2 +- openair1/PHY/defs_eNB.h | 11 ++- 8 files changed, 153 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 61a58c1b19..b483c2cbe0 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -75,6 +75,9 @@ l1_north_init_eNB () RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request; RC.eNB[i][j]->if_inst->schedule_response = schedule_response; + RC.eNB[i][j]->if_inst->PHY_config_update_sib2_req = phy_config_update_sib2_request; + RC.eNB[i][j]->if_inst->PHY_config_update_sib13_req = phy_config_update_sib13_request; + } } } @@ -325,7 +328,53 @@ void phy_config_request(PHY_Config_t *phy_config) { LOG_I (PHY, "eNB %d/%d configured\n", Mod_id, CC_id); } +void phy_config_update_sib2_request(PHY_Config_t *phy_config) { + uint8_t Mod_id = phy_config->Mod_id; + int CC_id = phy_config->CC_id; + int i; + nfapi_config_request_t *cfg = phy_config->cfg; + LOG_I(PHY,"Configure sib2 Mod_id(%d), CC_id(%d) cfg %p\n",Mod_id,CC_id,cfg); + + LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; + + fp->num_MBSFN_config = cfg->embms_mbsfn_config.num_mbsfn_config; + for( i=0; i < cfg->embms_mbsfn_config.num_mbsfn_config; i++){ + fp->MBSFN_config[i].radioframeAllocationPeriod = cfg->embms_mbsfn_config.radioframe_allocation_period[i]; + fp->MBSFN_config[i].radioframeAllocationOffset = cfg->embms_mbsfn_config.radioframe_allocation_offset[i]; + fp->MBSFN_config[i].fourFrames_flag = cfg->embms_mbsfn_config.fourframes_flag[i]; + fp->MBSFN_config[i].mbsfn_SubframeConfig = cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]; // 6-bit subframe configuration + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } + + + +} +void phy_config_update_sib13_request(PHY_Config_t *phy_config) { + + uint8_t Mod_id = phy_config->Mod_id; + int CC_id = phy_config->CC_id; + nfapi_config_request_t *cfg = phy_config->cfg; + + LOG_E(PHY,"configure sib3 Mod_id(%d), CC_id(%d) cfg %p\n",Mod_id,CC_id,cfg); + LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; + LOG_I (PHY, "[eNB%d] Applying MBSFN_Area_id %d for index %d\n", Mod_id, (uint16_t)cfg->embms_sib13_config.mbsfn_area_id_r9.value, (uint8_t)cfg->embms_sib13_config.mbsfn_area_idx.value); + + //cfg->embms_sib13_config.mbsfn_area_idx; + //cfg->embms_sib13_config.mbsfn_area_id_r9; + + AssertFatal((uint8_t)cfg->embms_sib13_config.mbsfn_area_idx.value == 0, "Fix me: only called when mbsfn_Area_idx == 0\n"); + if (cfg->embms_sib13_config.mbsfn_area_idx.value == 0) { + fp->Nid_cell_mbsfn = (uint16_t)cfg->embms_sib13_config.mbsfn_area_id_r9.value; + LOG_I(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n"); + } + lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); +#endif +} void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx, long mbsfn_AreaId_r9) diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index f7ab91c86e..04b615e90f 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -154,6 +154,42 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_OUT); } +void phy_config_mbsfn_list_ue(module_id_t Mod_id, + int CC_id, + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList){ + // MBSFN + + PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + LTE_DL_FRAME_PARMS *fp = &ue->frame_parms; + int i; + + if (mbsfn_SubframeConfigList != NULL) { + + fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; + + for (i=0; ilist.count; i++) { + fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; + fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; + + if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + fp->MBSFN_config[i].fourFrames_flag = 0; + fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + fp->MBSFN_config[i].fourFrames_flag = 1; + fp->MBSFN_config[i].mbsfn_SubframeConfig = + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %x\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } + } + } +} + + void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx, long mbsfn_AreaId_r9) { LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; @@ -592,7 +628,8 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, LTE_UE_PDSCH **const pdsch_vars_SI = ue->pdsch_vars_SI; LTE_UE_PDSCH **const pdsch_vars_ra = ue->pdsch_vars_ra; LTE_UE_PDSCH **const pdsch_vars_p = ue->pdsch_vars_p; - LTE_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH; + //LTE_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH; + LTE_UE_PDSCH* (*pdsch_vars_MCH_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdsch_vars_MCH; LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars; LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdcch_vars; LTE_UE_PBCH **const pbch_vars = ue->pbch_vars; @@ -673,6 +710,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, for (eNB_id=0; eNB_idn_connected_eNB; eNB_id++) { for (th_id=0; th_idllr[1] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) ); (*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + + (*pdsch_vars_MCH_th)[th_id][eNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts; + (*pdsch_vars_MCH_th)[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + } for (int i=0; inb_antennas_rx; i++) { for (th_id=0; th_idrho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); } } for (th_id=0; th_iddl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); } for (i=0; inb_antennas_rx; i++) @@ -715,6 +763,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, for (th_id=0; th_iddl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); } } @@ -726,6 +775,11 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + + (*pdsch_vars_MCH_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); } for (int i=0; inb_antennas_rx; i++) @@ -737,6 +791,11 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); } } } @@ -745,7 +804,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); - phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); + //phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE for (th_id=0; th_id ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - ((int16_t*)&txdataF[4][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i + ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i *jj = *jj + 1; - ((int16_t*)&txdataF[4][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} + ((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} *jj = *jj + 1; @@ -1989,8 +1989,8 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, *jj=*jj+1; - ((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); break; @@ -2029,8 +2029,8 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, *jj=*jj+1; - ((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); break; default: diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index 6fab3dc59b..7d1c6a7525 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -96,6 +96,8 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a) get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1, 2,proc->frame_tx,subframe,0); + eNB->dlsch_MCH->harq_processes[0]->Qm = get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs); + generate_mbsfn_pilot(eNB,proc, eNB->common_vars.txdataF, AMP); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c index 362c1bf773..973891d034 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c @@ -59,10 +59,10 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in #define NSYMB_PMCH 12 sprintf(fname,"mch_rxF_ext0.m"); sprintf(vname,"pmch_rxF_ext0"); - LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_ext[0],12*(ue->frame_parms.N_RB_DL)*12,1,1); + LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],12*(ue->frame_parms.N_RB_DL)*12,1,1); sprintf(fname,"mch_ch_ext00.m"); sprintf(vname,"pmch_ch_ext00"); - LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_estimates_ext[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); + LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); /* LOG_M("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*NSYMB_PMCH,1,1); LOG_M("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*NSYMB_PMCH,1,1); @@ -71,16 +71,16 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in */ sprintf(fname,"mch_rxF_comp0.m"); sprintf(vname,"pmch_rxF_comp0"); - LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_comp0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); + LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); sprintf(fname,"mch_rxF_llr.m"); sprintf(vname,"pmch_llr"); - LOG_M(fname,vname, ue->pdsch_vars_MCH[eNB_id]->llr[0],coded_bits_per_codeword,1,0); + LOG_M(fname,vname, ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->llr[0],coded_bits_per_codeword,1,0); sprintf(fname,"mch_mag1.m"); sprintf(vname,"pmch_mag1"); - LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_mag0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); + LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); sprintf(fname,"mch_mag2.m"); sprintf(vname,"pmch_mag2"); - LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_magb0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); + LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1); LOG_M("mch00_ch0.m","pmch00_ch0", &(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), @@ -104,6 +104,7 @@ void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) LTE_UE_DLSCH_t *dlsch = ue->dlsch_MCH[eNB_id]; LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; + dlsch->Mdlharq = 1; // dlsch->rnti = M_RNTI; dlsch->harq_processes[0]->mcs = mcs; dlsch->harq_processes[0]->rvidx = rvidx; @@ -1362,7 +1363,7 @@ int rx_pmch(PHY_VARS_UE *ue, { LTE_UE_COMMON *common_vars = &ue->common_vars; - LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id]; + LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id]; int avgs,aarx; @@ -1453,7 +1454,7 @@ int rx_pmch_khz_1dot25(PHY_VARS_UE *ue, //unsigned int symbol; LTE_UE_COMMON *common_vars = &ue->common_vars; - LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id]; + LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; //LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id]; int avgs,aarx; diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 294afb7bb0..8614e12bde 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -673,7 +673,7 @@ typedef struct { LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1]; - LTE_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_PDSCH *pdsch_vars_MCH[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 6036928a90..f4152a70f5 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -494,7 +494,9 @@ typedef enum { RRU_sync_ok=6, RRU_frame_resynch=7, RRU_MSG_max_num=8, - RRU_check_sync = 9 + RRU_check_sync = 9, + RRU_config_update=10, + RRU_config_update_ok=11 } rru_config_msg_type_t; typedef struct RRU_CONFIG_msg_s { @@ -588,10 +590,13 @@ typedef struct RRU_config_s { /// Timing statistics (RU_arrivals) time_stats_t ru_arrival_time; /// mask for RUs serving eNB (PRACH) - int RU_mask_prach; + int RU_mask_prach; + /// embms mbsfn sf config + int num_MBSFN_config; + /// embms mbsfn sf config + MBSFN_config_t MBSFN_config[8]; } RRU_config_t; - typedef struct { /// \brief Pointers (dynamic) to the received data in the time domain. /// - first index: rx antenna [0..nb_antennas_rx[ From 65133d4e1811f73dba3428fa69d8132bdbb5a79c Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sat, 14 Sep 2019 13:02:56 +0200 Subject: [PATCH 011/134] Implemented eMBMS FFT procedures (scheduling) ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: javier.morgade@ieee.org --- openair1/SCHED/phy_procedures_lte_eNb.c | 4 +- openair1/SCHED/ru_procedures.c | 83 +++++++++++++++-------- openair1/SCHED_UE/phy_procedures_lte_ue.c | 4 +- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 6cc9c84496..d524c9270c 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -123,7 +123,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { // uint8_t sync_area=255; #endif int subframe = proc->subframe_tx; - AssertFatal (1 == 0, "pmch not tested for the moment, exiting\n"); + AssertFatal (1 == 1, "pmch not tested for the moment, exiting\n"); // This is DL-Cell spec pilots in Control region generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -136,6 +136,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { proc->frame_tx, subframe); */ + mch_pduP= &RC.mac[eNB->Mod_id]->common_channels[eNB->CC_id].MCH_pdu; if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n", eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs, @@ -149,6 +150,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { if (mch_pduP) { fill_eNB_dlsch_MCH (eNB, mch_pduP->mcs, 1, 0); + eNB->dlsch_MCH->harq_ids[proc->frame_tx%2][subframe] = 0; // Generate PMCH generate_mch (eNB, proc, (uint8_t *) mch_pduP->payload); } else { diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 1f1a36b238..565f1acece 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -94,35 +94,49 @@ void feptx0(RU_t *ru,int slot) { fp->nb_prefix_samples, CYCLIC_PREFIX); else { - /* AssertFatal(ru->generate_dmrs_sync==1 && (fp->frame_type != TDD || ru->is_slave == 1), - "ru->generate_dmrs_sync should not be set, frame_type %d, is_slave %d\n", - fp->frame_type,ru->is_slave); -*/ - int num_symb = 7; + if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){ + if(slot==0){//just use one slot chance + normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], + (int*)&ru->common.txdata[aa][slot_offset], + 2, + fp); + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF+fp->ofdm_symbol_size*2], + (int*)&ru->common.txdata[aa][slot_offset+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2)], + fp->ofdm_symbol_size, + 10, + fp->ofdm_symbol_size>>2, + CYCLIC_PREFIX); + LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d F(%d) t(%d) IS PMCH(%d)\n",ru->proc.frame_tx, ru->proc.subframe_tx,slot,slot*slot_sizeF+fp->ofdm_symbol_size*2,slot_offset+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2),is_pmch_subframe(ru->proc.frame_tx,subframe,fp)); + } + }else{ + /* AssertFatal(ru->generate_dmrs_sync==1 && (fp->frame_type != TDD || ru->is_slave == 1), + "ru->generate_dmrs_sync should not be set, frame_type %d, is_slave %d\n", + fp->frame_type,ru->is_slave); + */ + int num_symb = 7; - if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe+1; - - if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) { - //int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32))); - //int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL}; - - generate_drs_pusch((PHY_VARS_UE *)NULL, - (UE_rxtx_proc_t*)NULL, - fp, - ru->common.txdataF_BF, - 0, - AMP, - 0, - 0, - fp->N_RB_DL, - aa); - } - normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], - (int*)&ru->common.txdata[aa][slot_offset], - num_symb, - fp); - - + if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe+1; + + if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) { + //int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32))); + //int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL}; + + generate_drs_pusch((PHY_VARS_UE *)NULL, + (UE_rxtx_proc_t*)NULL, + fp, + ru->common.txdataF_BF, + 0, + AMP, + 0, + 0, + fp->N_RB_DL, + aa); + } + normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], + (int*)&ru->common.txdata[aa][slot_offset], + num_symb, + fp); + } } /* len = fp->samples_per_tti>>1; @@ -311,6 +325,18 @@ void feptx_ofdm(RU_t *ru) { fp->nb_prefix_samples, CYCLIC_PREFIX); } else { + if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)/*subframe==1*/){ + normal_prefix_mod(&ru->common.txdataF_BF[aa][0], + dummy_tx_b, + 2, + fp); + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][fp->ofdm_symbol_size*2], + dummy_tx_b+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2), + fp->ofdm_symbol_size, + 10, + fp->ofdm_symbol_size>>2, + CYCLIC_PREFIX); + }else{ normal_prefix_mod(&ru->common.txdataF_BF[aa][slot_offset_F], dummy_tx_b, 7, @@ -321,6 +347,7 @@ void feptx_ofdm(RU_t *ru) { dummy_tx_b+(fp->samples_per_tti>>1), 7, fp); + } } // if S-subframe generate first slot only diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 5da97b3a1a..5e7f723c97 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2896,7 +2896,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_D dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0], ue->dlsch_MCH[0]->harq_processes[0]->G, - ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1); + ue->pdsch_vars_MCH[ue->current_thread_id[subframe_rx]][0]->llr[0],0,subframe_rx<<1); LOG_D(PHY,"start turbo decode for MCH %d.%d --> nb_rb %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb); LOG_D(PHY,"start turbo decode for MCH %d.%d --> rb_alloc_even %x \n", frame_rx, subframe_rx, (unsigned int)((intptr_t)ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even)); LOG_D(PHY,"start turbo decode for MCH %d.%d --> Qm %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Qm); @@ -2904,7 +2904,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_D LOG_D(PHY,"start turbo decode for MCH %d.%d --> G %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G); LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo); ret = dlsch_decoding(ue, - ue->pdsch_vars_MCH[0]->llr[0], + ue->pdsch_vars_MCH[ue->current_thread_id[subframe_rx]][0]->llr[0], &ue->frame_parms, ue->dlsch_MCH[0], ue->dlsch_MCH[0]->harq_processes[0], From 400c5458d4fb6eb913797f3f0d5c5c39694a4720 Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sat, 14 Sep 2019 13:05:38 +0200 Subject: [PATCH 012/134] Dedicated TUN interfaces for eMBMS oaitun_enm1 (eNB) <-> oaitun_uem1 (UE) ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: javier.morgade@ieee.org --- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 60 +++++++++++++++++++ openair1/SIMULATION/ETH_TRANSPORT/proto.h | 1 + 2 files changed, 61 insertions(+) diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index 396c76f8e6..ba32985ce0 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -58,6 +58,8 @@ struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)}; int nas_sock_fd[MAX_MOBILES_PER_ENB]; +int nas_sock_mbms_fd[8]; + struct msghdr nas_msg_tx; struct msghdr nas_msg_rx; @@ -92,6 +94,64 @@ static int tun_alloc(char *dev) { return fd; } + +int netlink_init_mbms_tun(char *ifprefix, int num_if) { + int ret; + char ifname[64]; + + int i= num_if-1; + sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1); + nas_sock_mbms_fd[i] = tun_alloc(ifname); + + if (nas_sock_mbms_fd[i] == -1) { + printf("[NETLINK] Error opening socket %s (%d:%s)\n",ifname,errno, strerror(errno)); + exit(1); + } + + printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd[i]); + ret = fcntl(nas_sock_mbms_fd[i],F_SETFL,O_NONBLOCK); + + if (ret == -1) { + printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); + + if (LINK_ENB_PDCP_TO_IP_DRIVER) { + exit(1); + } + } + + memset(&nas_src_addr, 0, sizeof(nas_src_addr)); + nas_src_addr.nl_family = AF_NETLINK; + nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ + nas_src_addr.nl_groups = 0; /* not in mcast groups */ + ret = bind(nas_sock_mbms_fd[i], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr)); + memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); + nas_dest_addr.nl_family = AF_NETLINK; + nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ + nas_dest_addr.nl_groups = 0; /* unicast */ + // TX PART + nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD)); + memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD)); + /* Fill the netlink message header */ + nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD); + nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */ + nas_nlh_tx->nlmsg_flags = 0; + nas_iov_tx.iov_base = (void *)nas_nlh_tx; + nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len; + memset(&nas_msg_tx,0,sizeof(nas_msg_tx)); + nas_msg_tx.msg_name = (void *)&nas_dest_addr; + nas_msg_tx.msg_namelen = sizeof(nas_dest_addr); + nas_msg_tx.msg_iov = &nas_iov_tx; + nas_msg_tx.msg_iovlen = 1; + // RX PART + memset(&nas_msg_rx,0,sizeof(nas_msg_rx)); + nas_msg_rx.msg_name = (void *)&nas_src_addr; + nas_msg_rx.msg_namelen = sizeof(nas_src_addr); + nas_msg_rx.msg_iov = &nas_iov_rx; + nas_msg_rx.msg_iovlen = 1; + + return 1; +} + int netlink_init_tun(char *ifprefix, int num_if) { int ret; char ifname[64]; diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index ff677d1580..02f7925d93 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -63,5 +63,6 @@ void clear_eNB_transport_info(uint8_t); void clear_UE_transport_info(uint8_t); int netlink_init(void); int netlink_init_tun(char *ifsuffix, int num_if); +int netlink_init_mbms_tun(char *ifsuffix, int num_if); #endif /* EMU_PROTO_H_ */ From f76cc8244874c663a0421583ec3f8e339e9df4b0 Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sat, 14 Sep 2019 13:13:00 +0200 Subject: [PATCH 013/134] New common definitons for M2,M3 interfaces -3GPP TS version 36.443 and 36.444 ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: javier.morgade@ieee.org --- openair2/COMMON/m2ap_messages_def.h | 1 + openair2/COMMON/m2ap_messages_types.h | 1 + openair2/COMMON/messages_def.h | 2 ++ openair2/COMMON/platform_constants.h | 3 ++- openair2/COMMON/rrc_messages_types.h | 1 + openair2/COMMON/tasks_def.h | 9 +++++++++ 6 files changed, 16 insertions(+), 1 deletion(-) diff --git a/openair2/COMMON/m2ap_messages_def.h b/openair2/COMMON/m2ap_messages_def.h index f4273573cd..adad70c9cc 100644 --- a/openair2/COMMON/m2ap_messages_def.h +++ b/openair2/COMMON/m2ap_messages_def.h @@ -19,6 +19,7 @@ * contact@openairinterface.org */ + /* eNB application layer -> M2AP messages */ /* ITTI LOG messages */ /* ENCODER */ diff --git a/openair2/COMMON/m2ap_messages_types.h b/openair2/COMMON/m2ap_messages_types.h index f2ee1de43e..501414f296 100644 --- a/openair2/COMMON/m2ap_messages_types.h +++ b/openair2/COMMON/m2ap_messages_types.h @@ -19,6 +19,7 @@ * contact@openairinterface.org */ + #ifndef M2AP_MESSAGES_TYPES_H_ #define M2AP_MESSAGES_TYPES_H_ diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h index b0219db50a..0d302cfea0 100644 --- a/openair2/COMMON/messages_def.h +++ b/openair2/COMMON/messages_def.h @@ -36,6 +36,8 @@ #include "s1ap_messages_def.h" #include "f1ap_messages_def.h" #include "x2ap_messages_def.h" +#include "m2ap_messages_def.h" +#include "m3ap_messages_def.h" #include "sctp_messages_def.h" #include "udp_messages_def.h" #include "gtpv1_u_messages_def.h" diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 2b28b760a8..f978258f88 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -109,7 +109,8 @@ #define NB_RAB_MAX LTE_maxDRB /* was 8, now 11 */ #define RAB_SHIFT1 9 #define RAB_SHIFT2 3 -#define RAB_OFFSET 0x0007 +//#define RAB_OFFSET 0x0007 +#define RAB_OFFSET 0x000F #define RAB_OFFSET1 0x7E00 #define RAB_OFFSET2 0x01F8 #define DIR_OFFSET 0x8000 diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 4b8f6077fe..cfb684d53d 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -200,6 +200,7 @@ typedef struct RrcConfigurationReq_s { int16_t N_RB_DL[MAX_NUM_CCs];// for testing, change later int nb_antenna_ports[MAX_NUM_CCs]; int eMBMS_configured; + int eMBMS_M2_configured; int eMTC_configured; int SL_configured; diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 2ccb7b1c29..f4656573ed 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -48,6 +48,15 @@ TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000) TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200) +/// M3ap task, acts as both source and target +TASK_DEF(TASK_M3AP, TASK_PRIORITY_MED, 200) +/// M3ap task, acts as both source and target +TASK_DEF(TASK_M3AP_MME, TASK_PRIORITY_MED, 200) +/// M3ap task, acts as both source and target +TASK_DEF(TASK_M3AP_MCE, TASK_PRIORITY_MED, 200) +/// M2ap task, acts as both source and target +TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200) +TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200) /// X2ap task, acts as both source and target TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200) /// Sctp task (Used by both S1AP and X2AP) From bcf42ca2a55031bca346f2343bdb5853abb75616 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:19:00 +0200 Subject: [PATCH 014/134] Implemented M2AP managing procedures at eNB (ENB_APP) -M2 register against MCE (Multicast Control Entity) -Basic M2AP control procedures developed (eNB<-M2AP->MCE) ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/ENB_APP/enb_app.c | 224 +++++++++++++++++++ openair2/ENB_APP/enb_config.c | 268 +++++++++++++++++++++++ openair2/ENB_APP/enb_config.h | 1 + openair2/ENB_APP/enb_paramdef.h | 86 ++++++++ openair2/ENB_APP/enb_paramdef_mce.h | 239 ++++++++++++++++++++ openair2/ENB_APP/enb_paramdef_mme.h | 82 +++++++ openair2/ENB_APP/flexran_agent_ran_api.c | 4 + 7 files changed, 904 insertions(+) create mode 100644 openair2/ENB_APP/enb_paramdef_mce.h create mode 100644 openair2/ENB_APP/enb_paramdef_mme.h diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 0580f0eb52..ba4c4a4513 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -46,6 +46,8 @@ # include "x2ap_eNB.h" # include "x2ap_messages_types.h" +# include "m2ap_eNB.h" +# include "m2ap_messages_types.h" # define X2AP_ENB_REGISTER_RETRY_DELAY 10 #include "openair1/PHY/INIT/phy_init.h" @@ -58,7 +60,87 @@ extern RAN_CONTEXT_t RC; #include "targets/RT/USER/lte-softmodem.h" +/*************************** ENB M2AP **************************/ +//static uint32_t eNB_app_register_MBMS_STA(ngran_node_t node_type,uint32_t enb_id_start, uint32_t enb_id_end) { +// uint32_t enb_id; +// //MessageDef *msg_p; +// uint32_t register_enb_pending = 0; +// +// for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { +// { +// +// //msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); +// //RCconfig_S1(msg_p, enb_id); +// +// if (enb_id == 0) RCconfig_gtpu(); +// +// //LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx)); +// +// //LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); +// //itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); +// +// register_enb_pending++; +// } +// } +// +// return register_enb_pending; +//} +//*****end M2AP ****/ +static uint32_t eNB_app_register_m2(uint32_t enb_id_start, uint32_t enb_id_end) { + uint32_t enb_id; + MessageDef *msg_p; + uint32_t register_enb_m2_pending = 0; + +// msg_p = itti_alloc_new_message (TASK_ENB_APP,MESSAGE_TEST ); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + + LOG_D(ENB_APP,"Register ...\n"); + + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + { + msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_REGISTER_ENB_REQ); + RCconfig_M2(msg_p, enb_id); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + register_enb_m2_pending++; + } + } + + return register_enb_m2_pending; +} + + +/*************************** M2AP ENB handle **********************************/ +static uint32_t eNB_app_handle_m2ap_mbms_scheduling_information(instance_t instance){ + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + return 0; +} +static uint32_t eNB_app_handle_m2ap_mbms_session_start_req(instance_t instance){ + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_START_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + return 0; +} +static uint32_t eNB_app_handle_m2ap_mbms_session_stop_req(instance_t instance){ + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_STOP_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + return 0; +} +static uint32_t eNB_app_handle_m2ap_mbms_session_update_req(instance_t instance){ + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_UPDATE_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + return 0; +} + +//// end M2AP ENB handle **********************************/ /*------------------------------------------------------------------------------*/ @@ -129,6 +211,9 @@ void *eNB_app_task(void *args_p) { uint32_t x2_register_enb_pending = 0; uint32_t x2_registered_enb = 0; long x2_enb_register_retry_timer_id; + uint32_t m2_register_enb_pending = 0; + uint32_t m2_registered_enb = 0; + long m2_enb_register_retry_timer_id; MessageDef *msg_p = NULL; instance_t instance; int result; @@ -147,6 +232,22 @@ void *eNB_app_task(void *args_p) { x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); } + /* Try to register each eNB with MCE each other */ + if (is_m2ap_eNB_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) { + //eNB_app_register_MBMS_STA(RC.rrc[0]->node_type, enb_id_start, enb_id_end); + //m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end); + + if (timer_setup (5, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &m2_enb_register_retry_timer_id) < 0) { + //LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); + //sleep(ENB_REGISTER_RETRY_DELAY); + /* Restart the registration process */ + //registered_enb = 0; + //register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end); + } + + } + do { // Wait for a message itti_receive_msg (TASK_ENB_APP, &msg_p); @@ -275,6 +376,12 @@ void *eNB_app_task(void *args_p) { } } /* if (EPC_MODE_ENABLED) */ + if(TIMER_HAS_EXPIRED (msg_p).timer_id == m2_enb_register_retry_timer_id) { + + LOG_I(ENB_APP, " Received %s: timer_id %ld M2 register\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); + m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end); + } + break; case X2AP_DEREGISTERED_ENB_IND: @@ -319,6 +426,123 @@ void *eNB_app_task(void *args_p) { break; + case M2AP_DEREGISTERED_ENB_IND: + LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2); + /* TODO handle recovering of registration */ + break; + + case M2AP_REGISTER_ENB_CNF: + LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + M2AP_REGISTER_ENB_CNF(msg_p).nb_m2); + DevAssert(m2_register_enb_pending > 0); + m2_register_enb_pending--; + + /* Check if at least eNB is registered with one target eNB */ + if (M2AP_REGISTER_ENB_CNF(msg_p).nb_m2 > 0) { + m2_registered_enb++; + } + + /* Check if all register eNB requests have been processed */ + if (m2_register_enb_pending == 0) { + if (m2_registered_enb == enb_nb) { + /* If all eNB are registered, start RRC HO task */ + } else { + uint32_t m2_not_associated = enb_nb - m2_registered_enb; + LOG_W(ENB_APP, " %d eNB %s not associated with the target\n", + m2_not_associated, m2_not_associated > 1 ? "are" : "is"); + + // timer to retry + /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ + //if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, + // INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, + // &x2_enb_register_retry_timer_id) < 0) { + // LOG_E(ENB_APP, " Can not start eNB X2AP register: retry timer, use \"sleep\" instead!\n"); + // sleep(X2AP_ENB_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // x2_registered_enb = 0; + // x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); + //} + } + } + break; + + case M2AP_SETUP_RESP: + LOG_I(ENB_APP,"M2AP_SETUP_RESP RESPONSE received\n"); + // AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/eNB\n"); + + // LOG_I(ENB_APP, "Received %s: associated ngran_eNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), + // F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate); + // + // handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p)); + + // DevAssert(register_enb_pending > 0); + // register_enb_pending--; + + // /* Check if at least eNB is registered with one MME */ + // if (F1AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) { + // registered_enb++; + // } + + // /* Check if all register eNB requests have been processed */ + // if (register_enb_pending == 0) { + // if (registered_enb == enb_nb) { + // /* If all eNB cells are registered, start L2L1 task */ + // MessageDef *msg_init_p; + + // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + + // } else { + // LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n", + // enb_nb - registered_enb, ENB_REGISTER_RETRY_DELAY); + + // /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &enb_register_retry_timer_id) < 0) { + // LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); + + // sleep(ENB_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // registered_enb = 0; + // register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);//, enb_properties_p); + // } + // } + // } + break; + + case M2AP_MBMS_SCHEDULING_INFORMATION: + LOG_I(ENB_APP,"M2AP_SCHEDULING_INFORMATION received\n"); + eNB_app_handle_m2ap_mbms_scheduling_information(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + break; + case M2AP_MBMS_SESSION_START_REQ: + LOG_I(ENB_APP,"M2AP_MBMS_SESSION_START_REQ received\n"); + eNB_app_handle_m2ap_mbms_session_start_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + break; + case M2AP_MBMS_SESSION_STOP_REQ: + LOG_I(ENB_APP,"M2AP_MBMS_SESSION_STOP_REQ received\n"); + eNB_app_handle_m2ap_mbms_session_stop_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + break; + case M2AP_RESET: + LOG_I(ENB_APP,"M2AP_RESET received\n"); + break; + case M2AP_ENB_CONFIGURATION_UPDATE_ACK: + LOG_I(ENB_APP,"M2AP_ENB_CONFIGURATION_UPDATE_ACK received\n"); + break; + case M2AP_ENB_CONFIGURATION_UPDATE_FAILURE: + LOG_I(ENB_APP,"M2AP_ENB_CONFIGURATION_UPDATE_FAILURE received\n"); + break; + case M2AP_ERROR_INDICATION: + LOG_I(ENB_APP,"M2AP_MBMS_SESSION_UPDATE_REQ\n"); + eNB_app_handle_m2ap_mbms_session_update_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + break; + case M2AP_MBMS_SERVICE_COUNTING_REQ: + LOG_I(ENB_APP,"M2AP_MBMS_SERVICE_COUNTING_REQ\n"); + break; + case M2AP_MCE_CONFIGURATION_UPDATE: + LOG_I(ENB_APP,"M2AP_MCE_CONFIGURATION_UPDATE\n"); + break; + default: LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); break; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index a957e11bcd..9692c084c1 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -435,6 +435,14 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { else RRC_CONFIGURATION_REQ (msg_p).enable_x2 = 0; + /* m2 enabled */ + if (ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr != NULL && + *(ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr) != NULL && + !strcmp(*(ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr), "yes")) + RRC_CONFIGURATION_REQ (msg_p).eMBMS_M2_configured = 1; + else + RRC_CONFIGURATION_REQ (msg_p).eMBMS_M2_configured = 0; + // Parse optional physical parameters config_getlist( &CCsParamList,NULL,0,enbpath); LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt); @@ -2144,6 +2152,266 @@ int RCconfig_gtpu(void ) { return 0; } +int RCconfig_M2(MessageDef *msg_p, uint32_t i) { + int I, J, j, k, l; + int enb_id; + char *address = NULL; + char *cidr = NULL; + ccparams_lte_t ccparams_lte; + memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t)); + paramdef_t ENBSParams[] = ENBSPARAMS_DESC; + paramdef_t ENBParams[] = ENBPARAMS_DESC; + paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; + /* get global parameters, defined outside any section in the config file */ + config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; + paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte); + paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; + + // ccparams_MCE_t MCEconfig; + // memset((void *)&MCEconfig,0,sizeof(ccparams_MCE_t)); + // paramdef_t MCEParams[] = MCEPARAMS_DESC((&MCEconfig)); + // checkedparam_t config_check_MCEparams[] = MCEPARAMS_CHECK; + + + /* map parameter checking array instances to parameter definition array instances */ + for (I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { + CCsParams[I].chkPptr = &(config_check_CCparams[I]); + } + + AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt, + "Failed to parse config file %s, %uth attribute %s \n", + RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS); + + if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) { + // Output a list of all eNBs. + config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); + + if (ENBParamList.numelt > 0) { + for (k = 0; k < ENBParamList.numelt; k++) { + if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { + // Calculate a default eNB ID + if (EPC_MODE_ENABLED) { + uint32_t hash; + hash = s1ap_generate_eNB_id (); + enb_id = k + (hash & 0xFFFF8); + } else { + enb_id = k; + } + } else { + enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr); + } + + // search if in active list + for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { + if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { + paramdef_t PLMNParams[] = PLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + + paramdef_t M2Params[] = M2PARAMS_DESC; + paramlist_def_t M2ParamList = {ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS,NULL,0}; + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + paramdef_t NETParams[] = NETPARAMS_DESC; + paramdef_t MBMSConfigParams[] = MBMS_CONFIG_PARAMS_DESC; + paramdef_t MBMSParams[] = MBMSPARAMS_DESC; + paramlist_def_t MBMSConfigParamList = {ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST,NULL,0}; + paramlist_def_t MBMSParamList = {ENB_CONFIG_STRING_MBMS_SERVICE_AREA_LIST,NULL,0}; + /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */ + /* this is most probably a problem with the config module */ + char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + /* Some default/random parameters */ + M2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; + + if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB; + } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", + RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); + } + + M2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); + M2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + + + +// char aprefix2[MAX_OPTNAME_SIZE*80 + 8]; +// sprintf(aprefix2,"%s.[%i].%s.[0]",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST); +// config_getlist(&MBMSParamList, MBMSParams, sizeof(MBMSParams)/sizeof(paramdef_t), aprefix2); +// if (MBMSParamList.numelt < 1 || MBMSParamList.numelt > 8) +// AssertFatal(0, "The number of MBMS Areas must be in [1,8], but is %d\n", +// MBMSParamList.numelt); +// M2AP_REGISTER_ENB_REQ (msg_p).num_mbms_service_area_list = MBMSParamList.numelt; +// for(J=0; J 8) + AssertFatal(0, "The number of MBMS Config Data must be in [1,8], but is %d\n", + MBMSConfigParamList.numelt); + M2AP_REGISTER_ENB_REQ (msg_p).num_mbms_configuration_data_list = MBMSConfigParamList.numelt; + for(int I=0; I < MBMSConfigParamList.numelt; I++){ + + sprintf(aprefix2,"%s.[%i].%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST,I); + config_getlist(&MBMSParamList, MBMSParams, sizeof(MBMSParams)/sizeof(paramdef_t), aprefix2); + if (MBMSParamList.numelt < 1 || MBMSParamList.numelt > 8) + AssertFatal(0, "The number of MBMS Areas must be in [1,8], but is %d\n", + MBMSParamList.numelt); + M2AP_REGISTER_ENB_REQ (msg_p).mbms_configuration_data_list[I].num_mbms_service_area_list = MBMSParamList.numelt; + for(J=0; J 6) + AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", + PLMNParamList.numelt); + + if (PLMNParamList.numelt > 1) + LOG_W(M2AP, "M2AP currently handles only one PLMN, ignoring the others!\n"); + + M2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + M2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + M2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(M2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 + || M2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + M2AP_REGISTER_ENB_REQ(msg_p).mnc); + /* CC params */ + config_getlist(&CCsParamList, NULL, 0, aprefix); + M2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; + + if (CCsParamList.numelt > 0) { + //char ccspath[MAX_OPTNAME_SIZE*2 + 16]; + for (J = 0; J < CCsParamList.numelt ; J++) { + sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J); + config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + M2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band; + M2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency; + M2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset; + M2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell; + + if (ccparams_lte.Nid_cell>503) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", + RC.config_file_name, k, ccparams_lte.Nid_cell); + } + + M2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL; + + if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", + RC.config_file_name, k, ccparams_lte.N_RB_DL); + } + + if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; + } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", + RC.config_file_name, k, ccparams_lte.frame_type); + } + + M2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL); + M2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL); + } + } + + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + config_getlist( &M2ParamList,M2Params,sizeof(M2Params)/sizeof(paramdef_t),aprefix); + AssertFatal(M2ParamList.numelt <= M2AP_MAX_NB_ENB_IP_ADDRESS, + "value of M2ParamList.numelt %d must be lower than M2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase M2AP_MAX_NB_ENB_IP_ADDRESS\n", + M2ParamList.numelt,M2AP_MAX_NB_ENB_IP_ADDRESS); + M2AP_REGISTER_ENB_REQ (msg_p).nb_m2 = 0; + + for (l = 0; l < M2ParamList.numelt; l++) { + M2AP_REGISTER_ENB_REQ (msg_p).nb_m2 += 1; + strcpy(M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4_address,*(M2ParamList.paramarray[l][ENB_M2_IPV4_ADDRESS_IDX].strptr)); + strcpy(M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6_address,*(M2ParamList.paramarray[l][ENB_M2_IPV6_ADDRESS_IDX].strptr)); + + if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 1; + M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 0; + } else if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 0; + M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 1; + } else if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 1; + M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 1; + } + } + // timers + //{ + // int t_reloc_prep = 0; + // int tx2_reloc_overall = 0; + // paramdef_t p[] = { + // { "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 }, + // { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 } + // }; + // config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix); + + // if (t_reloc_prep <= 0 || t_reloc_prep > 10000 || + // tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) { + // LOG_E(M2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n"); + // exit(1); + // } + + // M2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep; + // M2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall; + //} + // SCTP SETTING + M2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + M2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; + + if (EPC_MODE_ENABLED) { + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + M2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + M2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); + } + + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + // NETWORK_INTERFACES + config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); + M2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_M2C = (uint32_t)*(NETParams[ENB_PORT_FOR_M2C_IDX].uptr); + + if ((NETParams[ENB_IPV4_ADDR_FOR_M2C_IDX].strptr == NULL) || (M2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_M2C == 0)) { + LOG_E(RRC,"Add eNB IPv4 address and/or port for M2C in the CONF file!\n"); + exit(1); + } + + cidr = *(NETParams[ENB_IPV4_ADDR_FOR_M2C_IDX].strptr); + address = strtok(cidr, "/"); + M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv6 = 0; + M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv4 = 1; + strcpy(M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv4_address, address); + } + } + } + } + } + + return 0; +} + //----------------------------------------------------------------------------- /* * Configure the s1ap_register_enb_req in itti message for future diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index a204a47652..4e11e12a90 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -117,6 +117,7 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i); void read_config_and_init(void); int RCconfig_X2(MessageDef *msg_p, uint32_t i); +int RCconfig_M2(MessageDef *msg_p, uint32_t i); void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int cell_idx,int cc_idx,char *config_fname); void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, int cell_idx,int cc_idx,char *config_fname,char *brparamspath); diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index a9bc3ef3de..1ff5c1fc02 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -213,6 +213,8 @@ typedef enum { #define ENB_CONFIG_STRING_RRC_INACTIVITY_THRESHOLD "rrc_inactivity_threshold" #define ENB_CONFIG_STRING_MEASUREMENT_REPORTS "enable_measurement_reports" #define ENB_CONFIG_STRING_X2 "enable_x2" +#define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2" +#define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -236,6 +238,8 @@ typedef enum { {ENB_CONFIG_STRING_RRC_INACTIVITY_THRESHOLD, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_MEASUREMENT_REPORTS, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ } #define ENB_ENB_ID_IDX 0 #define ENB_CELL_TYPE_IDX 1 @@ -255,6 +259,8 @@ typedef enum { #define ENB_RRC_INACTIVITY_THRES_IDX 15 #define ENB_ENABLE_MEASUREMENT_REPORTS 16 #define ENB_ENABLE_X2 17 +#define ENB_ENABLE_ENB_M2 18 +#define ENB_ENABLE_MCE_M2 19 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define ENBPARAMS_CHECK { \ @@ -274,6 +280,10 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -308,6 +318,32 @@ typedef enum { } +/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST "mbms_configuration_data_list" + +#define ENB_CONFIG_STRING_MBMS_SYNC_AREA "mbms_sync_area" + +#define ENB_MBMS_SYNC_AREA_IDX 0 + +#define MBMS_CONFIG_PARAMS_DESC { \ +/* optname helpstr paramflags XXXptr def val type numelt */ \ + {ENB_CONFIG_STRING_MBMS_SYNC_AREA , NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define ENB_CONFIG_STRING_MBMS_SERVICE_AREA_LIST "mbms_service_area_list" + +#define ENB_CONFIG_STRING_MBMS_SERVICE_AREA "mbms_service_area" + +#define ENB_MBMS_SERVICE_AREA_IDX 0 + +#define MBMSPARAMS_DESC { \ +/* optname helpstr paramflags XXXptr def val type numelt */ \ + {ENB_CONFIG_STRING_MBMS_SERVICE_AREA, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + + /* component carries configuration parameters name */ #define ENB_CONFIG_STRING_NB_ANT_PORTS "nb_antenna_ports" @@ -922,6 +958,39 @@ typedef struct srb1_params_s { #define ENB_X2_IPV4_ADDRESS_IDX 0 #define ENB_X2_IPV6_ADDRESS_IDX 1 #define ENB_X2_IP_ADDRESS_PREFERENCE_IDX 2 + + +/*---------------------------------------------------------------------------------------------------------------------------------------*/ + +/* M2 configuration parameters section name */ +#define ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS "target_mce_m2_ip_address" + +/* M2 configuration parameters names */ + + +#define ENB_CONFIG_STRING_TARGET_MCE_M2_IPV4_ADDRESS "ipv4" +#define ENB_CONFIG_STRING_TARGET_MCE_M2_IPV6_ADDRESS "ipv6" +#define ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS_PREFERENCE "preference" + +/*---------------------------------------------------------------------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +/* M2 configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +#define M2PARAMS_DESC { \ +{ENB_CONFIG_STRING_TARGET_MCE_M2_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TARGET_MCE_M2_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +} + +#define ENB_M2_IPV4_ADDRESS_IDX 0 +#define ENB_M2_IPV6_ADDRESS_IDX 1 +#define ENB_M2_IP_ADDRESS_PREFERENCE_IDX 2 +/*---------------------------------------------------------------------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------------------------------------------------------------*/ /* SCTP configuration parameters section name */ #define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP" @@ -955,6 +1024,10 @@ typedef struct srb1_params_s { #define ENB_PORT_FOR_S1U_IDX 4 #define ENB_IPV4_ADDR_FOR_X2C_IDX 5 #define ENB_PORT_FOR_X2C_IDX 6 +#define ENB_IPV4_ADDR_FOR_M2C_IDX 7 +#define ENB_PORT_FOR_M2C_IDX 8 +#define MCE_IPV4_ADDR_FOR_M2C_IDX 9 +#define MCE_PORT_FOR_M2C_IDX 10 /* S1 interface configuration parameters names */ #define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME" @@ -967,6 +1040,13 @@ typedef struct srb1_params_s { #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C "ENB_IPV4_ADDRESS_FOR_X2C" #define ENB_CONFIG_STRING_ENB_PORT_FOR_X2C "ENB_PORT_FOR_X2C" +/* M2 interface configuration parameters names */ +#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_M2C "ENB_IPV4_ADDRESS_FOR_M2C" +#define ENB_CONFIG_STRING_ENB_PORT_FOR_M2C "ENB_PORT_FOR_M2C" +#define ENB_CONFIG_STRING_MCE_IPV4_ADDR_FOR_M2C "MCE_IPV4_ADDRESS_FOR_M2C" +#define ENB_CONFIG_STRING_MCE_PORT_FOR_M2C "MCE_PORT_FOR_M2C" + + /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ /* S1/X2 interface configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -979,6 +1059,10 @@ typedef struct srb1_params_s { {ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_ENB_PORT_FOR_M2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_MCE_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_MCE_PORT_FOR_M2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \ } @@ -1157,4 +1241,6 @@ typedef struct srb1_params_s { #include "enb_paramdef_emtc.h" #include "enb_paramdef_sidelink.h" +#include "enb_paramdef_mce.h" +#include "enb_paramdef_mme.h" #endif diff --git a/openair2/ENB_APP/enb_paramdef_mce.h b/openair2/ENB_APP/enb_paramdef_mce.h new file mode 100644 index 0000000000..8a4dd15766 --- /dev/null +++ b/openair2/ENB_APP/enb_paramdef_mce.h @@ -0,0 +1,239 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/enb_paramdef_mce.h + * \brief definition of configuration parameters for MCE modules + * \author Javier MORGADE + * \date 2019 + * \version 0.1 + * \company VICOMTECH Spain + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "common/config/config_paramdesc.h" +#include "RRC_paramsvalues.h" + + + +/* mce configuration parameters names */ + +#define MCE_CONFIG_STRING_MCE_ID "MCE_ID" +#define MCE_CONFIG_STRING_MCE_NAME "MCE_name" +#define MCE_CONFIG_STRING_MCE_M2 "enable_mce_m2" +#define MCE_CONFIG_STRING_MCE_M3 "enable_mce_m3" + +#define MCE_PARAMS_DESC {\ +{MCE_CONFIG_STRING_MCE_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCE_NAME, NULL, 0, strptr:NULL, defstrval:"OAIMCE", TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_MCE_M3, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ +} + +#define MCE_MCE_ID_IDX 0 +#define MCE_MCE_NAME_IDX 1 +#define MCE_ENABLE_MCE_M2_IDX 2 +#define MCE_ENABLE_MCE_M3_IDX 3 + +#define MCE_PARAMS_CHECK { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ +} + + +#define MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" + +#define MCE2_INTERFACE_NAME_FOR_M2_ENB_IDX 0 +#define MCE2_IPV4_ADDR_FOR_M2C_IDX 1 +#define MCE2_PORT_FOR_M2C_IDX 2 +#define MCE2_INTERFACE_NAME_FOR_M3_MME_IDX 3 +#define MCE2_IPV4_ADDR_FOR_M3C_IDX 4 +#define MCE2_PORT_FOR_M3C_IDX 5 + +/* interface configuration parameters names */ +/* M2 interface configuration parameters names */ +#define MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M2_ENB "ENB_INTERFACE_NAME_FOR_M2_ENB" +#define MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M2C "MCE_IPV4_ADDRESS_FOR_M2C" +#define MCE_CONFIG_STRING_MCE_PORT_FOR_M2C "MCE_PORT_FOR_M2C" + +/* M3 interface configuration parameters names */ +#define MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M3_MME "MCE_INTERFACE_NAME_FOR_M3_MME" +#define MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M3C "MCE_IPV4_ADDRESS_FOR_M3C" +#define MCE_CONFIG_STRING_MCE_PORT_FOR_M3C "MCE_PORT_FOR_M3C" + + +#define MCE_NETPARAMS_DESC { \ +{MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M2_ENB, NULL, 0, strptr:&mce_interface_name_for_m2_enb, defstrval:"lo", TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M2C, NULL, 0, strptr:&mce_ipv4_address_for_m2c, defstrval:NULL, TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_MCE_PORT_FOR_M2C, NULL, 0, uptr:&mce_port_for_m2c, defintval:36443L, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M3_MME, NULL, 0, strptr:&mce_interface_name_for_m3_mme, defstrval:NULL, TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M3C, NULL, 0, strptr:&mce_ipv4_address_for_m3c, defstrval:NULL, TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_MCE_PORT_FOR_M3C, NULL, 0, uptr:&mce_port_for_m3c, defintval:36444L, TYPE_UINT, 0}, \ +} + + +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +/* M3 configuration parameters */ +/* M3 configuration parameters section name */ +#define MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS "target_mme_m3_ip_address" +/* M3 configuration parameters names */ +#define MCE_CONFIG_STRING_TARGET_MME_M3_IPV4_ADDRESS "ipv4" +#define MCE_CONFIG_STRING_TARGET_MME_M3_IPV6_ADDRESS "ipv6" +#define MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS_PREFERENCE "preference" +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +#define M3PARAMS_DESC { \ +{MCE_CONFIG_STRING_TARGET_MME_M3_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_TARGET_MME_M3_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +} + +#define MCE2_M3_IPV4_ADDRESS_IDX 0 +#define MCE2_M3_IPV6_ADDRESS_IDX 1 +#define MCE2_M3_IP_ADDRESS_PREFERENCE_IDX 2 + + +/*-----------------------------------------------------------------------------------------------------------------------------------*/ +/* MCCH related BCCH Configuration per MBSFN area configuration parameters */ +/* MCCH configuration parameters section */ +#define MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA "mcch_config_per_mbsfn_area" +/* M3 configuration parameters names */ +#define MCE_CONFIG_STRING_MCCH_MBSFN_AREA "mbsfn_area" +#define MCE_CONFIG_STRING_MCCH_PDCCH_LENGTH "pdcch_length" +#define MCE_CONFIG_STRING_MCCH_REPETITION_PERIOD "repetition_period" +#define MCE_CONFIG_STRING_MCCH_OFFSET "offset" +#define MCE_CONFIG_STRING_MCCH_MODIFICATION_PERIOD "modification_period" +#define MCE_CONFIG_STRING_MCCH_SF_ALLOCATION_INFO "subframe_allocation_info" +#define MCE_CONFIG_STRING_MCCH_MCS "mcs" + +/* optname helpstr paramflags XXXptr defXXXval type numelt */ + +#define MCCH_PARAMS_DESC { \ +{MCE_CONFIG_STRING_MCCH_MBSFN_AREA, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCCH_PDCCH_LENGTH, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCCH_REPETITION_PERIOD, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCCH_OFFSET, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCCH_MODIFICATION_PERIOD,NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCCH_SF_ALLOCATION_INFO, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCCH_MCS, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + +#define MCCH_MBSFN_AREA_IDX 0 +#define MCCH_PDCCH_LENGTH_IDX 1 +#define MCCH_REPETITION_PERIOD_IDX 2 +#define MCCH_OFFSET_IDX 3 +#define MCCH_MODIFICATION_PERIOD_IDX 4 +#define MCCH_SF_ALLOCATION_INFO_IDX 5 +#define MCCH_MCS_IDX 6 +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +/* M3 configuration parameters section name */ +#define MCE_CONFIG_STRING_PLMN "plnm" +/* M3 configuration parameters names */ +#define MCE_CONFIG_STRING_MCC "mcc" +#define MCE_CONFIG_STRING_MNC "mnc" +#define MCE_CONFIG_STRING_MNC_LENGTH "mnc_length" +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +#define MCE_PLMN_PARAMS_DESC { \ +{MCE_CONFIG_STRING_MCC, NULL, 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MNC, NULL, 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MNC_LENGTH, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + +#define MCE_CONFIG_STRING_MCC_IDX 0 +#define MCE_CONFIG_STRING_MNC_IDX 1 +#define MCE_CONFIG_STRING_MNC_LENGTH_IDX 2 +/*-------------------------------------------------------------------------------------------------------------------------------------*/ + +#define MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO "mbms_sched_info" + +#define MCE_CONFIG_STRING_MCCH_UPDATE_TIME "mcch_update_time" +#define MCE_MBMS_SCHEDULING_INFO_PARAMS_DESC { \ +{MCE_CONFIG_STRING_MCCH_UPDATE_TIME, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} +#define MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX 0 + +///*-------------------------------------------------------------------------------------------------------------------------------------*/ +#define MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST "mbms_area_config_list" + +#define MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD "common_sf_allocation_period" +#define MCE_CONFIG_STRING_MBMS_AREA_ID "mbms_area_id" + +#define MCE_MBMS_AREA_CONFIGURATION_LIST_PARAMS_DESC { \ +{MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MBMS_AREA_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} +#define MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD_IDX 0 +#define MCE_CONFIG_STRING_MBMS_AREA_ID_IDX 1 +// +///*-------------------------------------------------------------------------------------------------------------------------------------*/ +#define MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST "pmch_config_list" + +#define MCE_CONFIG_STRING_ALLOCATED_SF_END "allocated_sf_end" +#define MCE_CONFIG_STRING_DATA_MCS "data_mcs" +#define MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD "mch_scheduling_period" + +#define MCE_MBMS_PMCH_CONFIGURATION_LIST_PARAMS_DESC { \ +{MCE_CONFIG_STRING_ALLOCATED_SF_END, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_DATA_MCS, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} +#define MCE_CONFIG_STRING_ALLOCATED_SF_END_IDX 0 +#define MCE_CONFIG_STRING_DATA_MCS_IDX 1 +#define MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD_IDX 2 +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +#define MCE_CONFIG_STRING_MBMS_SESSION_LIST "mbms_session_list" + +#define MCE_CONFIG_STRING_MBMS_SERVICE_ID "service_id" +#define MCE_CONFIG_STRING_MBMS_LCID_ID "lcid_id" +#define MCE_CONFIG_STRING_MBMS_LCID "lcid" + +#define MCE_MBMS_MBMS_SESSION_LIST_DESC { \ +{MCE_CONFIG_STRING_MBMS_SERVICE_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT32, 0}, \ +{MCE_CONFIG_STRING_MBMS_LCID_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_MBMS_LCID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} +#define MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX 0 +#define MCE_CONFIG_STRING_MBMS_LCID_ID_IDX 1 +#define MCE_CONFIG_STRING_MBMS_LCID_IDX 2 + +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +#define MCE_CONFIG_STRING_MBMS_SF_CONFIGURATION_LIST "mbms_sf_config_list" + +#define MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD "radioframe_allocation_period" +#define MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET "radioframe_alloocation_offset" +#define MCE_CONFIG_STRING_NUM_FRAME "num_frame" +#define MCE_CONFIG_STRING_SUBFRAME_ALLOCATION "subframe_allocation" + +#define MCE_MBMS_MBMS_SF_CONFIGURATION_LIST_PARAMS_DESC { \ +{MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{MCE_CONFIG_STRING_NUM_FRAME, NULL, 0, strptr:NULL, defstrval:"oneFrame", TYPE_STRING, 0}, \ +{MCE_CONFIG_STRING_SUBFRAME_ALLOCATION, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +} +#define MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD_IDX 0 +#define MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET_IDX 1 +#define MCE_CONFIG_STRING_NUM_FRAME_IDX 2 +#define MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX 3 + + + diff --git a/openair2/ENB_APP/enb_paramdef_mme.h b/openair2/ENB_APP/enb_paramdef_mme.h new file mode 100644 index 0000000000..0ff1df765c --- /dev/null +++ b/openair2/ENB_APP/enb_paramdef_mme.h @@ -0,0 +1,82 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/enb_paramdef_mme.h + * \brief definition of configuration parameters for MME modules + * \author Javier MORGADE + * \date 2019 + * \version 0.1 + * \company VICOMTECH Spain + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "common/config/config_paramdesc.h" +#include "RRC_paramsvalues.h" + + + +/* mme configuration parameters names */ + +#define MME_CONFIG_STRING_MME_ID "MME_ID" +#define MME_CONFIG_STRING_MME_NAME "MME_name" +#define MME_CONFIG_STRING_MME_M3 "enable_mme_m3" + +#define MMEPARAMS_DESC {\ +{MME_CONFIG_STRING_MME_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{MME_CONFIG_STRING_MME_NAME, NULL, 0, strptr:NULL, defstrval:"OAIMME", TYPE_STRING, 0}, \ +{MME_CONFIG_STRING_MME_M3, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ +} + +#define MME_MME_ID_IDX 0 +#define MME_MME_NAME_IDX 1 +#define MME_ENABLE_MME_M3_IDX 2 + +#define MMEPARAMS_CHECK { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ +} + + +#define MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" + +#define MME_INTERFACE_NAME_FOR_M3_MME_IDX 0 +#define MME_IPV4_ADDRESS_FOR_M3C_IDX 1 +#define MME_PORT_FOR_M3C_IDX 2 + +/* interface configuration parameters names */ +/* M3 interface configuration parameters names */ +#define MME_CONFIG_STRING_MME_INTERFACE_NAME_FOR_M3_MCE "MME_INTERFACE_NAME_FOR_M3_MCE" +#define MME_CONFIG_STRING_MME_IPV4_ADDRESS_FOR_M3C "MME_IPV4_ADDRESS_FOR_M3C" +#define MME_CONFIG_STRING_MME_PORT_FOR_M3C "MME_PORT_FOR_M3C" + + +#define MME_NETPARAMS_DESC { \ +{MME_CONFIG_STRING_MME_INTERFACE_NAME_FOR_M3_MCE, NULL, 0, strptr:&mme_interface_name_for_m3_mce, defstrval:"lo", TYPE_STRING, 0}, \ +{MME_CONFIG_STRING_MME_IPV4_ADDRESS_FOR_M3C, NULL, 0, strptr:&mme_ipv4_address_for_m3c, defstrval:"127.0.0.18/24", TYPE_STRING, 0}, \ +{MME_CONFIG_STRING_MME_PORT_FOR_M3C, NULL, 0, uptr:&mme_port_for_m3c, defintval:36444L, TYPE_UINT, 0}, \ +} + + + + diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index bb81c2c2d2..4bd4ab6089 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -2607,6 +2607,8 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) (*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; (*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; break; + case ngran_eNB_MBMS_STA: + break; } return n_caps; } @@ -2643,6 +2645,8 @@ uint16_t flexran_get_capabilities_mask(mid_t mod_id) | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC); break; + case ngran_eNB_MBMS_STA: + break; } return mask; } From dc14cdc665e1b885f1082a8580f395943211edff Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:23:30 +0200 Subject: [PATCH 015/134] *L2 procedures to enable mixed unicast/broadcast operation at ENB implemeted: -MBMS scheduler developed (oneFrame allocations implemented at this time) -UE DSLCH schedulers updated: if an eMBMS session running UE DTCH, DCCH will be only scheduled at non MBSFN sufbframes -eMBMS L2 procedures implemented -Dedicated MBMS PDCP pipes src/sink enabled (only for TUN) -BUGFIX eMBMS MAC procedures (wrong indexing at few loops) -ENB FAPI updated to enable dynamic MBSFN configurations through M2AP (RRC<->MCE) ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/LAYER2/MAC/config.c | 125 ++++++++++++++++ openair2/LAYER2/MAC/config_ue.c | 5 +- openair2/LAYER2/MAC/defs.h | 2 +- openair2/LAYER2/MAC/defs_NB_IoT.h | 3 +- openair2/LAYER2/MAC/eNB_scheduler.c | 1 + openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 7 + openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 6 + openair2/LAYER2/MAC/eNB_scheduler_mch.c | 160 +++++++++++++++++---- openair2/LAYER2/MAC/mac.h | 7 +- openair2/LAYER2/MAC/ue_procedures.c | 37 +++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 149 +++++++++++++++++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 14 ++ openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 156 +++++++++++++++++++- openair2/LAYER2/RLC/rlc_rrc.c | 6 +- 14 files changed, 619 insertions(+), 59 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ec2497d6ad..b687a22909 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -53,6 +53,7 @@ #include "LTE_MBSFN-AreaInfoList-r9.h" #include "LTE_MBSFN-AreaInfo-r9.h" #include "LTE_MBSFN-SubframeConfigList.h" +#include "LTE_MBSFN-SubframeConfig.h" #include "LTE_PMCH-InfoList-r9.h" @@ -633,6 +634,123 @@ config_sib2(int Mod_idP, #endif } +void +config_sib2_mbsfn_part( int Mod_idP, + int CC_idP, + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { + + //LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_idP][CC_idP]->frame_parms; + //int i; + //if(mbsfn_SubframeConfigListP != NULL) { + // fp->num_MBSFN_config = mbsfn_SubframeConfigListP->list.count; + + // for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) { + // fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod; + // fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset; + + // if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + // fp->MBSFN_config[i].fourFrames_flag = 0; + // fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + // LOG_I (PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); + // } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + // fp->MBSFN_config[i].fourFrames_flag = 1; + // fp->MBSFN_config[i].mbsfn_SubframeConfig = + // mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| + // (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + // (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + + // LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, + // fp->MBSFN_config[i].mbsfn_SubframeConfig); + // } + // } + + //} else + // fp->num_MBSFN_config = 0; + + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_idP; + phycfg.CC_id = CC_idP; + phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; + int i; + + if(mbsfn_SubframeConfigListP != NULL) { + phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = mbsfn_SubframeConfigListP->list.count; + + for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) { + phycfg.cfg->embms_mbsfn_config.radioframe_allocation_period[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod; + phycfg.cfg->embms_mbsfn_config.radioframe_allocation_offset[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset; + + if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 0; + phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); + } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 1; + phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = + mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| + (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + + LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, + phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); + } + } + phycfg.cfg->num_tlv++; + + } else{ + phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = 0; + phycfg.cfg->num_tlv++; + } + + phycfg.cfg->embms_mbsfn_config.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_TAG; + + if (RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req) RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req(&phycfg); +} + +void +config_sib13( int Mod_id, + int CC_id, + int mbsfn_Area_idx, + long mbsfn_AreaId_r9){ + + //nfapi_config_request_t *cfg = &RC.mac[Mod_id]->config[CC_id]; + + //work around until PHY_config_re "update" mechanisms get defined +// LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; +// LOG_I (MAC, "[eNB%d] Applying MBSFN_Area_id %ld for index %d\n", Mod_id, mbsfn_AreaId_r9, mbsfn_Area_idx); +// +// AssertFatal(mbsfn_Area_idx == 0, "Fix me: only called when mbsfn_Area_idx == 0\n"); +// if (mbsfn_Area_idx == 0) { +// fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; +// LOG_I(MAC,"Fix me: only called when mbsfn_Area_idx == 0)\n"); +// } +// lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn); +// +//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +// lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); +//#endif +// + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_id; + phycfg.CC_id = CC_id; + phycfg.cfg = &RC.mac[Mod_id]->config[CC_id]; + + phycfg.cfg->embms_sib13_config.mbsfn_area_idx.value = (uint8_t)mbsfn_Area_idx; + phycfg.cfg->embms_sib13_config.mbsfn_area_idx.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG; + phycfg.cfg->num_tlv++; + phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.value = (uint32_t)mbsfn_AreaId_r9; + phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG; + phycfg.cfg->num_tlv++; + + if (RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req) RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req(&phycfg); + +// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + +} + + + + void config_dedicated(int Mod_idP, int CC_idP, @@ -878,6 +996,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag; #endif + config_sib2_mbsfn_part(Mod_idP,0,mbsfn_SubframeConfigList); + } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -925,6 +1045,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_idP,i, RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); // config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); + config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } @@ -954,6 +1075,10 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, RC.mac[Mod_idP]->common_channels[0]. mbms_SessionList[i]->list.count); + for(int ii=0; ii < RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.count;ii++){ + LOG_I(MAC, "PMCH[%d] MBMS Session[%d] is: %lu\n", i,ii, + RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.array[ii]->logicalChannelIdentity_r9); + } } } diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index 50586c37e3..bad219caab 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -162,7 +162,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, phy_config_sib2_ue(Mod_idP, 0, eNB_index, radioResourceConfigCommon, ul_CarrierFreq, ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); + NULL/*mbsfn_SubframeConfigList*/); } // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup @@ -513,6 +513,9 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, } if (mbsfn_SubframeConfigList != NULL) { + phy_config_mbsfn_list_ue(Mod_idP, 0, + mbsfn_SubframeConfigList); + LOG_I(MAC, "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_idP, mbsfn_SubframeConfigList->list.count); diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 45b46aae54..451117823a 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -327,7 +327,7 @@ typedef struct { /*!\brief DTCH DRB1 logical channel */ #define DTCH 3 // LCID /*!\brief MCCH logical channel */ -#define MCCH 4 +#define MCCH 11 /*!\brief MTCH logical channel */ #define MTCH 1 // DLSCH LCHAN ID diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h index 0d7dd7d2c0..517f01d1b9 100644 --- a/openair2/LAYER2/MAC/defs_NB_IoT.h +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -64,7 +64,8 @@ #define DTCH 3 // LCID /*!\brief MCCH logical channel */ //#define MCCH 4 -#define MCCH 62 +//#define MCCH 62 +#define MCCH 11 /*!\brief MTCH logical channel */ #define MTCH 1 // DLSCH LCHAN ID diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 3a809c4327..76fae02374 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -931,6 +931,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP); pdcp_run(&ctxt); + pdcp_mbms_run(&ctxt); rrc_rx_tx(&ctxt, CC_id); #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 134089dbf4..22775f8c7d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -506,6 +506,13 @@ schedule_ue_spec(module_id_t module_idP, rrc_eNB_ue_context_t *ue_contextP = NULL; int nb_mac_CC = RC.nb_mac_CC[module_idP]; long dl_Bandwidth; + + if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){ + //LOG_E(MAC,"Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP); + return ; + } + + start_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index c071c1f505..7ac5918b6e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -855,6 +855,12 @@ schedule_ue_spec_fairRR(module_id_t module_idP, #ifdef DEBUG_eNB_SCHEDULER int k; #endif + + if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){ + //LOG_E(MAC,"fairRR Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP); + return; + } + start_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index cf358752e8..552e870c59 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -65,7 +65,7 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area) { // currently there is one-to-one mapping between sf allocation pattern and sync area - if (mbsfn_sync_area >= MAX_MBSFN_AREA) { + if (mbsfn_sync_area > MAX_MBSFN_AREA) { LOG_W(MAC, "[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ", module_idP, CC_id, mbsfn_sync_area); @@ -82,6 +82,18 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, } } +uint32_t bytes_in_buffer=0; +uint8_t msi_active=0; +uint8_t msi_pmch_stop=0; +uint8_t msi_pmch_stop2=0; + +uint16_t mbms_rab_id = 2047; + +uint8_t msi_sfs=0; + + +//MSI_ELEMENT * ptr =NULL; + int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP) @@ -90,6 +102,12 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + if(RC.mac[module_idP]->common_channels[CC_id]. + pmch_Config[0] == NULL ) + + return 0; + + int mch_scheduling_period = 8 << (RC.mac[module_idP]->common_channels[CC_id]. pmch_Config[0]->mch_SchedulingPeriod_r9); @@ -103,6 +121,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, mac_rlc_status_resp_t rlc_status; int num_mtch; int msi_length, i, k; + //uint8_t l =0; unsigned char sdu_lcids[11], num_sdus = 0, offset = 0; uint16_t sdu_lengths[11], sdu_length_total = 0; unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only @@ -480,6 +499,12 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } else if (mtch_flag == 1) { // only MTCH in this subframeP cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; } + + + uint8_t num_sf_alloc=0; + for( int iii=0; iii < 6; iii++) + num_sf_alloc += ( 0x39 & (0x80>>iii)) == (0x80 >> iii); + // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC // there is MSI (MCH Scheduling Info) @@ -488,25 +513,80 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint16_t msi_control_element[29], *msi_ptr; msi_ptr = &msi_control_element[0]; - ((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH + //((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH - if (mcch_flag == 1) { - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; - } else { // no mcch for this MSP - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047 - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; - } + //if (mcch_flag == 1) { + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; + //} else { // no mcch for this MSP + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047 + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; + //} - msi_ptr += sizeof(MSI_ELEMENT); + //msi_ptr += sizeof(MSI_ELEMENT); //Header for MTCHs num_mtch = cc->mbms_SessionList[0]->list.count; + TBS = + get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); + //l=0; + for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; + //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0x2; //100 + + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) + //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; //100 + +// ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x0; // last subframeP of this mtch (only one mtch now) +// ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0x2; //100 + + //while((++l)*TBS<=bytes_in_buffer && l<=cc->pmch_Config[0]->sf_AllocEnd_r9){ + // if(l>=6 && l<=cc->pmch_Config[0]->sf_AllocEnd_r9){ + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; //we limite till 256 TOFIX + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = l; + // } + //} + //ptr = (MSI_ELEMENT *) msi_ptr; + + if( msi_sfs != 0 ) + msi_pmch_stop = msi_sfs-1; + else + msi_pmch_stop = msi_sfs; + //msi_pmch_stop = bytes_in_buffer/TBS; + //if(bytes_in_buffer%TBS) + //msi_pmch_stop++; + + // + //msi_pmch_stop = 20; + if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) + //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop; + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); + msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); + }else{ + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; //100 + msi_pmch_stop=0; + } +// do{ +// if(l>=0 && l<=cc->pmch_Config[0]->sf_AllocEnd_r9){ +// ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; //we limite till 256 TOFIX +// ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = l; +// } +// }while((l++)*TBS<=bytes_in_buffer); +// + // if(((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB !=0x7 && ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB != 0xFF ) + // msi_active=1; + // else + // msi_active=1; + //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = l; + // l++; + // } msi_ptr += sizeof(MSI_ELEMENT); } @@ -519,8 +599,11 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes \n", - module_idP, CC_id, frameP, msi_length); + "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes TBS %d, bytes in buffer %d stop_sf_LSB %d msi_sfs %d cc->pmch_Config[0]->sf_AllocEnd_r9 %ld\n", + module_idP, CC_id, frameP, msi_length,TBS, bytes_in_buffer,msi_pmch_stop,msi_sfs,cc->pmch_Config[0]->sf_AllocEnd_r9); + + msi_sfs = 0; + //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" ); // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length); @@ -531,7 +614,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sdu_lcids[num_sdus] = MCH_SCHDL_INFO; sdu_lengths[num_sdus] = msi_length; sdu_length_total += sdu_lengths[num_sdus]; - LOG_I(MAC, "[eNB %d] CC_id %d Create %d bytes for MSI\n", + LOG_D(MAC, "[eNB %d] CC_id %d Create %d bytes for MSI\n", module_idP, CC_id, sdu_lengths[num_sdus]); num_sdus++; cc->msi_active = 1; @@ -545,6 +628,8 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], i); // this is the mbsfn sync area index + mcch_sdu_length+=1; //RLC ? + if (mcch_sdu_length > 0) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", @@ -558,7 +643,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, module_idP, CC_id, frameP, subframeP, mcch_sdu_length, mcch_mcs); } else { - LOG_I(MAC, + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", module_idP, CC_id, frameP, subframeP, mcch_sdu_length, mcch_mcs); @@ -566,7 +651,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, cc->mcch_active = 1; - memcpy((char *) &mch_buffer[sdu_length_total], + memcpy((char *) &mch_buffer[sdu_length_total]+1, &cc->MCCH_pdu.payload[0], mcch_sdu_length); sdu_lcids[num_sdus] = MCCH_LCHANID; sdu_lengths[num_sdus] = mcch_sdu_length; @@ -584,7 +669,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } TBS = - get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); + get_TBS_DL(cc->pmch_Config[0]->dataMCS_r9/*cc->MCH_pdu.mcs*/, to_prb(cc->mib->message.dl_Bandwidth)); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // do not let mcch and mtch multiplexing when relaying is active // for sync area 1, so not transmit data @@ -592,7 +677,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, #endif // there is MTCHs, loop if there are more than 1 - if (mtch_flag == 1) { + if (mtch_flag == 1 ) { // Calculate TBS /* if ((msi_flag==1) || (mcch_flag==1)) { TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL); @@ -627,29 +712,37 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch); + mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9; + rlc_status = mac_rlc_status_ind(module_idP, 0, frameP, subframeP, module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, - MTCH, + cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, + //MTCH, TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); + bytes_in_buffer = rlc_status.bytes_in_buffer; + + + msi_sfs = rlc_status.bytes_in_buffer/TBS+(rlc_status.bytes_in_buffer%TBS?1:0); LOG_D(MAC, - "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", - MTCH, frameP, subframeP, rlc_status.bytes_in_buffer); + "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS %d pmch_stop %d msi_sfs %d\n", + MTCH, frameP, subframeP, rlc_status.bytes_in_buffer,TBS,msi_pmch_stop,msi_sfs); - if (rlc_status.bytes_in_buffer > 0) { + if (rlc_status.bytes_in_buffer > 0 /*&& msi_pmch_stop > 0*/ /*msi_pmch_stop>=num_sf_alloc*/ ) { + //if(rlc_status.bytes_in_buffer > 0){ LOG_I(MAC, "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n", module_idP, CC_id, frameP, TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch, header_len_mtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, 0, //not used (char *) &mch_buffer[sdu_length_total] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -657,22 +750,31 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, 0 #endif ); - - + //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]); LOG_I(MAC, - "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n", - module_idP, CC_id, sdu_lengths[num_sdus], MTCH); + "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_sfs %d sdu_lengths[num_sdus] %d\n", + module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs, sdu_lengths[num_sdus]); cc->mtch_active = 1; - sdu_lcids[num_sdus] = MTCH; + sdu_lcids[num_sdus] = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9/*MTCH*/; sdu_length_total += sdu_lengths[num_sdus]; + if (msi_pmch_stop != 0) + msi_pmch_stop--; + + if (sdu_lengths[num_sdus] < 128) { header_len_mtch = 2; } num_sdus++; - } else { + //} + } + else { + // LOG_E(MAC, + // "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_buffer %d msi_sfs %ld msi_buffer_act %ld sdu_lengths[num_sdus] %d\n", + // module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs,msi_buffer_act, sdu_lengths[num_sdus]); + header_len_mtch = 0; } } @@ -750,7 +852,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, " MCS for this sf is %d (mcch active %d, mtch active %d)\n", cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active, cc->MCH_pdu.mtch_active); - LOG_I(MAC, + LOG_D(MAC, "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", module_idP, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding, diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 33502c00da..c2e1e18957 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -424,8 +424,8 @@ typedef struct { #define BCCH_SI_BR 7 // SI-BR #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /*!\brief Values of BCCH SIB1_BR logical channel (fake) */ -#define BCCH_SIB1_MBMS 60 // SIB1_MBMS //TODO better armonize index -#define BCCH_SI_MBMS 61 // SIB_MBMS //TODO better armonize index +#define BCCH_SIB1_MBMS 12 // SIB1_MBMS //TODO better armonize index +#define BCCH_SI_MBMS 13 // SIB_MBMS //TODO better armonize index #endif /*!\brief Value of CCCH / SRB0 logical channel */ #define CCCH 0 // srb0 @@ -437,7 +437,8 @@ typedef struct { #define DTCH 3 // LCID /*!\brief MCCH logical channel */ //#define MCCH 4 -#define MCCH 62 +//#define MCCH 62 +#define MCCH 11 /*!\brief MTCH logical channel */ #define MTCH 1 // DLSCH LCHAN ID diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index f001c5f2ae..c58b2a937a 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -73,6 +73,8 @@ extern UL_IND_t *UL_INFO; extern int next_ra_frame; extern module_id_t next_Mod_id; +int mbms_rab_id = 2047; + /* * #ifndef USER_MODE @@ -828,6 +830,9 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) { LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j); + //This sucks I know ... workaround ! + mbms_rab_id = rx_lcids[i]; + //end sucks :-( mac_rlc_data_ind( module_idP, UE_mac_inst[module_idP].crnti, @@ -1132,6 +1137,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) { int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1; + int l =0; int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; long mch_scheduling_period = -1; uint8_t mch_lcid = 0; @@ -1383,28 +1389,39 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ // Acount for sf_allocable in CSA int num_sf_alloc = 0; - for (i = 0; i < 8; i++) { - if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) continue; - if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) continue; - uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]; + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0]; for (j = 0; j < 6; j++) num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j)); } - for (i = 0; i < 28; i++) { - if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) { - if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) { - if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL) + for (l = 0; l < 28; l++) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= num_sf_alloc) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[l] != 2047) { + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL){ mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationPeriod; + long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + if(UE_mac_inst[module_idP].common_num_sf_alloc >= UE_mac_inst[module_idP].pmch_stop_mtch[l]){ + //LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc); + mtch_mcs = -1; + } + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period); + + + } else mtch_mcs = -1; - mch_lcid = (uint8_t)i; + mch_lcid = (uint8_t)l; break; } } @@ -1413,7 +1430,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ // sf allocation is non-overlapping if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", - module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag); + module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag); *sync_area=i; break; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 41688a62cf..8db23e4e4e 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -966,15 +966,15 @@ pdcp_data_ind( #ifdef MBMS_MULTICAST_OUT if ((MBMS_flagP != 0) && (mbms_socket != -1)) { - struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset]; - struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)]; - struct sockaddr_in dest_addr; - dest_addr.sin_family = AF_INET; - dest_addr.sin_port = udp_header->dest; - dest_addr.sin_addr.s_addr = ip_header->daddr; + // struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset]; + // struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)]; + // struct sockaddr_in dest_addr; + // dest_addr.sin_family = AF_INET; + // dest_addr.sin_port = udp_header->dest; + // dest_addr.sin_addr.s_addr = ip_header->daddr; - sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); - //packet_forwarded = TRUE; + // sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); + // //packet_forwarded = TRUE; } @@ -1250,6 +1250,131 @@ pdcp_run ( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT); } +//----------------------------------------------------------------------------- +void +pdcp_mbms_run ( + const protocol_ctxt_t *const ctxt_pP +) +//----------------------------------------------------------------------------- +{ + // if (ctxt_pP->enb_flag) { + // start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run); + // } else { + // start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); + // } + + // pdcp_enb[ctxt_pP->module_id].sfn++; // range: 0 to 18,446,744,073,709,551,615 + // pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023 + // pdcp_enb[ctxt_pP->module_id].subframe= ctxt_pP->subframe; + // pdcp_update_stats(ctxt_pP); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); + // MessageDef *msg_p; + //int result; + //protocol_ctxt_t ctxt; + +// do { +// // Checks if a message has been sent to PDCP sub-task +// itti_poll_msg (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p); +// +// if (msg_p != NULL) { +// switch (ITTI_MSG_ID(msg_p)) { +// case RRC_DCCH_DATA_REQ: +// PROTOCOL_CTXT_SET_BY_MODULE_ID( +// &ctxt, +// RRC_DCCH_DATA_REQ (msg_p).module_id, +// RRC_DCCH_DATA_REQ (msg_p).enb_flag, +// RRC_DCCH_DATA_REQ (msg_p).rnti, +// RRC_DCCH_DATA_REQ (msg_p).frame, +// 0, +// RRC_DCCH_DATA_REQ (msg_p).eNB_index); +// LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", +// PROTOCOL_CTXT_ARGS(&ctxt), +// ITTI_MSG_NAME (msg_p), +// ITTI_MSG_ORIGIN_NAME(msg_p), +// ITTI_MSG_INSTANCE (msg_p), +// RRC_DCCH_DATA_REQ (msg_p).rb_id, +// RRC_DCCH_DATA_REQ (msg_p).muip, +// RRC_DCCH_DATA_REQ (msg_p).confirmp, +// RRC_DCCH_DATA_REQ (msg_p).mode); +// LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); +// result = pdcp_data_req (&ctxt, +// SRB_FLAG_YES, +// RRC_DCCH_DATA_REQ (msg_p).rb_id, +// RRC_DCCH_DATA_REQ (msg_p).muip, +// RRC_DCCH_DATA_REQ (msg_p).confirmp, +// RRC_DCCH_DATA_REQ (msg_p).sdu_size, +// RRC_DCCH_DATA_REQ (msg_p).sdu_p, +// RRC_DCCH_DATA_REQ (msg_p).mode, +// NULL, NULL +// ); +// +// if (result != TRUE) +// LOG_E(PDCP, "PDCP data request failed!\n"); +// +// // Message buffer has been processed, free it now. +// result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ (msg_p).sdu_p); +// AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +// break; +// +// case RRC_PCCH_DATA_REQ: { +// sdu_size_t sdu_buffer_sizeP; +// sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size; +// uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id; +// uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index; +// RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP; +// +// if (sdu_buffer_sizeP > 0) { +// memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP); +// } +// +// //paging pdcp log +// LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP); +// } +// break; +// +// default: +// LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); +// break; +// } +// +// result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); +// AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +// } +// } while(msg_p != NULL); +// + // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer + // if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { + pdcp_fifo_read_input_mbms_sdus_fromtun(ctxt_pP); + } + + // PDCP -> NAS/IP traffic: RX +// if (ctxt_pP->enb_flag) { +// start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip); +// } else { +// start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip); +// } +// + + //pdcp_fifo_flush_mbms_sdus(ctxt_pP); + +// if (ctxt_pP->enb_flag) { +// stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip); +// } else { +// stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip); +// } +// +// if (ctxt_pP->enb_flag) { +// stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run); +// } else { +// stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); +// } +// +// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT); +} + + + void pdcp_init_stats_UE(module_id_t mod, uint16_t uid) { Pdcp_stats_tx_window_ms[mod][uid] = 100; Pdcp_stats_rx_window_ms[mod][uid] = 100; @@ -1694,7 +1819,7 @@ rrc_pdcp_config_asn1_req ( for (j=0; jlist.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; - if (MBMS_SessionInfo_p->sessionId_r9) + if (0/*MBMS_SessionInfo_p->sessionId_r9*/) lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; else lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; @@ -1721,7 +1846,7 @@ rrc_pdcp_config_asn1_req ( } } - LOG_D(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n", + LOG_I(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n", lc_id, MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0], MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1], @@ -2169,10 +2294,14 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { if(UE_NAS_USE_TUN) { int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; netlink_init_tun("ue",num_if); + netlink_init_mbms_tun("uem",1); + nas_config_mbms(1, 2, 2, "uem"); LOG_I(PDCP, "UE pdcp will use tun interface\n"); } else if(ENB_NAS_USE_TUN) { netlink_init_tun("enb",1); nas_config(1, 1, 1, "enb"); + netlink_init_mbms_tun("enm",1); + nas_config_mbms(1, 2, 1, "enm"); LOG_I(PDCP, "ENB pdcp will use tun interface\n"); } else { LOG_I(PDCP, "pdcp will use kernel modules\n"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 860f90bf34..d0cf1ad98c 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -392,6 +392,17 @@ boolean_t pdcp_remove_UE( */ //void rrc_pdcp_config_release ( const protocol_ctxt_t* const ctxt_pP, rb_id_t); +/*! \fn void pdcp_mbms_run(const protocol_ctxt_t* const ctxt_pP) +* \brief Runs PDCP entity to let it handle incoming/outgoing SDUs +* \param[in] ctxt_pP Running context. +* \return none +* \note None +* @ingroup _pdcp +*/ +void pdcp_mbms_run ( + const protocol_ctxt_t *const ctxt_pP); + + /*! \fn void pdcp_run(const protocol_ctxt_t* const ctxt_pP) * \brief Runs PDCP entity to let it handle incoming/outgoing SDUs * \param[in] ctxt_pP Running context. @@ -416,6 +427,9 @@ void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req); void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind); pdcp_data_ind_func_t get_pdcp_data_ind_func(void); //----------------------------------------------------------------------------- +int pdcp_fifo_flush_mbms_sdus ( const protocol_ctxt_t *const ctxt_pP); +int pdcp_fifo_read_input_mbms_sdus_fromtun ( const protocol_ctxt_t *const ctxt_pP); + /* * Following two types are utilized between NAS driver and PDCP diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index dc1799ccb6..9ad57db7a1 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -77,6 +77,11 @@ extern struct iovec nas_iov_rx; extern int nas_sock_fd[MAX_MOBILES_PER_ENB]; +extern int nas_sock_mbms_fd[8]; + +extern int mbms_rab_id; + + extern struct msghdr nas_msg_tx; extern struct msghdr nas_msg_rx; @@ -125,7 +130,16 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) ); } else if (UE_NAS_USE_TUN) { - ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + //ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + if(rb_id == mbms_rab_id){ + ret = write(nas_sock_mbms_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); + } + else + { + ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); + } } else if (ENB_NAS_USE_TUN) { ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); } else if (PDCP_USE_NETLINK) { @@ -143,6 +157,47 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { return pdcp_nb_sdu_sent; } +int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) { + mem_block_t *sdu_p; + int pdcp_nb_sdu_sent = 0; + //int ret=0; + + while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) { + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + //int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id; + //int sizeToWrite= sizeof (pdcp_data_ind_header_t) + + //((pdcp_data_ind_header_t *) sdu_p->data)->data_size; + + //if (rb_id == 10) { //hardcoded for PC5-Signaling + // if( LOG_DEBUGFLAG(DEBUG_PDCP) ) { + // debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), + // "pdcp_fifo_flush_sdus sends a aPC5S message"); + // } + + // ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), + // sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) ); + //} else if (UE_NAS_USE_TUN) { + // ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + // LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); + + //} else if (ENB_NAS_USE_TUN) { + // ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + //} else if (PDCP_USE_NETLINK) { + // memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite); + // nas_nlh_tx->nlmsg_len = sizeToWrite; + // ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0); + //} // PDCP_USE_NETLINK + + //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); + list_remove_head (&pdcp_sdu_list); + free_mem_block (sdu_p, __func__); + pdcp_nb_sdu_sent ++; + } + + return pdcp_nb_sdu_sent; +} + + int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { protocol_ctxt_t ctxt = *ctxt_pP; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; @@ -210,6 +265,105 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { return len; } +int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { + protocol_ctxt_t ctxt = *ctxt_pP; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc = HASH_TABLE_OK; + //pdcp_t *pdcp_p = NULL; + int len; + rb_id_t rab_id = mbms_rab_id;//DEFAULT_RAB_ID; + //if(mbms_rab_id > 9 || mbms_rab_id < 4) + //h_rc = 2; + + if(UE_NAS_USE_TUN) + return 0; + + do { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 1 ); + len = read(UE_NAS_USE_TUN?nas_sock_mbms_fd[0]:nas_sock_mbms_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 0 ); + + if (len<=0) continue; + + if (UE_NAS_USE_TUN) { + //key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + //h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + } else { // => ENB_NAS_USE_TUN + //ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0]; + // ctxt.enb_flag=ENB_FLAG_YES; + // ctxt.module_id=0; + // key = PDCP_COLL_KEY_VALUE(ctxt.module_id, /*ctxt.rnti*/0, ctxt.enb_flag, /*mbms_rab_id*/8, SRB_FLAG_YES); + // h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + // LOG_W(PDCP,"h_rc %d %d\n",h_rc,rab_id); + } + + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + + if (h_rc == HASH_TABLE_OK) { + LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + ctxt.frame, ctxt.instance, len, rab_id); + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n", + ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, + ctxt.rnti, rab_id); + MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt.instance, rab_id, rab_id, len); + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + //DEFAULT_RAB_ID, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + len, + (unsigned char *)nl_rx_buf, + PDCP_TRANSMISSION_MODE_TRANSPARENT + , NULL, NULL + ); + + //pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, + // RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf, + // PDCP_TRANSMISSION_MODE_DATA + // , NULL, NULL + // ); + } else { + MSC_LOG_RX_DISCARDED_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt.instance, rab_id, rab_id, len); + LOG_D(PDCP, + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, + ctxt.rnti, rab_id, key); + //if (!UE_NAS_USE_TUN) { + // pdcp_data_req( + // &ctxt, + // SRB_FLAG_NO, + // DEFAULT_RAB_ID, + // RLC_MUI_UNDEFINED, + // RLC_SDU_CONFIRM_NO, + // len, + // (unsigned char *)nl_rx_buf, + // PDCP_TRANSMISSION_MODE_TRANSPARENT + // , NULL, NULL + // ); + //} + } + } while (len > 0); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 0 ); + return len; +} + int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctxt_pP) { int len = 1; int rlc_data_req_flag = 3; diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 63c24d6e3c..f9e460e325 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -414,7 +414,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP for (j=0; jlist.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; - if (MBMS_SessionInfo_p->sessionId_r9) + if (0/*MBMS_SessionInfo_p->sessionId_r9*/) mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; else mbms_session_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; @@ -454,7 +454,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP } } - LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id, rb_id, @@ -710,7 +710,7 @@ rlc_union_t* rrc_rlc_add_rlc ( } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); - } + }else if ((sourceL2Id > 0) && (destinationL2Id > 0) ){ key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP); key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, sourceL2Id, destinationL2Id, srb_flagP); From 97bc5e9292f561e60fa36046759d21882d714c2d Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:34:08 +0200 Subject: [PATCH 016/134] Few missing files from previous commit ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/PHY_INTERFACE/IF_Module.h | 2 ++ openair2/PHY_INTERFACE/phy_stub_UE.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index c42ba992c9..d14f478933 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -144,6 +144,8 @@ typedef struct IF_Module_s{ void (*UL_indication)(UL_IND_t *UL_INFO); void (*schedule_response)(Sched_Rsp_t *Sched_INFO); void (*PHY_config_req)(PHY_Config_t* config_INFO); + void (*PHY_config_update_sib2_req)(PHY_Config_t* config_INFO); + void (*PHY_config_update_sib13_req)(PHY_Config_t* config_INFO); uint32_t CC_mask; uint16_t current_frame; uint8_t current_subframe; diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 930387c742..14974c2e15 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -1049,7 +1049,11 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } void phy_config_request(PHY_Config_t *phy_config) { +} +void phy_config_update_sib2_request(PHY_Config_t *phy_config) { +} +void phy_config_update_sib13_request(PHY_Config_t *phy_config) { } uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { return(0);} From 3992eb9e87f57845d6ac8dbf31895768ed584cc8 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:36:09 +0200 Subject: [PATCH 017/134] -MBMS RRC procedures for M2AP -On the fligh MBMS recofiguration for MBSFN, sib13,sib2 and MCCH enabled through M2 interface (MCE) -RRC NAS update for MBMS TUN interfaces configuration -UE RRC modified to handle dynamic SIB2 (MBSFN Subframe Config Lists), SIB13 (MCCH) reconfigurations (TO CAREFULLY BE CHECKED) ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/RRC/LTE/L2_interface.c | 4 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 22 +- openair2/RRC/LTE/rrc_UE.c | 91 +- openair2/RRC/LTE/rrc_eNB.c | 38 + openair2/RRC/LTE/rrc_eNB_M2AP.c | 1312 ++++++++++++++++++++++++++ openair2/RRC/LTE/rrc_eNB_M2AP.h | 115 +++ openair2/RRC/NAS/nas_config.c | 39 + openair2/RRC/NAS/nas_config.h | 14 + 8 files changed, 1615 insertions(+), 20 deletions(-) create mode 100644 openair2/RRC/LTE/rrc_eNB_M2AP.c create mode 100644 openair2/RRC/LTE/rrc_eNB_M2AP.h diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 219c905c42..aea1ff61a1 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -77,7 +77,7 @@ mac_rrc_data_req( carrier = &rrc->carrier[0]; mib = &carrier->mib; - if(Srb_id == BCCH_SI_MBMS){ + if((Srb_id & RAB_OFFSET )== BCCH_SI_MBMS){ if (frameP%4 == 0){ memcpy(&buffer_pP[0], RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS, @@ -208,7 +208,7 @@ mac_rrc_data_req( RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); if (LOG_DEBUGFLAG(DEBUG_RRC)) { - LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); + LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) { LOG_T(RRC,"%x.",buffer_pP[i]); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9303fb79f1..5d824debbe 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -244,7 +244,7 @@ uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_ //TODO additionalNonBMSFNSubframes-r14 INTEGER (0..3) ? //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_BCCH_BCH_Message_MBMS, (void *)mib_fembms); + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_BCH_Message_MBMS, (void *)mib_fembms); //} @@ -602,7 +602,7 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message); + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message); //} enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, @@ -755,8 +755,8 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, LTE_PLMN_IdentityInfo_t PLMN_identity_info[num_plmn]; LTE_MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; asn_enc_rval_t enc_rval; - LTE_SchedulingInfo_t schedulingInfo; - LTE_SIB_Type_t sib_type; + LTE_SchedulingInfo_t schedulingInfo,schedulingInfo2; + LTE_SIB_Type_t sib_type,sib_type2; uint8_t *buffer; LTE_BCCH_DL_SCH_Message_t *bcch_message; @@ -785,6 +785,12 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, memset(PLMN_identity_info,0,num_plmn * sizeof(LTE_PLMN_IdentityInfo_t)); memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_t)); memset(&sib_type,0,sizeof(LTE_SIB_Type_t)); + if(configuration->eMBMS_M2_configured){ + memset(&schedulingInfo2,0,sizeof(LTE_SchedulingInfo_t)); + memset(&sib_type2,0,sizeof(LTE_SIB_Type_t)); + } + + /* as per TS 36.311, up to 6 PLMN_identity_info are allowed in list -> add one by one */ for (int i = 0; i < configuration->num_plmn; ++i) { @@ -882,10 +888,18 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, 7; #endif schedulingInfo.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; + if(configuration->eMBMS_M2_configured){ + schedulingInfo2.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; + } // This is for SIB2/3 sib_type=LTE_SIB_Type_sibType3; ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,&sib_type); ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); + if(configuration->eMBMS_M2_configured){ + sib_type2=LTE_SIB_Type_sibType13_v920; + ASN_SEQUENCE_ADD(&schedulingInfo2.sib_MappingInfo.list,&sib_type2); + ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo2); + } // ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,NULL); #if defined(ENABLE_ITTI) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 85bad0789d..8f0d28cef1 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -4277,7 +4277,7 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2; - new_sib=1; + //new_sib=1; memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(LTE_SystemInformationBlockType2_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib2( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] ); @@ -4362,7 +4362,58 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { } #endif } - } + }else{ + //LOG_W( RRC, "[UE %d] Received new SIB1/SIB2/SIB3 with MBMSs %d\n", ctxt_pP->module_id, ((&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList == NULL ? 0:1) ); + if((&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList != NULL && (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4096) == 0){ + LOG_W( RRC, "[UE %d] Received SIB2 with MBSFN SF Config\n", ctxt_pP->module_id ); + + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(LTE_SystemInformationBlockType2_t) ); + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); + rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,0, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL +#endif +#ifdef CBA + ,0, + 0 +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + NULL, + NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); + + } + } break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 @@ -4516,8 +4567,8 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); - break; } + break; #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -4587,19 +4638,30 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { default: break; } + if (new_sib == 1) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt++; + + if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count) + rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); + + LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus, + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt, + sib1->schedulingInfoList.list.count); + } } - if (new_sib == 1) { - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt++; + //if (new_sib == 1) { + // UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt++; - if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count) - rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); + // if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count) + // rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); - LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus, - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt, - sib1->schedulingInfoList.list.count); - } + // LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", + // UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus, + // UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt, + // sib1->schedulingInfoList.list.count); + //} VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); return 0; @@ -4927,7 +4989,7 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB ctxt_pP->frame, mbsfn_sync_area); return 0; // avoid decoding to prevent memory bloating - } else { + } else if(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State >= RRC_CONNECTED /*|| UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_RECONFIGURED*/){ dec_rval = uper_decode_complete(NULL, &asn_DEF_LTE_MCCH_Message, (void **)&mcch, @@ -5043,7 +5105,8 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f #endif ); - UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1; + if(UE_rrc_inst[ue_mod_idP].Info[eNB_index].State >= RRC_CONNECTED /*|| UE_rrc_inst[ue_mod_idP].Info[eNB_index].State == RRC_RECONFIGURED*/) + UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, UE_rrc_inst[ue_mod_idP].Info[eNB_index].rnti, frameP, 0,eNB_index); // Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function) rrc_pdcp_config_asn1_req(&ctxt, diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d93510ac5d..5ce317a225 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -86,6 +86,7 @@ #include "rrc_eNB_S1AP.h" #include "rrc_eNB_GTPV1U.h" +#include "rrc_eNB_M2AP.h" #include "pdcp.h" #include "gtpv1u_eNB_task.h" @@ -9098,6 +9099,43 @@ void *rrc_enb_process_itti_msg(void *notUsed) { rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); break; + case M2AP_SETUP_RESP: + rrc_eNB_process_M2AP_SETUP_RESP(&ctxt,0/*CC_id*/,ENB_INSTANCE_TO_MODULE_ID(instance),&M2AP_SETUP_RESP(msg_p)); + break; + + case M2AP_MBMS_SCHEDULING_INFORMATION: + rrc_eNB_process_M2AP_MBMS_SCHEDULING_INFORMATION(&ctxt,0/*CC_id*/,ENB_INSTANCE_TO_MODULE_ID(instance),&M2AP_MBMS_SCHEDULING_INFORMATION(msg_p)); + break; + + case M2AP_MBMS_SESSION_START_REQ: + rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ(&ctxt,0/*CC_id*/,ENB_INSTANCE_TO_MODULE_ID(instance),&M2AP_MBMS_SESSION_START_REQ(msg_p)); + break; + + case M2AP_MBMS_SESSION_STOP_REQ: + rrc_eNB_process_M2AP_MBMS_SESSION_STOP_REQ(&ctxt,&M2AP_MBMS_SESSION_STOP_REQ(msg_p)); + break; + + case M2AP_RESET: + rrc_eNB_process_M2AP_RESET(&ctxt,&M2AP_RESET(msg_p)); + break; + + case M2AP_ENB_CONFIGURATION_UPDATE_ACK: + rrc_eNB_process_M2AP_ENB_CONFIGURATION_UPDATE_ACK(&ctxt,&M2AP_ENB_CONFIGURATION_UPDATE_ACK(msg_p)); + break; + + case M2AP_ERROR_INDICATION: + rrc_eNB_process_M2AP_ERROR_INDICATION(&ctxt,&M2AP_ERROR_INDICATION(msg_p)); + break; + + case M2AP_MBMS_SERVICE_COUNTING_REQ: + rrc_eNB_process_M2AP_MBMS_SERVICE_COUNTING_REQ(&ctxt,&M2AP_MBMS_SERVICE_COUNTING_REQ(msg_p)); + break; + + case M2AP_MCE_CONFIGURATION_UPDATE: + rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt,&M2AP_MCE_CONFIGURATION_UPDATE(msg_p)); + break; + + default: LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p); break; diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.c b/openair2/RRC/LTE/rrc_eNB_M2AP.c new file mode 100644 index 0000000000..ac68bbcbcd --- /dev/null +++ b/openair2/RRC/LTE/rrc_eNB_M2AP.c @@ -0,0 +1,1312 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file rrc_eNB_M2AP.c + * \brief rrc M2AP procedures for eNB + * \author Javier Morgade + * \version 0.1 + * \company Vicomtech Spain + * \email: javier.morgade@ieee.org + */ + +# include "rrc_defs.h" +# include "rrc_extern.h" +# include "RRC/LTE/MESSAGES/asn1_msg.h" +# include "rrc_eNB_M2AP.h" +//# include "rrc_eNB_UE_context.h" +# include "msc.h" +# include "asn1_conversions.h" +# include "intertask_interface.h" +# include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + +static m2ap_setup_resp_t * m2ap_setup_resp_g=NULL; +static m2ap_mbms_scheduling_information_t *m2ap_mbms_scheduling_information_g=NULL; + + +static void +rrc_M2AP_openair_rrc_top_init_MBMS(int eMBMS_active){ + module_id_t module_id; + int CC_id; + + (void)CC_id; + LOG_D(RRC, "[OPENAIR][INIT] Init function start: NB_eNB_INST=%d\n", RC.nb_inst); + + if (RC.nb_inst > 0) { +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LOG_I(RRC,"[eNB] eMBMS active state is %d \n", eMBMS_active); + + for (module_id=0; module_idcarrier[CC_id].MBMS_flag = (uint8_t)eMBMS_active; + } + } + +#endif + } +} + + + +static uint8_t rrc_M2AP_do_MBSFNAreaConfig( + uint8_t Mod_id, + uint8_t sync_area, + uint8_t *buffer, + LTE_MCCH_Message_t *mcch_message, + LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +) { + int i,j,k; + + asn_enc_rval_t enc_rval; + LTE_MBSFN_SubframeConfig_t *mbsfn_SubframeConfig1; + LTE_PMCH_Info_r9_t *pmch_Info_1; + LTE_MBMS_SessionInfo_r9_t *mbms_Session_1; + // MBMS_SessionInfo_r9_t *mbms_Session_2; + //eNB_RRC_INST *rrc = RC.rrc[Mod_id]; + //rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0]; + memset(mcch_message,0,sizeof(LTE_MCCH_Message_t)); + mcch_message->message.present = LTE_MCCH_MessageType_PR_c1; + mcch_message->message.choice.c1.present = LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9; + *mbsfnAreaConfiguration = &mcch_message->message.choice.c1.choice.mbsfnAreaConfiguration_r9; + // Common Subframe Allocation (CommonSF-Alloc-r9) + + for(i=0; inum_mbms_area_config_list; i++){ + for(j=0;j < m2ap_mbms_scheduling_information->mbms_area_config_list[i].num_mbms_sf_config_list; j++){ + + mbsfn_SubframeConfig1= CALLOC(1,sizeof(*mbsfn_SubframeConfig1)); + memset((void *)mbsfn_SubframeConfig1,0,sizeof(*mbsfn_SubframeConfig1)); + // + mbsfn_SubframeConfig1->radioframeAllocationPeriod= m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period;//LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; + mbsfn_SubframeConfig1->radioframeAllocationOffset= m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset; + if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){ + mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF); + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF); + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation>>16) & 0xFF); + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3; + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0; + + + }else { + mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = (m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation & 0x3F)<<2; + } + + ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->commonSF_Alloc_r9.list,mbsfn_SubframeConfig1); + } + // commonSF-AllocPeriod-r9 + (*mbsfnAreaConfiguration)->commonSF_AllocPeriod_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].common_sf_allocation_period;//LTE_MBSFNAreaConfiguration_r9__commonSF_AllocPeriod_r9_rf16; + // PMCHs Information List (PMCH-InfoList-r9) + for(j=0; j < m2ap_mbms_scheduling_information->mbms_area_config_list[i].num_pmch_config_list; j++){ + // PMCH_1 Config + pmch_Info_1 = CALLOC(1,sizeof(LTE_PMCH_Info_r9_t)); + memset((void *)pmch_Info_1,0,sizeof(LTE_PMCH_Info_r9_t)); + /* + * take the value of last mbsfn subframe in this CSA period because there is only one PMCH in this mbsfn area + * Note: this has to be set based on the subframeAllocation and CSA + */ + pmch_Info_1->pmch_Config_r9.sf_AllocEnd_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end; + pmch_Info_1->pmch_Config_r9.dataMCS_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].data_mcs; + pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; + // MBMSs-SessionInfoList-r9 + for(k=0; k < m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list; k++){ + // pmch_Info_1->mbms_SessionInfoList_r9 = CALLOC(1,sizeof(struct MBMS_SessionInfoList_r9)); + // Session 1 + mbms_Session_1 = CALLOC(1,sizeof(LTE_MBMS_SessionInfo_r9_t)); + memset(mbms_Session_1,0,sizeof(LTE_MBMS_SessionInfo_r9_t)); + // TMGI value + mbms_Session_1->tmgi_r9.plmn_Id_r9.present= LTE_TMGI_r9__plmn_Id_r9_PR_plmn_Index_r9; + mbms_Session_1->tmgi_r9.plmn_Id_r9.choice.plmn_Index_r9= 1; + // Service ID + //uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 10.5.4a + char buf[4]; + buf[0] = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id << 24; + buf[1] = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id << 16; + buf[2] = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id << 8; + buf[3] = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id << 0; + //INT32_TO_BUFFER(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id,buf); + memset(&mbms_Session_1->tmgi_r9.serviceId_r9,0,sizeof(OCTET_STRING_t));// need to check + OCTET_STRING_fromBuf(&mbms_Session_1->tmgi_r9.serviceId_r9,(const char *)&buf[1],3); + // Session ID is still missing here, it can be used as an rab id or mrb id + mbms_Session_1->sessionId_r9 = CALLOC(1,sizeof(OCTET_STRING_t)); + mbms_Session_1->sessionId_r9->buf= MALLOC(1); + mbms_Session_1->sessionId_r9->size= 1; + mbms_Session_1->sessionId_r9->buf[0]= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id; //1; + // Logical Channel ID + mbms_Session_1->logicalChannelIdentity_r9=m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid; //1; + LOG_D(RRC,"lcid %lu %d\n",mbms_Session_1->logicalChannelIdentity_r9,m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid); + LOG_D(RRC,"service_id %d\n",m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id); + ASN_SEQUENCE_ADD(&pmch_Info_1->mbms_SessionInfoList_r9.list,mbms_Session_1); + } + ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->pmch_InfoList_r9.list,pmch_Info_1); + } + } + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void *)mcch_message); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_MCCH_Message, + NULL, + (void *)mcch_message, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_I(RRC,"[eNB] MCCH Message Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : MCCH encoding failed for MBSFNAreaConfiguration\n"); + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} + +static void rrc_M2AP_init_MBMS( + module_id_t enb_mod_idP, + int CC_id, + frame_t frameP +){ + // init the configuration for MTCH + protocol_ctxt_t ctxt; + + if (RC.rrc[enb_mod_idP]->carrier[CC_id].MBMS_flag > 0) { + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,enb_mod_idP); + LOG_I(RRC, "[eNB %d] Frame %d : Radio Bearer config request for MBMS\n", enb_mod_idP, frameP); //check the lcid + // Configuring PDCP and RLC for MBMS Radio Bearer + rrc_pdcp_config_asn1_req(&ctxt, + (LTE_SRB_ToAddModList_t *)NULL, // LTE_SRB_ToAddModList + (LTE_DRB_ToAddModList_t *)NULL, // LTE_DRB_ToAddModList + (LTE_DRB_ToReleaseList_t *)NULL, + 0, // security mode + NULL, // key rrc encryption + NULL, // key rrc integrity + NULL // key encryption + , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) + ,NULL); + + if (!NODE_IS_CU(RC.rrc[enb_mod_idP]->node_type)) { + rrc_rlc_config_asn1_req(&ctxt, + NULL, // LTE_SRB_ToAddModList + NULL, // LTE_DRB_ToAddModList + NULL, // DRB_ToReleaseList + &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 +#endif + ); + } + //rrc_mac_config_req(); + } +} + + +static void rrc_M2AP_init_MCCH( + const protocol_ctxt_t *const ctxt_pP, + uint8_t enb_mod_idP, + int CC_id, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +){ + + int sync_area = 0; + // initialize RRC_eNB_INST MCCH entry + eNB_RRC_INST *rrc = RC.rrc[enb_mod_idP]; + + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE = + malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *)); + + for (sync_area = 0; sync_area < RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area; sync_area++) { + RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = 0; + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] = (uint8_t *) malloc16(32); + AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] != NULL, + "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP); + RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = rrc_M2AP_do_MBSFNAreaConfig(enb_mod_idP, + sync_area, + (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], + &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch, + &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message, + m2ap_mbms_scheduling_information + ); + LOG_I(RRC, "mcch message pointer %p for sync area %d \n", + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], + sync_area); + LOG_D(RRC, "[eNB %d] MCCH_MESSAGE contents for Sync Area %d (partial)\n", enb_mod_idP, sync_area); + LOG_D(RRC, "[eNB %d] CommonSF_AllocPeriod_r9 %ld\n", enb_mod_idP, + RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_AllocPeriod_r9); + LOG_D(RRC, + "[eNB %d] CommonSF_Alloc_r9.list.count (number of MBSFN Subframe Pattern) %d\n", + enb_mod_idP, RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.count); + LOG_D(RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n", + enb_mod_idP, + RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.array[0]->subframeAllocation. + choice.oneFrame.buf[0]); + AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255, + "RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255"); + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1; + } + + + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + rrc_mac_config_req_eNB(enb_mod_idP, CC_id, + 0,0,0,0,0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + 0,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + , + 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL +#endif + ); + } + + return; +} +//static uint8_t rrc_M2AP_do_SIB1( +// const protocol_ctxt_t *const ctxt_pP, +// uint8_t Mod_id, +// int CC_id, +// const m2ap_setup_resp_t *const m2ap_setup_resp, +// const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +//){ +// int i/*,j,l*/; +// +// //eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; +// //rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; +// +// asn_enc_rval_t enc_rval; +// +// uint8_t *buffer; +// +// LTE_SystemInformationBlockType1_t **sib1; +// +// LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; +// +//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +// if (ctxt_pP->brOption) { +// buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB1_BR; +// bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].siblock1_BR; +// sib1 = &RC.rrc[Mod_id]->carrier[CC_id].sib1_BR; +// } +// else +//#endif +// { +// buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB1; +// bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].siblock1; +// sib1 = &RC.rrc[Mod_id]->carrier[CC_id].sib1; +// } +// +// *sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1; +// +// uint8_t find_sib13=0; +// for(i=0; i<(*sib1)->schedulingInfoList.list.count; i++){ +// //for(j=0; j<(*sib1)->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count;j++) +// // if((*sib1)->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[j] == LTE_SIB_Type_sibType13_v920) +// // find_sib13=1; +// } +// if(!find_sib13){ +// LTE_SchedulingInfo_t schedulingInfo; +// LTE_SIB_Type_t sib_type; +// memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_t)); +// memset(&sib_type,0,sizeof(LTE_SIB_Type_t)); +// +// schedulingInfo.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; +// sib_type=LTE_SIB_Type_sibType13_v920; +// ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); +// } +// +// enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, +// NULL, +// (void *)bcch_message, +// buffer, +// 900); +// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", +// enc_rval.failed_type->name, enc_rval.encoded); +// LOG_W(RRC,"[eNB] SystemInformationBlockType1 Encoded %zd bits (%zd bytes) with new SIB13(%d) \n",enc_rval.encoded,(enc_rval.encoded+7)/8,find_sib13); +// +// +// RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = ((enc_rval.encoded+7)/8); +// +// +// +// +// return 0; +//} + + + +static uint8_t rrc_M2AP_do_SIB23_SIB2( + const protocol_ctxt_t *const ctxt_pP, + uint8_t Mod_id, + int CC_id, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +){ + + int i,j,l; + + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; + rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + //struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; + LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList/*,*MBSFNSubframeConfigList_copy*/; + //LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list/*,*MBSFNArea_list_copy*/; +#endif + + asn_enc_rval_t enc_rval; + + LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; + uint8_t *buffer; + LTE_SystemInformationBlockType2_t **sib2; + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(ctxt_pP->brOption){ + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; + LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); + + }else +#endif + { + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; + } + + + + if (bcch_message) { + //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); + } else { + LOG_E(RRC,"[eNB %d] BCCH_MESSAGE is null, exiting\n", Mod_id); + exit(-1); + } + + if (!sib2) { + LOG_E(RRC,"[eNB %d] sib2 is null, exiting\n", Mod_id); + exit(-1); + } + + //if (!sib3) { + // LOG_E(RRC,"[eNB %d] sib3 is null, exiting\n", Mod_id); + // exit(-1); + //} + + for (i=0; i < bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; + switch(typeandinfo->present) { + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_NOTHING: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib14_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib15_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib16_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib17_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib20_v1310: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + + LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2); + + for(j=0; j < m2ap_mbms_scheduling_information->num_mbms_area_config_list ; j++) { + + (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList)); + MBSFNSubframeConfigList = (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList; + + for(l=0; l < m2ap_mbms_scheduling_information->mbms_area_config_list[j].num_mbms_sf_config_list; l++){ + LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; + sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1)); + memset((void *)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); + + sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_period; + sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_offset; + + + if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){ + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; + + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF); + + }else{ + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation<<2); + + + } + + ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1); + } + } + + break; + + } + } + + + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, + NULL, + (void *)bcch_message, + buffer, + 900); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + LOG_I(RRC,"[eNB] MBMS SIB2 SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI encoding failed for SIB23\n"); + return(-1); + } + + carrier->MBMS_flag =1; + + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, + 0,0,0,0,0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + 0,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, + (LTE_AdditionalSpectrumEmission_t *)NULL, + (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList, + carrier->MBMS_flag, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL +#endif + ); + } + + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = ((enc_rval.encoded+7)/8); + + return 0; +} + +static uint8_t rrc_M2AP_do_SIB23_SIB13( + const protocol_ctxt_t *const ctxt_pP, + uint8_t Mod_id, + int CC_id, + const m2ap_setup_resp_t *const m2ap_setup_resp +){ + + int i; + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; + rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; + //LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; + LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list; +#endif + + asn_enc_rval_t enc_rval; + + LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; + uint8_t *buffer; + LTE_SystemInformationBlockType2_t **sib2; + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(ctxt_pP->brOption){ + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; + LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); + + }else +#endif + { + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; + } + + + + if (bcch_message) { + //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); + } else { + LOG_E(RRC,"[eNB %d] BCCH_MESSAGE is null, exiting\n", Mod_id); + exit(-1); + } + + if (!sib2) { + LOG_E(RRC,"[eNB %d] sib2 is null, exiting\n", Mod_id); + exit(-1); + } + + //if (!sib3) { + // LOG_E(RRC,"[eNB %d] sib3 is null, exiting\n", Mod_id); + // exit(-1); + //} + + /*for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; + switch(typeandinfo->present) { + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + LTE_SystemInformationBlockType2_t *sib2 = &typeandinfo->choice.sib2 + LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2\n"); + LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; + (*sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList)); + MBSFNSubframeConfigList = (*sib2)->mbsfn_SubframeConfigList; + sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1)); + memset((void *)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); + sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; + sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset= 1; + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x38<<2; + + ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1); + + + break; + + } + }*/ + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; +#endif + + struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1/*, *MBSFN_Area2*/; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; + + *sib13 = &sib13_part->choice.sib13_v920; +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + (*sib13)->notificationConfig_r9.notificationOffset_r9=0; + (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; + + // MBSFN-AreaInfoList + MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list)); + memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); + +for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ + // MBSFN Area 1 + MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); + MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mbsfn_area; + MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[i].pdcch_length; + MBSFN_Area1->notificationIndicator_r9= 0; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].offset; // in accordance with mbsfn subframe configuration in sib2 + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].modification_period; + + // Subframe Allocation Info + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info<<2; // FDD: SF1 + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs; + ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); + } +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib13_part); +#endif + + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, + NULL, + (void *)bcch_message, + buffer, + 900); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + LOG_I(RRC,"[eNB] MBMS SIB13 SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI encoding failed for SIB23\n"); + return(-1); + } + + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, + 0,0,0,0,0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + 0,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + , + 0, + (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL +#endif + ); + } + + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = ((enc_rval.encoded+7)/8); + + return 0; +} + + + +static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( + const protocol_ctxt_t *const ctxt_pP, + uint8_t Mod_id, + int CC_id, + const m2ap_setup_resp_t *const m2ap_setup_resp, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +){ + + int i,j,l; + + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; + rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; + LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList/*,*MBSFNSubframeConfigList_copy*/; +#endif + + asn_enc_rval_t enc_rval; + + LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; + uint8_t *buffer; + LTE_SystemInformationBlockType2_t **sib2; + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list/*,*MBSFNArea_list_copy*/; + LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; + struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1; +#endif + + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(ctxt_pP->brOption){ + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; + LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); + + }else +#endif + { + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; + } + + + + if (bcch_message) { + //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); + } else { + LOG_E(RRC,"[eNB %d] BCCH_MESSAGE is null, exiting\n", Mod_id); + exit(-1); + } + + if (!sib2) { + LOG_E(RRC,"[eNB %d] sib2 is null, exiting\n", Mod_id); + exit(-1); + } + + if(!sib13){ + LOG_I(RRC,"[eNB %d] sib13 is null, it should get created\n",Mod_id); + } + + //if (!sib3) { + // LOG_E(RRC,"[eNB %d] sib3 is null, exiting\n", Mod_id); + // exit(-1); + //} + + for (i=0; i < bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; + switch(typeandinfo->present) { + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_NOTHING: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: + *sib13=&typeandinfo->choice.sib13_v920; +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + (*sib13)->notificationConfig_r9.notificationOffset_r9=0; + (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; + // MBSFN-AreaInfoList + MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list)); + memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); + + for( j=0; j < m2ap_setup_resp->num_mcch_config_per_mbsfn; j++){ + // MBSFN Area 1 + MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); + MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mbsfn_area; + MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[j].pdcch_length; + MBSFN_Area1->notificationIndicator_r9= 0; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].offset; // in accordance with mbsfn subframe configuration in sib2 + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].modification_period; + + // Subframe Allocation Info + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[j].subframe_allocation_info<<2; // FDD: SF1 + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mcs; + ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); + } +#endif + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib14_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib15_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib16_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib17_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib20_v1310: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + + LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2); + + for(j=0; j < m2ap_mbms_scheduling_information->num_mbms_area_config_list ; j++) { + + (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList)); + MBSFNSubframeConfigList = (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList; + + for(l=0; l < m2ap_mbms_scheduling_information->mbms_area_config_list[j].num_mbms_sf_config_list; l++){ + LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; + sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1)); + memset((void *)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); + + sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_period; + sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_offset; + + + if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){ + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; + + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF); + + }else{ + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation<<2); + + + } + + ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1); + } + } + + break; + + } + } + + if(*sib13==NULL){ +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; + + *sib13 = &sib13_part->choice.sib13_v920; +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + (*sib13)->notificationConfig_r9.notificationOffset_r9=0; + (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; + + // MBSFN-AreaInfoList + MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list)); + memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); + + for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ + // MBSFN Area 1 + MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); + MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mbsfn_area; + MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[i].pdcch_length; + MBSFN_Area1->notificationIndicator_r9= 0; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].offset; // in accordance with mbsfn subframe configuration in sib2 + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].modification_period; + + // Subframe Allocation Info + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info<<2; // FDD: SF1 + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs; + ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); + } +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib13_part); +#endif + + } + + + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, + NULL, + (void *)bcch_message, + buffer, + 900); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + LOG_I(RRC,"[eNB] MBMS SIB2 SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI encoding failed for SIB23\n"); + return(-1); + } + + carrier->MBMS_flag =1; + + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, + 0,0,0,0,0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + 0,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, + (LTE_AdditionalSpectrumEmission_t *)NULL, + (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList, + carrier->MBMS_flag, + (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL +#endif + ); + } + + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = ((enc_rval.encoded+7)/8); + + return 0; +} + + +int +rrc_eNB_process_M2AP_SETUP_RESP( + const protocol_ctxt_t *const ctxt_pP, + int CC_id, + instance_t instance, + const m2ap_setup_resp_t *const m2ap_setup_resp +) +{ + //protocol_ctxt_t ctxt; + //LOG_W(RRC,"instance %d\n",instance); + + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[0].SIB23 != NULL,"Memory fo SIB23 not allocated"); + AssertFatal(m2ap_setup_resp != NULL, "m2ap_setup_resp memory not allocated"); + + + pthread_mutex_lock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); + //RC.rrc[ctxt_pP->module_id]->carrier[CC_id].num_mbsfn_sync_area = m2ap_setup_resp->num_mcch_config_per_mbsfn; + //rrc_M2AP_do_SIB23_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp); + m2ap_setup_resp_g = (m2ap_setup_resp_t*)calloc(1,sizeof(m2ap_setup_resp_t)); + memcpy(m2ap_setup_resp_g,m2ap_setup_resp,sizeof(m2ap_setup_resp_t)); + pthread_mutex_unlock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); + + return 0; +} + + +int +rrc_eNB_process_M2AP_MBMS_SCHEDULING_INFORMATION( + const protocol_ctxt_t *const ctxt_pP, + int CC_id, + instance_t instance, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +) +{ + //protocol_ctxt_t ctxt; + //LOG_W(RRC,"instance %d\n",instance); + + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[0].SIB23 != NULL,"Memory fo SIB23 not allocated"); + AssertFatal(m2ap_mbms_scheduling_information != NULL, "m2ap_mbms_scheduling_information memory not allocated"); + + //RC.rrc[ctxt_pP->module_id]->carrier[CC_id].num_mbsfn_sync_area = m2ap_setup_resp->num_mcch_config_per_mbsfn; + + pthread_mutex_lock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); + m2ap_mbms_scheduling_information_g = (m2ap_mbms_scheduling_information_t*)calloc(1,sizeof(m2ap_mbms_scheduling_information_t)); + memcpy(m2ap_mbms_scheduling_information_g,m2ap_mbms_scheduling_information,sizeof(m2ap_mbms_scheduling_information_t)); + + /*if(m2ap_setup_resp_g != NULL){ + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].num_mbsfn_sync_area = m2ap_setup_resp_g->num_mcch_config_per_mbsfn; + rrc_M2AP_do_SIB23_SIB2(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information); + rrc_M2AP_do_SIB23_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g); + rrc_M2AP_init_MCCH(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information); + rrc_M2AP_init_MBMS(ctxt_pP->module_id, CC_id, 0); + rrc_M2AP_openair_rrc_top_init_MBMS(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag); + }*/ + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + pthread_mutex_unlock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); + + + return 0; +} + +int +rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ( + const protocol_ctxt_t *const ctxt_pP, + int CC_id, + instance_t instance, + const m2ap_session_start_req_t *const m2ap_mbms_session_start_req +) +{ + int split_cfg=0; + pthread_mutex_lock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); + if(m2ap_setup_resp_g != NULL && m2ap_mbms_scheduling_information_g !=NULL ){ + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].num_mbsfn_sync_area = m2ap_setup_resp_g->num_mcch_config_per_mbsfn; + + //rrc_M2AP_do_SIB1(ctxt_pP,ctxt_pP->module_id,CC_id,NULL,NULL); + if(split_cfg){ + rrc_M2AP_do_SIB23_SIB2(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information_g); + rrc_M2AP_do_SIB23_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g); + }else{ + rrc_M2AP_do_SIB23_SIB2_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g); + } + rrc_M2AP_init_MCCH(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information_g); + rrc_M2AP_init_MBMS(ctxt_pP->module_id, CC_id, 0); + rrc_M2AP_openair_rrc_top_init_MBMS(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag); + } + pthread_mutex_unlock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); + + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_START_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} + +int +rrc_eNB_process_M2AP_MBMS_SESSION_STOP_REQ( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_session_stop_req_t *const m2ap_session_stop_req +) +{ + return 0; +} + +int +rrc_eNB_process_M2AP_RESET( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_reset_t *const m2ap_reset +) +{ + return 0; +} + +int +rrc_eNB_process_M2AP_ENB_CONFIGURATION_UPDATE_ACK( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_enb_configuration_update_ack_t *const m2ap_enb_configuration_update_ack +) +{ + return 0; +} + +int +rrc_eNB_process_M2AP_ERROR_INDICATION( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_error_indication_t *const m2ap_error_indication +) +{ + return 0; +} + +int +rrc_eNB_process_M2AP_MBMS_SERVICE_COUNTING_REQ( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_mbms_service_counting_req_t *const m2ap_mbms_service_counting_req +) +{ + return 0; +} + +int +rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_mce_configuration_update_t *const m2ap_mce_configuration_update +) +{ + return 0; +} + + + +void rrc_eNB_send_M2AP_MBMS_SCHEDULING_INFORMATION_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +) +{ + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); +} + +void rrc_eNB_send_M2AP_MBMS_SESSION_START_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +) +{ + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_START_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); +} + +void rrc_eNB_send_M2AP_MBMS_SESSION_STOP_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +) +{ + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_STOP_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); +} + +void rrc_eNB_send_M2AP_MBMS_SESSION_UPDATE_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +) +{ + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_UPDATE_RESP); + itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); +} diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.h b/openair2/RRC/LTE/rrc_eNB_M2AP.h new file mode 100644 index 0000000000..3b95aafb11 --- /dev/null +++ b/openair2/RRC/LTE/rrc_eNB_M2AP.h @@ -0,0 +1,115 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file rrc_eNB_M2AP.h + * \brief rrc M2AP procedures for eNB + * \author Javier Morgade + * \version 0.1 + * \company Vicomtech, Spain + * \email: javier.morgade@ieee.org + */ + +#ifndef RRC_ENB_M2AP_H_ +#define RRC_ENB_M2AP_H_ + + +int +rrc_eNB_process_M2AP_SETUP_RESP( + const protocol_ctxt_t *const ctxt_pP, + int CC_id, + instance_t instance, + const m2ap_setup_resp_t *const m2ap_setup_resp +); + +int +rrc_eNB_process_M2AP_MBMS_SCHEDULING_INFORMATION( + const protocol_ctxt_t *const ctxt_pP, + int CC_id, + instance_t instance, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +); + +int +rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ( + const protocol_ctxt_t *const ctxt_pP, + int CC_id, + instance_t instance, + const m2ap_session_start_req_t *const m2ap_session_start_req +); + +int +rrc_eNB_process_M2AP_MBMS_SESSION_STOP_REQ( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_session_stop_req_t *const m2ap_session_stop_req +); + +int +rrc_eNB_process_M2AP_RESET( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_reset_t *const m2ap_reset +); + +int +rrc_eNB_process_M2AP_ENB_CONFIGURATION_UPDATE_ACK( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_enb_configuration_update_ack_t *const m2ap_enb_configuration_update_ack +); + +int +rrc_eNB_process_M2AP_ERROR_INDICATION( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_error_indication_t *const m2ap_error_indication +); + +int +rrc_eNB_process_M2AP_MBMS_SERVICE_COUNTING_REQ( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_mbms_service_counting_req_t *const m2ap_mbms_service_counting_req +); + +int +rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE( + const protocol_ctxt_t *const ctxt_pP, + const m2ap_mce_configuration_update_t *const m2ap_mce_configuration_update +); + + +void rrc_eNB_send_M2AP_MBMS_SCHEDULING_INFORMATION_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +); + +void rrc_eNB_send_M2AP_MBMS_SESSION_START_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +); + +void rrc_eNB_send_M2AP_MBMS_SESSION_STOP_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +); + +void rrc_eNB_send_M2AP_MBMS_SESSION_UPDATE_RESP( + const protocol_ctxt_t *const ctxt_pP + //,const rrc_eNB_mbms_context_t *const rrc_eNB_mbms_context +); + +#endif /* RRC_ENB_M2AP_H_ */ diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index aa6696c864..fa9799c177 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -230,6 +230,45 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br return returnValue; } +int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { + //char buf[5]; + char ipAddress[20]; + char broadcastAddress[20]; + char interfaceName[20]; + int returnValue; + //if(strcmp(ifname,"ue") == 0) + //sprintf(ipAddress, "%s.%d.%d", "20.0",thirdOctet,fourthOctet); + ////else + sprintf(ipAddress, "%s.%d.%d",baseNetAddress,thirdOctet,fourthOctet); + + sprintf(broadcastAddress, "%s.%d.255",baseNetAddress, thirdOctet); + sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname, + UE_NAS_USE_TUN?ifname/*"ue"*/: (ENB_NAS_USE_TUN?ifname/*"enb"*/:""),interface_id); + bringInterfaceUp(interfaceName, 0); + // sets the machine address + returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR); + + // sets the machine network mask + if(!returnValue) + returnValue= setInterfaceParameter(interfaceName, netMask,SIOCSIFNETMASK); + + // sets the machine broadcast address + if(!returnValue) + returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR); + + if(!returnValue) + bringInterfaceUp(interfaceName, 1); + + if(!returnValue) + LOG_I(OIP,"Interface %s successfuly configured, ip address %s, mask %s broadcast address %s\n", + interfaceName, ipAddress, netMask, broadcastAddress); + else + LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n", + interfaceName, ipAddress, netMask, broadcastAddress); + + return returnValue; +} + // non blocking full configuration of the interface (address, and the two lest octets of the address) int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { //char buf[5]; diff --git a/openair2/RRC/NAS/nas_config.h b/openair2/RRC/NAS/nas_config.h index fdc3c98f1b..9c7945107d 100644 --- a/openair2/RRC/NAS/nas_config.h +++ b/openair2/RRC/NAS/nas_config.h @@ -63,6 +63,20 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br */ int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix); +/*! \fn int nas_config_mbms(char*, int, int) + * \brief This function initializes the nasmesh interface using the basic values, + * basic address, network mask and broadcast address, as the default configured + * ones + * \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1 + * \param[in] third octet of the ip address e.g. for the 10.1.2.3 address would be 2 + * \param[in] fourth octet of the ip address e.g. for the 10.1.2.3 address would be 3 + * \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails + * \note + * @ingroup ????? + */ +int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix); + + /*! \fn int blocking_NAS_config(char*, char*, char*, char*) * \brief This function initializes the nasmesh interface, in a blocking way, * the system calls are interrupted From ab04e0e469f48d03f1d299fa50fdd382dcf720b2 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:45:27 +0200 Subject: [PATCH 018/134] M2AP 3GPP TS 36.443 interface implemented: 1.MCE (Multicast Control Entity) entity developed (new dedicated task developed: TASK_MCE_APP) 2.eNB side M2 interface procedures (new dedicated task developed: TASK_M2AP_ENB) 3.MCE side M2 interface procedures (new dedicated task developed: TASK_M2AP_MCE) 4.ASN1 bindings for m2ap-14.0.0.asn1 implemented and tested 5.MCE config parameters ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/M2AP/m2ap_MCE.c | 733 +++++++ openair2/M2AP/m2ap_MCE.h | 55 + openair2/M2AP/m2ap_MCE_defs.h | 210 ++ openair2/M2AP/m2ap_MCE_generate_messages.c | 804 +++++++ openair2/M2AP/m2ap_MCE_generate_messages.h | 63 + openair2/M2AP/m2ap_MCE_handler.c | 123 ++ openair2/M2AP/m2ap_MCE_handler.h | 43 + openair2/M2AP/m2ap_MCE_interface_management.c | 1905 +++++++++++++++++ openair2/M2AP/m2ap_MCE_interface_management.h | 196 ++ .../M2AP/m2ap_MCE_management_procedures.c | 257 +++ .../M2AP/m2ap_MCE_management_procedures.h | 54 + openair2/M2AP/m2ap_common.h | 7 - openair2/M2AP/m2ap_decoder.c | 194 ++ openair2/M2AP/m2ap_decoder.h | 35 + openair2/M2AP/m2ap_default_values.h | 47 + openair2/M2AP/m2ap_eNB.c | 704 ++++++ openair2/M2AP/m2ap_eNB.h | 55 + openair2/M2AP/m2ap_eNB_defs.h | 221 ++ openair2/M2AP/m2ap_eNB_generate_messages.c | 808 +++++++ openair2/M2AP/m2ap_eNB_generate_messages.h | 63 + openair2/M2AP/m2ap_eNB_handler.c | 123 ++ openair2/M2AP/m2ap_eNB_handler.h | 43 + openair2/M2AP/m2ap_eNB_interface_management.c | 1385 ++++++++++++ openair2/M2AP/m2ap_eNB_interface_management.h | 173 ++ .../M2AP/m2ap_eNB_management_procedures.c | 257 +++ .../M2AP/m2ap_eNB_management_procedures.h | 54 + openair2/M2AP/m2ap_encoder.c | 61 + openair2/M2AP/m2ap_encoder.h | 35 + openair2/M2AP/m2ap_handler.c | 123 ++ openair2/M2AP/m2ap_handler.h | 43 + openair2/M2AP/m2ap_ids.c | 128 ++ openair2/M2AP/m2ap_ids.h | 80 + openair2/M2AP/m2ap_itti_messaging.c | 96 + openair2/M2AP/m2ap_itti_messaging.h | 48 + openair2/M2AP/m2ap_timers.c | 105 + openair2/M2AP/m2ap_timers.h | 45 + openair2/MCE_APP/mce_app.c | 754 +++++++ openair2/MCE_APP/mce_app.h | 41 + openair2/MCE_APP/mce_config.c | 512 +++++ openair2/MCE_APP/mce_config.h | 71 + 40 files changed, 10747 insertions(+), 7 deletions(-) create mode 100644 openair2/M2AP/m2ap_MCE.c create mode 100644 openair2/M2AP/m2ap_MCE.h create mode 100644 openair2/M2AP/m2ap_MCE_defs.h create mode 100644 openair2/M2AP/m2ap_MCE_generate_messages.c create mode 100644 openair2/M2AP/m2ap_MCE_generate_messages.h create mode 100644 openair2/M2AP/m2ap_MCE_handler.c create mode 100644 openair2/M2AP/m2ap_MCE_handler.h create mode 100644 openair2/M2AP/m2ap_MCE_interface_management.c create mode 100644 openair2/M2AP/m2ap_MCE_interface_management.h create mode 100644 openair2/M2AP/m2ap_MCE_management_procedures.c create mode 100644 openair2/M2AP/m2ap_MCE_management_procedures.h create mode 100644 openair2/M2AP/m2ap_decoder.c create mode 100644 openair2/M2AP/m2ap_decoder.h create mode 100644 openair2/M2AP/m2ap_default_values.h create mode 100644 openair2/M2AP/m2ap_eNB.c create mode 100644 openair2/M2AP/m2ap_eNB.h create mode 100644 openair2/M2AP/m2ap_eNB_defs.h create mode 100644 openair2/M2AP/m2ap_eNB_generate_messages.c create mode 100644 openair2/M2AP/m2ap_eNB_generate_messages.h create mode 100644 openair2/M2AP/m2ap_eNB_handler.c create mode 100644 openair2/M2AP/m2ap_eNB_handler.h create mode 100644 openair2/M2AP/m2ap_eNB_interface_management.c create mode 100644 openair2/M2AP/m2ap_eNB_interface_management.h create mode 100644 openair2/M2AP/m2ap_eNB_management_procedures.c create mode 100644 openair2/M2AP/m2ap_eNB_management_procedures.h create mode 100644 openair2/M2AP/m2ap_encoder.c create mode 100644 openair2/M2AP/m2ap_encoder.h create mode 100644 openair2/M2AP/m2ap_handler.c create mode 100644 openair2/M2AP/m2ap_handler.h create mode 100644 openair2/M2AP/m2ap_ids.c create mode 100644 openair2/M2AP/m2ap_ids.h create mode 100644 openair2/M2AP/m2ap_itti_messaging.c create mode 100644 openair2/M2AP/m2ap_itti_messaging.h create mode 100644 openair2/M2AP/m2ap_timers.c create mode 100644 openair2/M2AP/m2ap_timers.h create mode 100644 openair2/MCE_APP/mce_app.c create mode 100644 openair2/MCE_APP/mce_app.h create mode 100644 openair2/MCE_APP/mce_config.c create mode 100644 openair2/MCE_APP/mce_config.h diff --git a/openair2/M2AP/m2ap_MCE.c b/openair2/M2AP/m2ap_MCE.c new file mode 100644 index 0000000000..096f3cabee --- /dev/null +++ b/openair2/M2AP/m2ap_MCE.c @@ -0,0 +1,733 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE.c + * \brief m2ap tasks for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include +#include +#include + +#include "intertask_interface.h" + +#include "m2ap_MCE.h" +#include "m2ap_MCE_defs.h" +#include "m2ap_MCE_management_procedures.h" +#include "m2ap_MCE_handler.h" +#include "m2ap_MCE_generate_messages.h" +#include "m2ap_common.h" +#include "m2ap_MCE_interface_management.h" +#include "m2ap_ids.h" +#include "m2ap_timers.h" + +#include "queue.h" +#include "assertions.h" +#include "conversions.h" + +struct m2ap_mce_map; +struct m2ap_MCE_data_s; + +m2ap_setup_req_t *m2ap_mce_data_from_enb; + +RB_PROTOTYPE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id); + +static +void m2ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); + +static +void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +static +void m2ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind); + +static +void m2ap_MCE_handle_register_MCE(instance_t instance, + m2ap_register_mce_req_t *m2ap_register_MCE); +static +void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p, + net_ip_address_t *target_MCE_ip_addr, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t mce_port_for_M2C, + int multi_sd); + +//static +//void m2ap_MCE_handle_handover_req(instance_t instance, +// m2ap_handover_req_t *m2ap_handover_req); +// +//static +//void m2ap_MCE_handle_handover_req_ack(instance_t instance, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack); +// +//static +//void m2ap_MCE_ue_context_release(instance_t instance, +// m2ap_ue_context_release_t *m2ap_ue_context_release); +// + +static +void m2ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { + int result; + DevAssert(sctp_data_ind != NULL); + m2ap_MCE_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + +static +void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + + DevAssert(sctp_new_association_resp != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + LOG_W(M2AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + + if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN) + //proto_agent_stop(instance); + //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; // exit -1 for debugging + } + + // go to an init func + m2ap_mce_data_from_enb = (m2ap_setup_req_t *)calloc(1, sizeof(m2ap_setup_req_t)); + // save the assoc id + m2ap_mce_data_from_enb->assoc_id = sctp_new_association_resp->assoc_id; + m2ap_mce_data_from_enb->sctp_in_streams = sctp_new_association_resp->in_streams; + m2ap_mce_data_from_enb->sctp_out_streams = sctp_new_association_resp->out_streams; + + + + // m2ap_MCE_instance_t *instance_p; + // m2ap_MCE_data_t *m2ap_mce_data_p; + // DevAssert(sctp_new_association_resp != NULL); + // printf("m2ap_MCE_handle_sctp_association_resp at 1\n"); + // dump_mce_trees_m2(); + // instance_p = instance;//m2ap_MCE_get_instance(instance); + // DevAssert(instance_p != NULL); + + // /* if the assoc_id is already known, it is certainly because an IND was received + // * before. In this case, just update streams and return + // */ + // if (sctp_new_association_resp->assoc_id != -1) { + // m2ap_mce_data_p = m2ap_get_MCE(instance_p, sctp_new_association_resp->assoc_id, + // sctp_new_association_resp->ulp_cnx_id); + + // if (m2ap_mce_data_p != NULL) { + // /* some sanity check - to be refined at some point */ + // if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + // M2AP_ERROR("m2ap_mce_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); + // abort(); + // } + + // m2ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams; + // m2ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams; + // return; + // } + // } + + // m2ap_mce_data_p = m2ap_get_MCE(instance_p, -1, + // sctp_new_association_resp->ulp_cnx_id); + // DevAssert(m2ap_mce_data_p != NULL); + // printf("m2ap_MCE_handle_sctp_association_resp at 2\n"); + // dump_mce_trees_m2(); + + // if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + // M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + // sctp_new_association_resp->sctp_state, + // instance, + // sctp_new_association_resp->ulp_cnx_id); + // //m2ap_eNB_handle_m2_setup_message(instance_p, m2ap_mce_data_p, + // //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + // return; + // } + + // printf("m2ap_MCE_handle_sctp_association_resp at 3\n"); + // dump_mce_trees_m2(); + // /* Update parameters */ + // m2ap_mce_data_p->assoc_id = sctp_new_association_resp->assoc_id; + // m2ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams; + // m2ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams; + // printf("m2ap_MCE_handle_sctp_association_resp at 4\n"); + // dump_mce_trees_m2(); + // /* Prepare new m2 Setup Request */ + // //m2ap_MCE_generate_m2_setup_request(instance_p, m2ap_mce_data_p); +} + +static +void m2ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { + //m2ap_MCE_instance_t *instance_p; + //m2ap_MCE_data_t *m2ap_mce_data_p; + //printf("m2ap_MCE_handle_sctp_association_ind at 1 (called for instance %d)\n", instance); + ///dump_mce_trees_m2(); + ///DevAssert(sctp_new_association_ind != NULL); + ///instance_p = instance;//m2ap_MCE_get_instance(instance); + ///DevAssert(instance_p != NULL); + ///m2ap_mce_data_p = m2ap_get_MCE(instance_p, sctp_new_association_ind->assoc_id, -1); + + ///if (m2ap_mce_data_p != NULL) abort(); + + ///// DevAssert(m2ap_enb_data_p != NULL); + ///if (m2ap_mce_data_p == NULL) { + /// /* Create new MCE descriptor */ + /// m2ap_mce_data_p = calloc(1, sizeof(*m2ap_mce_data_p)); + /// DevAssert(m2ap_mce_data_p != NULL); + /// m2ap_mce_data_p->cnx_id = m2ap_MCE_fetch_add_global_cnx_id(); + /// m2ap_mce_data_p->m2ap_MCE_instance = instance_p; + /// /* Insert the new descriptor in list of known MCE + /// * but not yet associated. + /// */ + /// RB_INSERT(m2ap_mce_map, &instance_p->m2ap_mce_head, m2ap_mce_data_p); + /// m2ap_mce_data_p->state = M2AP_MCE_STATE_CONNECTED; + /// instance_p->m2_target_mce_nb++; + + /// if (instance_p->m2_target_mce_pending_nb > 0) { + /// instance_p->m2_target_mce_pending_nb--; + /// } + ///} else { + /// M2AP_WARN("m2ap_mce_data_p already exists\n"); + ///} + + ///printf("m2ap_MCE_handle_sctp_association_ind at 2\n"); + ///dump_mce_trees_m2(); + ////* Update parameters */ + ///m2ap_mce_data_p->assoc_id = sctp_new_association_ind->assoc_id; + ///m2ap_mce_data_p->in_streams = sctp_new_association_ind->in_streams; + ///m2ap_mce_data_p->out_streams = sctp_new_association_ind->out_streams; + ///printf("m2ap_MCE_handle_sctp_association_ind at 3\n"); + ///dump_mce_trees_m2(); +} + +int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t mce_port_for_M2C) { + // Create and alloc new message + MessageDef *message; + sctp_init_t *sctp_init = NULL; + DevAssert(instance_p != NULL); + DevAssert(local_ip_addr != NULL); + message = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG_MULTI_REQ); + sctp_init = &message->ittiMsg.sctp_init_multi; + sctp_init->port = mce_port_for_M2C; + sctp_init->ppid = M2AP_SCTP_PPID; + sctp_init->ipv4 = 1; + sctp_init->ipv6 = 0; + sctp_init->nb_ipv4_addr = 1; +#if 0 + memcpy(&sctp_init->ipv4_address, + local_ip_addr, + sizeof(*local_ip_addr)); +#endif + sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + sctp_init->nb_ipv6_addr = 0; + sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); +} + +static void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p, + net_ip_address_t *target_MCE_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t mce_port_for_M2C, + int multi_sd) { + MessageDef *message = NULL; + sctp_new_association_req_multi_t *sctp_new_association_req = NULL; + m2ap_MCE_data_t *m2ap_mce_data = NULL; + DevAssert(instance_p != NULL); + DevAssert(target_MCE_ip_address != NULL); + message = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI); + sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; + sctp_new_association_req->port = mce_port_for_M2C; + sctp_new_association_req->ppid = M2AP_SCTP_PPID; + sctp_new_association_req->in_streams = in_streams; + sctp_new_association_req->out_streams = out_streams; + sctp_new_association_req->multi_sd = multi_sd; + memcpy(&sctp_new_association_req->remote_address, + target_MCE_ip_address, + sizeof(*target_MCE_ip_address)); + memcpy(&sctp_new_association_req->local_address, + local_ip_addr, + sizeof(*local_ip_addr)); + /* Create new MCE descriptor */ + m2ap_mce_data = calloc(1, sizeof(*m2ap_mce_data)); + DevAssert(m2ap_mce_data != NULL); + m2ap_mce_data->cnx_id = m2ap_MCE_fetch_add_global_cnx_id(); + sctp_new_association_req->ulp_cnx_id = m2ap_mce_data->cnx_id; + m2ap_mce_data->assoc_id = -1; + m2ap_mce_data->m2ap_MCE_instance = instance_p; + /* Insert the new descriptor in list of known MCE + * but not yet associated. + */ + RB_INSERT(m2ap_mce_map, &instance_p->m2ap_mce_head, m2ap_mce_data); + m2ap_mce_data->state = M2AP_MCE_STATE_WAITING; + instance_p->m2_target_mce_nb ++; + instance_p->m2_target_mce_pending_nb ++; + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message); +} + +static +void m2ap_MCE_handle_register_MCE(instance_t instance, + m2ap_register_mce_req_t *m2ap_register_MCE) { + m2ap_MCE_instance_t *new_instance; + DevAssert(m2ap_register_MCE != NULL); + /* Look if the provided instance already exists */ + new_instance = m2ap_MCE_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same MCE */ + DevCheck(new_instance->MCE_id == m2ap_register_MCE->MCE_id, new_instance->MCE_id, m2ap_register_MCE->MCE_id, 0); + DevCheck(new_instance->cell_type == m2ap_register_MCE->cell_type, new_instance->cell_type, m2ap_register_MCE->cell_type, 0); + DevCheck(new_instance->tac == m2ap_register_MCE->tac, new_instance->tac, m2ap_register_MCE->tac, 0); + DevCheck(new_instance->mcc == m2ap_register_MCE->mcc, new_instance->mcc, m2ap_register_MCE->mcc, 0); + DevCheck(new_instance->mnc == m2ap_register_MCE->mnc, new_instance->mnc, m2ap_register_MCE->mnc, 0); + M2AP_WARN("MCE[%d] already registered\n", instance); + } else { + new_instance = calloc(1, sizeof(m2ap_MCE_instance_t)); + DevAssert(new_instance != NULL); + RB_INIT(&new_instance->m2ap_mce_head); + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->MCE_name = m2ap_register_MCE->MCE_name; + new_instance->MCE_id = m2ap_register_MCE->MCE_id; + new_instance->cell_type = m2ap_register_MCE->cell_type; + new_instance->tac = m2ap_register_MCE->tac; + new_instance->mcc = m2ap_register_MCE->mcc; + new_instance->mnc = m2ap_register_MCE->mnc; + new_instance->mnc_digit_length = m2ap_register_MCE->mnc_digit_length; + new_instance->num_cc = m2ap_register_MCE->num_cc; + + m2ap_id_manager_init(&new_instance->id_manager); + m2ap_timers_init(&new_instance->timers, + m2ap_register_MCE->t_reloc_prep, + m2ap_register_MCE->tm2_reloc_overall); + + for (int i = 0; i< m2ap_register_MCE->num_cc; i++) { + new_instance->eutra_band[i] = m2ap_register_MCE->eutra_band[i]; + new_instance->downlink_frequency[i] = m2ap_register_MCE->downlink_frequency[i]; + new_instance->uplink_frequency_offset[i] = m2ap_register_MCE->uplink_frequency_offset[i]; + new_instance->Nid_cell[i] = m2ap_register_MCE->Nid_cell[i]; + new_instance->N_RB_DL[i] = m2ap_register_MCE->N_RB_DL[i]; + new_instance->frame_type[i] = m2ap_register_MCE->frame_type[i]; + new_instance->fdd_earfcn_DL[i] = m2ap_register_MCE->fdd_earfcn_DL[i]; + new_instance->fdd_earfcn_UL[i] = m2ap_register_MCE->fdd_earfcn_UL[i]; + } + + DevCheck(m2ap_register_MCE->nb_m2 <= M2AP_MAX_NB_MCE_IP_ADDRESS, + M2AP_MAX_NB_MCE_IP_ADDRESS, m2ap_register_MCE->nb_m2, 0); + memcpy(new_instance->target_mce_m2_ip_address, + m2ap_register_MCE->target_mce_m2_ip_address, + m2ap_register_MCE->nb_m2 * sizeof(net_ip_address_t)); + new_instance->nb_m2 = m2ap_register_MCE->nb_m2; + new_instance->mce_m2_ip_address = m2ap_register_MCE->mce_m2_ip_address; + new_instance->sctp_in_streams = m2ap_register_MCE->sctp_in_streams; + new_instance->sctp_out_streams = m2ap_register_MCE->sctp_out_streams; + new_instance->mce_port_for_M2C = m2ap_register_MCE->mce_port_for_M2C; + /* Add the new instance to the list of MCE (meaningfull in virtual mode) */ + m2ap_MCE_insert_new_instance(new_instance); + M2AP_INFO("Registered new MCE[%d] and %s MCE id %u\n", + instance, + m2ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home", + m2ap_register_MCE->MCE_id); + + /* initiate the SCTP listener */ + if (m2ap_MCE_init_sctp(new_instance,&m2ap_register_MCE->mce_m2_ip_address,m2ap_register_MCE->mce_port_for_M2C) < 0 ) { + M2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n"); + return; + } + + M2AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n", + instance, m2ap_register_MCE->MCE_id); + } +} + +static +void m2ap_MCE_handle_sctp_init_msg_multi_cnf( + instance_t instance_id, + sctp_init_msg_multi_cnf_t *m) { + m2ap_MCE_instance_t *instance; + int index; + DevAssert(m != NULL); + instance = m2ap_MCE_get_instance(instance_id); + DevAssert(instance != NULL); + instance->multi_sd = m->multi_sd; + + /* Exit if CNF message reports failure. + * Failure means multi_sd < 0. + */ + if (instance->multi_sd < 0) { + M2AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n"); + DevAssert(instance->multi_sd >= 0); + } + + /* Trying to connect to the provided list of MCE ip address */ + + for (index = 0; index < instance->nb_m2; index++) { + M2AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n", + instance_id, instance->MCE_id); + m2ap_MCE_register_MCE(instance, + &instance->target_mce_m2_ip_address[index], + &instance->mce_m2_ip_address, + instance->sctp_in_streams, + instance->sctp_out_streams, + instance->mce_port_for_M2C, + instance->multi_sd); + } +} + +//static +//void m2ap_MCE_handle_handover_req(instance_t instance, +// m2ap_handover_req_t *m2ap_handover_req) +//{ +// m2ap_MCE_instance_t *instance_p; +// m2ap_MCE_data_t *target; +// m2ap_id_manager *id_manager; +// int ue_id; +// +// int target_pci = m2ap_handover_req->target_physCellId; +// +// instance_p = m2ap_MCE_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m2ap_is_MCE_pci_in_list(target_pci); +// DevAssert(target != NULL); +// +// /* allocate m2ap ID */ +// id_manager = &instance_p->id_manager; +// ue_id = m2ap_allocate_new_id(id_manager); +// if (ue_id == -1) { +// M2AP_ERROR("could not allocate a new M2AP UE ID\n"); +// /* TODO: cancel handover: send (to be defined) message to RRC */ +// exit(1); +// } +// /* id_source is ue_id, id_target is unknown yet */ +// m2ap_set_ids(id_manager, ue_id, m2ap_handover_req->rnti, ue_id, -1); +// m2ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE); +// m2ap_set_reloc_prep_timer(id_manager, ue_id, +// m2ap_timer_get_tti(&instance_p->timers)); +// m2ap_id_set_target(id_manager, ue_id, target); +// +// m2ap_MCE_generate_m2_handover_request(instance_p, target, m2ap_handover_req, ue_id); +//} + +//static +//void m2ap_MCE_handle_handover_req_ack(instance_t instance, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack) +//{ +// /* TODO: remove this hack (the goal is to find the correct +// * eNodeB structure for the other end) - we need a proper way for RRC +// * and M2AP to identify eNodeBs +// * RRC knows about mod_id and M2AP knows about MCE_id (MCE_ID in +// * the configuration file) +// * as far as I understand.. CROUX +// */ +// m2ap_MCE_instance_t *instance_p; +// m2ap_MCE_data_t *target; +// int source_assoc_id = m2ap_handover_req_ack->source_assoc_id; +// int ue_id; +// int id_source; +// int id_target; +// +// instance_p = m2ap_MCE_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m2ap_get_MCE(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// /* rnti is a new information, save it */ +// ue_id = m2ap_handover_req_ack->m2_id_target; +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// m2ap_set_ids(&instance_p->id_manager, ue_id, m2ap_handover_req_ack->rnti, id_source, id_target); +// +// m2ap_MCE_generate_m2_handover_request_ack(instance_p, target, m2ap_handover_req_ack); +//} +// +//static +//void m2ap_MCE_ue_context_release(instance_t instance, +// m2ap_ue_context_release_t *m2ap_ue_context_release) +//{ +// m2ap_MCE_instance_t *instance_p; +// m2ap_MCE_data_t *target; +// int source_assoc_id = m2ap_ue_context_release->source_assoc_id; +// int ue_id; +// instance_p = m2ap_MCE_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m2ap_get_MCE(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// m2ap_MCE_generate_m2_ue_context_release(instance_p, target, m2ap_ue_context_release); +// +// /* free the M2AP UE ID */ +// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti); +// exit(1); +// } +// m2ap_release_id(&instance_p->id_manager, ue_id); +//} + +void MCE_task_send_sctp_init_req(instance_t enb_id, m2ap_mce_sctp_req_t * m2ap_mce_sctp_req) { + // 1. get the itti msg, and retrive the enb_id from the message + // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port + // 3. creat an itti message to init + + LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n"); + MessageDef *message_p = NULL; + + message_p = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG); + + // if( m2ap_mce_sctp_req == NULL ){ + // message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER; + // message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID; + // message_p->ittiMsg.sctp_init.ipv4 = 1; + // message_p->ittiMsg.sctp_init.ipv6 = 0; + // message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + // //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); + // message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7"); + // /* + // * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + // * * * * Disable it for now. + // */ + // message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; + // message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + // }else{ + message_p->ittiMsg.sctp_init.port = m2ap_mce_sctp_req->mce_port_for_M2C; + message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID; + message_p->ittiMsg.sctp_init.ipv4 = 1; + message_p->ittiMsg.sctp_init.ipv6 = 0; + message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); + message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; + message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + // } + + itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); +} + +void *m2ap_MCE_task(void *arg) { + MessageDef *received_msg = NULL; + int result; + M2AP_DEBUG("Starting M2AP layer\n"); + m2ap_MCE_prepare_internal_data(); + itti_mark_task_ready(TASK_M2AP_MCE); + + //MCE_task_send_sctp_init_req(0,NULL); + + + while (1) { + itti_receive_msg(TASK_M2AP_MCE, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case MESSAGE_TEST: + LOG_W(M2AP,"MCE Received MESSAGE_TEST Message\n"); + //MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_MCE, MESSAGE_TEST); + //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p); + break; + case TERMINATE_MESSAGE: + M2AP_WARN(" *** Exiting M2AP thread\n"); + itti_exit_task(); + break; + + case M2AP_MCE_SCTP_REQ: + MCE_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MCE_SCTP_REQ(received_msg)); + break; + + case M2AP_SUBFRAME_PROCESS: + m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + break; + + case M2AP_REGISTER_MCE_REQ: + LOG_I(M2AP,"MCE Received M2AP_REGISTER_MCE_REQ Message\n"); + m2ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_REGISTER_MCE_REQ(received_msg)); + break; + + case M2AP_SETUP_RESP: + LOG_I(M2AP,"MCE Received M2AP_SETUP_RESP Message\n"); + MCE_send_M2_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_SETUP_RESP(received_msg)); + break; + + case M2AP_SETUP_FAILURE: + LOG_I(M2AP,"MCE Received M2AP_SETUP_FAILURE Message\n"); + MCE_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_SETUP_FAILURE(received_msg)); + break; + + case M2AP_MBMS_SCHEDULING_INFORMATION: + LOG_I(M2AP,"MCE Received M2AP_MBMS_SCHEDULING_INFORMATION Message\n"); + MCE_send_MBMS_SCHEDULING_INFORMATION(0, + &M2AP_MBMS_SCHEDULING_INFORMATION(received_msg)); + break; + + case M2AP_MBMS_SESSION_START_REQ: + LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_START_REQ Message\n"); + MCE_send_MBMS_SESSION_START_REQUEST(0, + &M2AP_MBMS_SESSION_START_REQ(received_msg)); + break; + + case M2AP_MBMS_SESSION_STOP_REQ: + LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_STOP_REQ Message\n"); + MCE_send_MBMS_SESSION_STOP_REQUEST(0, + &M2AP_MBMS_SESSION_STOP_REQ(received_msg)); + break; + + case M2AP_MBMS_SESSION_UPDATE_REQ: + LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_UPDATE_REQ Message\n"); + MCE_send_MBMS_SESSION_UPDATE_REQUEST(0, + &M2AP_MBMS_SESSION_UPDATE_REQ(received_msg)); + break; + + case M2AP_RESET: + LOG_I(M2AP,"MCE Received M2AP_RESET Message\n"); + MCE_send_RESET(0, + &M2AP_RESET(received_msg)); + break; + + case M2AP_ENB_CONFIGURATION_UPDATE_ACK: + LOG_I(M2AP,"MCE Received M2AP_ENB_CONFIGURATION_UPDATE_ACK Message\n"); + MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(0, + &M2AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg)); + break; + + case M2AP_ENB_CONFIGURATION_UPDATE_FAILURE: + LOG_I(M2AP,"MCE Received M2AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n"); + MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(0, + &M2AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg)); + break; + + + case M2AP_MCE_CONFIGURATION_UPDATE: + LOG_I(M2AP,"MCE Received M2AP_MCE_CONFIGURATION_UPDATE Message\n"); + //MCE_send_MCE_CONFIGURATION_UPDATE(0, + //&M2AP_MCE_CONFIGURATION_UPDATE(received_msg)); + break; + + +// case M2AP_HANDOVER_REQ: +// m2ap_MCE_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M2AP_HANDOVER_REQ(received_msg)); +// break; +// +// case M2AP_HANDOVER_REQ_ACK: +// m2ap_MCE_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M2AP_HANDOVER_REQ_ACK(received_msg)); +// break; +// +// case M2AP_UE_CONTEXT_RELEASE: +// m2ap_MCE_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M2AP_UE_CONTEXT_RELEASE(received_msg)); +// break; +// + case SCTP_INIT_MSG_MULTI_CNF: + LOG_D(M2AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n"); + m2ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_init_msg_multi_cnf); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n"); + m2ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_NEW_ASSOCIATION_IND: + LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n"); + m2ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_DATA_IND: + LOG_D(M2AP,"MCE Received SCTP_DATA_IND Message\n"); + m2ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + default: + M2AP_ERROR("MCE Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; + } + + return NULL; +} + +#include "common/config/config_userapi.h" + +int is_m2ap_MCE_enabled(void) +{ + static volatile int config_loaded = 0; + static volatile int enabled = 0; + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if (pthread_mutex_lock(&mutex)) goto mutex_error; + + if (config_loaded) { + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + return enabled; + } + + char *enable_m2 = NULL; + paramdef_t p[] = { + { "enable_mce_m2", "yes/no", 0, strptr:&enable_m2, defstrval:"", TYPE_STRING, 0 } + }; + + /* TODO: do it per module - we check only first MCE */ + config_get(p, sizeof(p)/sizeof(paramdef_t), "MCEs.[0]"); + if (enable_m2 != NULL && strcmp(enable_m2, "yes") == 0) + enabled = 1; + + config_loaded = 1; + + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + + return enabled; + +mutex_error: + LOG_E(M2AP, "mutex error\n"); + exit(1); +} diff --git a/openair2/M2AP/m2ap_MCE.h b/openair2/M2AP/m2ap_MCE.h new file mode 100644 index 0000000000..563b860883 --- /dev/null +++ b/openair2/M2AP/m2ap_MCE.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE.h + * \brief m2ap tasks for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include + +/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +#ifndef M2AP_MCE_H_ +#define M2AP_MCE_H_ + +#include "m2ap_MCE_defs.h" + + +int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t enb_port_for_M2C); + +void *m2ap_MCE_task(void *arg); + +int is_m2ap_MCE_enabled(void); + +#endif /* M2AP_MCE_H_ */ + +/** + * @} + */ diff --git a/openair2/M2AP/m2ap_MCE_defs.h b/openair2/M2AP/m2ap_MCE_defs.h new file mode 100644 index 0000000000..5267232d69 --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_defs.h @@ -0,0 +1,210 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_defs.h + * \brief m2ap struct definitions for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#include "m2ap_ids.h" //looks X2AP specific for HO +#include "m2ap_timers.h" + +#ifndef M2AP_MCE_DEFS_H_ +#define M2AP_MCE_DEFS_H_ + +#define M2AP_MCE_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + M2AP_MCE_STATE_DISCONNECTED = 0x0, + + /* State waiting for m2 Setup response message if the target MCE accepts or + * M2 Setup failure if rejects the MCE. + */ + M2AP_MCE_STATE_WAITING = 0x1, + + /* The MCE is successfully connected to another MCE. */ + M2AP_MCE_STATE_CONNECTED = 0x2, + + /* M2AP is ready, and the MCE is successfully connected to another MCE. */ + M2AP_MCE_STATE_READY = 0x3, + + M2AP_MCE_STATE_OVERLOAD = 0x4, + + M2AP_MCE_STATE_RESETTING = 0x5, + + /* Max number of states available */ + M2AP_MCE_STATE_MAX, +} m2ap_MCE_state_t; + +/* Served PLMN identity element */ +/*struct plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + STAILQ_ENTRY(plmn_identity_s) next; +};*/ + +/* Served group id element */ +/*struct served_group_id_s { + uint16_t mce_group_id; + STAILQ_ENTRY(served_group_id_s) next; +};*/ + +/* Served enn code for a particular MCE */ +/*struct mce_code_s { + uint8_t mce_code; + STAILQ_ENTRY(mce_code_s) next; +};*/ + +struct m2ap_MCE_instance_s; + +/* This structure describes association of a MCE to another MCE */ +typedef struct m2ap_MCE_data_s { + /* MCE descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(m2ap_MCE_data_s) entry; + + /* This is the optional name provided by the MME */ + char *MCE_name; + + /* target MCE ID */ + uint32_t MCE_id; + + /* Current MCE load information (if any). */ + //m2ap_load_state_t overload_state; + + /* Current MCE->MCE M2AP association state */ + m2ap_MCE_state_t state; + + /* Next usable stream for UE signalling */ + int32_t nextstream; + + /* Number of input/ouput streams */ + uint16_t in_streams; + uint16_t out_streams; + + /* Connexion id used between SCTP/M2AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Nid cells */ + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + + /* Only meaningfull in virtual mode */ + struct m2ap_MCE_instance_s *m2ap_MCE_instance; +} m2ap_MCE_data_t; + +typedef struct m2ap_MCE_instance_s { + /* used in simulation to store multiple MCE instances*/ + STAILQ_ENTRY(m2ap_MCE_instance_s) m2ap_MCE_entries; + + /* Number of target MCEs requested by MCE (tree size) */ + uint32_t m2_target_mce_nb; + /* Number of target MCEs for which association is pending */ + uint32_t m2_target_mce_pending_nb; + /* Number of target MCE successfully associated to MCE */ + uint32_t m2_target_mce_associated_nb; + /* Tree of M2AP MCE associations ordered by association ID */ + RB_HEAD(m2ap_mce_map, m2ap_MCE_data_s) m2ap_mce_head; + + /* Tree of UE ordered by MCE_ue_m2ap_id's */ + // RB_HEAD(m2ap_ue_map, m2ap_MCE_ue_context_s) m2ap_ue_head; + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + /* Displayable name of MCE */ + char *MCE_name; + + /* Unique MCE_id to identify the MCE within EPC. + * In our case the MCE is a macro MCE so the id will be 20 bits long. + * For Home MCE id, this field should be 28 bits long. + */ + uint32_t MCE_id; + /* The type of the cell */ + cell_type_t cell_type; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* CC params */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_MCE_IP_ADDRESS]; + uint8_t nb_m2; + net_ip_address_t mce_m2_ip_address; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + uint32_t mce_port_for_M2C; + int multi_sd; + + m2ap_id_manager id_manager; + m2ap_timers_t timers; +} m2ap_MCE_instance_t; + +typedef struct { + /* List of served MCEs + * Only used for virtual mode + */ + STAILQ_HEAD(m2ap_MCE_instances_head_s, m2ap_MCE_instance_s) m2ap_MCE_instances_head; + /* Nb of registered MCEs */ + uint8_t nb_registered_MCEs; + + /* Generate a unique connexion id used between M2AP and SCTP */ + uint16_t global_cnx_id; +} m2ap_MCE_internal_data_t; + +int m2ap_MCE_compare_assoc_id(struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2); + +/* Generate the tree management functions */ +struct m2ap_MCE_map; +struct m2ap_MCE_data_s; +RB_PROTOTYPE(m2ap_MCE_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id); + + +#endif /* M2AP_MCE_DEFS_H_ */ diff --git a/openair2/M2AP/m2ap_MCE_generate_messages.c b/openair2/M2AP/m2ap_MCE_generate_messages.c new file mode 100644 index 0000000000..a28097cf1a --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_generate_messages.c @@ -0,0 +1,804 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_generate_messages.c + * \brief m2ap procedures for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +//#include "M2AP_LastVisitedCell-Item.h" + +#include "m2ap_common.h" +#include "m2ap_MCE.h" +#include "m2ap_MCE_generate_messages.h" +#include "m2ap_encoder.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +#include "m2ap_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +int m2ap_MCE_generate_m2_setup_request( + m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p) +{ + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupRequest_t *out; + M2AP_M2SetupRequest_Ies_t *ie; + //M2AP_PLMN_Identity_t *plmn; + //ServedCells__Member *servedCellMember; + //M2AP_GU_Group_ID_t *gu; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(m2ap_MCE_data_p != NULL); + + m2ap_MCE_data_p->state = M2AP_MCE_STATE_WAITING; + + /* Prepare the M2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest; + + /* mandatory */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GlobalMCE_ID; + //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &ie->value.choice.GlobalMCE_ID.pLMN_Identity); + //ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID; + //MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id, + // &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID); + //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id, + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_ServedCells; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_ServedCells; + //{ + // for (int i = 0; inum_cc; i++){ + // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); + // { + // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; + + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); + // MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0, + // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); + + // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); + // } + + // if (instance_p->frame_type[i] == FDD) { + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + // switch (instance_p->N_RB_DL[i]) { + // case 6: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // break; + // case 15: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // break; + // case 25: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // break; + // case 50: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // break; + // case 75: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // break; + // case 100: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // break; + // default: + // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + // break; + // } + // } + // else { + // AssertFatal(0,"M2Setuprequest not supported for TDD!"); + // } + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + // } + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GUGroupIDList; + //{ + // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &gu->pLMN_Identity); + // //@TODO: consider to update this value + // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + M2AP_ERROR("Failed to encode M2 setup request\n"); + return -1; + } + + //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); + + m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p) +{ + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupResponse_t *out; + M2AP_M2SetupResponse_Ies_t *ie; + //M2AP_PLMN_Identity_t *plmn; + //ServedCells__Member *servedCellMember; + //M2AP_GU_Group_ID_t *gu; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(m2ap_MCE_data_p != NULL); + + /* Prepare the M2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse; + + /* mandatory */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalMCE_ID; + //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &ie->value.choice.GlobalMCE_ID.pLMN_Identity); + //ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID; + //MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id, + // &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID); + //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id, + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_ServedCells; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells; + //{ + // for (int i = 0; inum_cc; i++){ + // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); + // { + // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; + + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); + // MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0, + // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); + + // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); + // } + + // if (instance_p->frame_type[i] == FDD) { + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + // switch (instance_p->N_RB_DL[i]) { + // case 6: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // break; + // case 15: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // break; + // case 25: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // break; + // case 50: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // break; + // case 75: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // break; + // case 100: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // break; + // default: + // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + // break; + // } + // } + // else { + // AssertFatal(0,"M2Setupresponse not supported for TDD!"); + // } + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + // } + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList; + //{ + // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &gu->pLMN_Identity); + // //@TODO: consider to update this value + // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + M2AP_ERROR("Failed to encode M2 setup response\n"); + return -1; + } + + m2ap_MCE_data_p->state = M2AP_MCE_STATE_READY; + + //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id); + + m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int m2ap_MCE_generate_m2_setup_failure(instance_t instance, + uint32_t assoc_id, + M2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait) +{ + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupFailure_t *out; + M2AP_M2SetupFailure_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + /* Prepare the M2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure; + + /* mandatory */ + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_Cause; + //ie->criticality = M2AP_Criticality_ignore; + //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause; + + //m2ap_MCE_set_cause (&ie->value.choice.Cause, cause_type, cause_value); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional: consider to handle this later */ + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait; + //ie->criticality = M2AP_Criticality_ignore; + //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait; + + //if (time_to_wait > -1) { + // ie->value.choice.TimeToWait = time_to_wait; + //} + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + M2AP_ERROR("Failed to encode M2 setup failure\n"); + return -1; + } + + //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, + // MSC_M2AP_TARGET_MCE, NULL, 0, + // "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", + // assoc_id, cause_type, cause_value); + + m2ap_MCE_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); + + return ret; +} + +int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value) +{ + + DevAssert (cause_p != NULL); + cause_p->present = cause_type; + + switch (cause_type) { + case M2AP_Cause_PR_radioNetwork: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_transport: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_protocol: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_misc: + cause_p->choice.misc = cause_value; + break; + + default: + return -1; + } + + return 0; +} + +//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequest_t *out; +// M2AP_HandoverRequest_IEs_t *ie; +// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; +// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; +// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause; +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.ECGI.pLMN_Identity); +// MACRO_MCE_ID_TO_CELL_IDENTITY(m2ap_MCE_data_p->MCE_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); +// //@TODO: consider to update these values +// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); +// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; +// //@TODO: consider to update this value +// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id; +// +// KMCE_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); +// +// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc; +// } +// else { +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; +// } +// +// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); +// +// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); +// +// //@TODO: update with proper UEAMPR +// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); +// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t)); +// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; +// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; +// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; +// { +// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length/8); +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length%8; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = +// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, +// m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.buffer, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); +// } +// } +// +// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; +// //@TODO: consider to update this value +// { +// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t)); +// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); +// MACRO_MCE_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); +// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small; +// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover request\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequestAcknowledge_t *out; +// M2AP_HandoverRequestAcknowledge_IEs_t *ie; +// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; +// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// ue_id = m2ap_handover_req_ack->m2_id_target; +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; +// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; +// +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t)); +// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; +// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; +// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; +// { +// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); +// } +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargetMCEtoSource_MCETransparentContainer; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargetMCEtoSource_MCETransparentContainer; +// +// OCTET_STRING_fromBuf(&ie->value.choice.TargetMCEtoSource_MCETransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover response\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_UEContextRelease_t *out; +// M2AP_UEContextRelease_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti); +// exit(1); +// } +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP ue context relase message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease; +// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 UE Context Release\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverCancel_t *out; +// M2AP_HandoverCancel_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// ue_id = m2_ue_id; +// id_source = ue_id; +// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id); +// +// /* Prepare the M2AP handover cancel message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// if (id_target != -1) { +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause; +// switch (cause) { +// case M2AP_T_RELOC_PREP_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_trelocprep_expiry; +// break; +// case M2AP_TX2_RELOC_OVERALL_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_tx2relocoverall_expiry; +// break; +// default: +// /* we can't come here */ +// M2AP_ERROR("unhandled cancel cause\n"); +// exit(1); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 Handover Cancel\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} diff --git a/openair2/M2AP/m2ap_MCE_generate_messages.h b/openair2/M2AP/m2ap_MCE_generate_messages.h new file mode 100644 index 0000000000..1632dc807a --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_generate_messages.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_generate_messages.h + * \brief m2ap procedures for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_MCE_GENERATE_MESSAGES_H_ +#define M2AP_MCE_GENERATE_MESSAGES_H_ + +#include "m2ap_MCE_defs.h" +#include "m2ap_common.h" + +int m2ap_MCE_generate_m2_setup_request(m2ap_MCE_instance_t *instance_p, + m2ap_MCE_data_t *m2ap_MCE_data_p); + +int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p); + +int m2ap_MCE_generate_m2_setup_failure(instance_t instance, + uint32_t assoc_id, + M2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait); + +int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value); + +//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id); +// +//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack); +// +//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_ue_context_release_t *m2ap_ue_context_release); +// +//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause); + +#endif /* M2AP_MCE_GENERATE_MESSAGES_H_ */ diff --git a/openair2/M2AP/m2ap_MCE_handler.c b/openair2/M2AP/m2ap_MCE_handler.c new file mode 100644 index 0000000000..85e342f996 --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_handler.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_handler.c + * \brief m2ap handler procedures for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m2ap_common.h" +#include "m2ap_MCE_defs.h" +#include "m2ap_MCE_handler.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +//#include "m2ap_MCE_management_procedures.h" +#include "m2ap_MCE_generate_messages.h" + +#include "m2ap_MCE_interface_management.h" +//#include "m2ap_eNB_interface_management.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +/* Handlers matrix. Only eNB related procedure present here */ +m2ap_message_decoded_callback m2ap_MCE_messages_callback[][3] = { + { 0, MCE_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */ + { 0, MCE_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */ + { 0, MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE, 0 }, /* MBMSSchedulingInformation */ + { 0, 0, 0 }, /* Error Indication */ + { 0, 0, 0 }, /* Reset */ + { MCE_handle_M2_SETUP_REQUEST, 0, 0 }, /* M2 Setup */ + { 0, 0, 0 }, /* eNBConfigurationUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { 0, 0, 0 }, /* privateMessage */ + { 0, 0, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MBMSServiceCounting */ + { 0, 0, 0 }, /* MBMSServiceCountingResultReport */ + { 0, 0, 0 } /* MBMSOverloadNotification */ +}; + +static char *m2ap_direction2String(int m2ap_dir) { +static char *m2ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m2ap_direction_String[m2ap_dir]); +} + + +int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + M2AP_M2AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + if (m2ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(M2AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_MCE_messages_callback) / (3 * sizeof( + m2ap_MCE_message_decoded_callback)) + || (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(M2AP, "Calling handler with instance %d\n",instance); + ret = (*m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return ret; +} + + diff --git a/openair2/M2AP/m2ap_MCE_handler.h b/openair2/M2AP/m2ap_MCE_handler.h new file mode 100644 index 0000000000..e9faae8f5d --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_handler.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_handler.h + * \brief m2ap handler procedures for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_MCE_HANDLERS_H_ +#define M2AP_MCE_HANDLERS_H_ + +#include "m2ap_MCE_defs.h" + +//void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + +//int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + //const uint8_t * const data, const uint32_t data_length); + + +#endif /* M2AP_MCE_HANDLERS_H_ */ diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c new file mode 100644 index 0000000000..903e395197 --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_interface_management.c @@ -0,0 +1,1905 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_interface_management.c + * \brief m2ap interface management for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "m2ap_common.h" +#include "m2ap_encoder.h" +#include "m2ap_decoder.h" +#include "m2ap_itti_messaging.h" +#include "m2ap_MCE_interface_management.h" + +#include "conversions.h" + +extern m2ap_setup_req_t *m2ap_mce_data_from_enb; + +/* + * MBMS Session start + */ +int MCE_send_MBMS_SESSION_START_REQUEST(instance_t instance/*, uint32_t assoc_id*/,m2ap_session_start_req_t* m2ap_session_start_req){ + + //AssertFatal(1==0,"Not implemented yet\n"); + + //module_id_t enb_mod_idP=0; + //module_id_t du_mod_idP=0; + + M2AP_M2AP_PDU_t pdu; + M2AP_SessionStartRequest_t *out; + M2AP_SessionStartRequest_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i=0; + //int j=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_sessionStart; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_SessionStartRequest; + out = &pdu.choice.initiatingMessage.value.choice.SessionStartRequest; + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartRequest_Ies__value_PR_MCE_MBMS_M2AP_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. TMGI (integrer value) */ + ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_TMGI; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartRequest_Ies__value_PR_TMGI; + MCC_MNC_TO_PLMNID(0,0,3,&ie->value.choice.TMGI.pLMNidentity);/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/ + uint8_t TMGI[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(&ie->value.choice.TMGI.serviceID,(const char*)&TMGI[2],3); + + //&ie->choice.TMGI.pLMN_Identity); + //INT16_TO_OCTET_STRING(0,&ie->choice.TMGI.serviceId); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c3. MBMS_Session_ID (integrer value) */ //OCTET_STRING + if(0){ + ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MBMS_Session_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartRequest_Ies__value_PR_MBMS_Session_ID; + //INT16_TO_OCTET_STRING(0,&ie->choice.MBMS_Session_ID); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c5. MBMS_Service_Area (integrer value) */ //OCTET_STRING + ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MBMS_Service_Area; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartRequest_Ies__value_PR_MBMS_Service_Area; + //OCTET_STRING_fromBuf(&ie->value.choice.MBMS_Service_Area, m2ap_setup_resp->MCEname, + //strlen(m2ap_setup_resp->MCEname)); + //INT16_TO_OCTET_STRING(0,&ie->choice.TMGI.serviceId); + ie->value.choice.MBMS_Service_Area.buf = calloc(3,sizeof(uint8_t)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c6. TNL_Information (integrer value) */ + ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_TNL_Information; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartRequest_Ies__value_PR_TNL_Information; + //ie->value.choice.TNL_Information.iPMCAddress.buf = calloc(4,sizeof(uint8_t)); + //ie->value.choice.TNL_Information.iPSourceAddress.buf = calloc(4,sizeof(uint8_t)); + //TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234,&ie->value.choice.TNL_Information.iPMCAddress); + //TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234,&ie->value.choice.TNL_Information.iPSourceAddress); + + OCTET_STRING_fromBuf(&ie->value.choice.TNL_Information.gTP_TEID, "1204",strlen("1234")); + OCTET_STRING_fromBuf(&ie->value.choice.TNL_Information.iPMCAddress, "1204",strlen("1234")); + OCTET_STRING_fromBuf(&ie->value.choice.TNL_Information.iPSourceAddress, "1204",strlen("1234")); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if(0){ + // /* optional */ + // /* c7. TNL_Information_1 (integrer value) */ + // ie = (M2AP_SessionStartRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStartRequest_Ies_t)); + // ie->id = M2AP_ProtocolIE_ID_id_TNL_Information_1; + // ie->criticality = M2AP_Criticality_reject; + // ie->value.present = M2AP_SessionStartRequest_Ies__value_PR_TNL_Information_1; + // //asn_int642INTEGER(&ie->value.choice.MBMS_Session_ID, f1ap_du_data->MBMS_Session_ID); //? + // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + + /* encode */ + if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + } + + //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); + m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); + return 0; + +} + +int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M2AP, "MCE_handle_MBMS_SESSION_START_RESPONSE\n"); + + AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome, + "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M2AP_ProcedureCode_id_sessionStart, + "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_sessionStart\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M2AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M2AP_SuccessfulOutcome__value_PR_SessionStartResponse, + "pdu->choice.successfulOutcome.value.present != M2AP_SuccessfulOutcome__value_PR_SessionStartResponse\n"); + + + M2AP_SessionStartResponse_t *in = &pdu->choice.successfulOutcome.value.choice.SessionStartResponse; + M2AP_SessionStartResponse_Ies_t *ie; + int MCE_MBMS_M2AP_ID=-1; + int ENB_MBMS_M2AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SESSION_START_RESP); //TODO + + LOG_D(M2AP, "M2AP: SessionStart-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_MCE_MBMS_M2AP_ID, + "ie->value.present != M2AP_sessionStartResponse_IEs__value_PR_MCE_MBMS_M2AP_ID\n"); + MCE_MBMS_M2AP_ID=ie->value.choice.MCE_MBMS_M2AP_ID; + LOG_D(M2AP, "M2AP: SessionStart-Resp: MCE_MBMS_M2AP_ID %d\n", + MCE_MBMS_M2AP_ID); + break; + case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID, + "ie->value.present != M2AP_sessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID\n"); + ENB_MBMS_M2AP_ID=ie->value.choice.ENB_MBMS_M2AP_ID; + LOG_D(M2AP, "M2AP: SessionStart-Resp: ENB_MBMS_M2AP_ID %d\n", + ENB_MBMS_M2AP_ID); + break; + } + } + + AssertFatal(MCE_MBMS_M2AP_ID!=-1,"MCE_MBMS_M2AP_ID was not sent\n"); + AssertFatal(ENB_MBMS_M2AP_ID!=-1,"ENB_MBMS_M2AP_ID was not sent\n"); + //M2AP_SESSION_START_RESP(msg_p). +// MSC_LOG_RX_MESSAGE( +// MSC_M2AP_MCE, +// MSC_M2AP_ENB, + //return 0; +// 0, +// 0, +// MSC_AS_TIME_FMT" MCE_handle_M2_SESSION_START_RESPONSE successfulOutcome assoc_id %d", +// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +// assoc_id); +// + LOG_D(M2AP, "Sending M2AP_SESSION_START_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g); + return 0; + +} +int MCE_handle_MBMS_SESSION_START_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + +/* + * MBMS Session stop + */ +int MCE_send_MBMS_SESSION_STOP_REQUEST(instance_t instance, m2ap_session_stop_req_t* m2ap_session_stop_req){ + + + // module_id_t enb_mod_idP=0; + //module_id_t du_mod_idP=0; + + M2AP_M2AP_PDU_t pdu; + M2AP_SessionStopRequest_t *out; + M2AP_SessionStopRequest_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i=0; + //int j=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_sessionStop; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_SessionStopRequest; + out = &pdu.choice.initiatingMessage.value.choice.SessionStopRequest; + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStopRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStopRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStopRequest_Ies__value_PR_MCE_MBMS_M2AP_ID; + ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. ENB_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStopRequest_Ies_t *)calloc(1, sizeof(M2AP_SessionStopRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStopRequest_Ies__value_PR_ENB_MBMS_M2AP_ID; + ie->value.choice.ENB_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* encode */ + if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + } + + //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); + m2ap_MCE_itti_send_sctp_data_req(instance, m2ap_mce_data_from_enb->assoc_id,buffer,len,0); + return 0; + + + +} + +int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M2AP, "MCE_handle_MBMS_SESSION_STOP_RESPONSE\n"); + + AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome, + "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M2AP_ProcedureCode_id_sessionStop, + "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_sessionStop\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M2AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M2AP_SuccessfulOutcome__value_PR_SessionStopResponse, + "pdu->choice.successfulOutcome->value.present != M2AP_SuccessfulOutcome__value_PR_SessionStopResponse\n"); + + + M2AP_SessionStopResponse_t *in = &pdu->choice.successfulOutcome.value.choice.SessionStopResponse; + M2AP_SessionStopResponse_Ies_t *ie; + int MCE_MBMS_M2AP_ID=-1; + int ENB_MBMS_M2AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SESSION_STOP_RESP); //TODO + + LOG_D(M2AP, "M2AP: SessionStop-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_SessionStopResponse_Ies__value_PR_MCE_MBMS_M2AP_ID, + "ie->value.present != M2AP_SessionStopResponse_Ies__value_PR_MCE_MBMS_M2AP_ID\n"); + MCE_MBMS_M2AP_ID=ie->value.choice.MCE_MBMS_M2AP_ID; + LOG_D(M2AP, "M2AP: SessionStop-Resp: MCE_MBMS_M2AP_ID %d\n", + MCE_MBMS_M2AP_ID); + break; + case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_SessionStopResponse_Ies__value_PR_ENB_MBMS_M2AP_ID, + "ie->value.present != M2AP_SessionStopResponse_Ies__value_PR_ENB_MBMS_M2AP_ID\n"); + ENB_MBMS_M2AP_ID=ie->value.choice.ENB_MBMS_M2AP_ID; + LOG_D(M2AP, "M2AP: SessionStop-Resp: ENB_MBMS_M2AP_ID %d\n", + ENB_MBMS_M2AP_ID); + break; + } + } + + AssertFatal(MCE_MBMS_M2AP_ID!=-1,"MCE_MBMS_M2AP_ID was not sent\n"); + AssertFatal(ENB_MBMS_M2AP_ID!=-1,"ENB_MBMS_M2AP_ID was not sent\n"); + // M2AP_SESSION_STOP_RESP(msg_p). + // MSC_LOG_RX_MESSAGE( + // MSC_M2AP_MCE, + // MSC_M2AP_ENB, + // 0, + // 0, + // MSC_AS_TIME_FMT" MCE_handle_M2_SESSION_STOP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + // LOG_D(M2AP, "Sending M2AP_SESSION_START_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g); + // + return 0; +} + + + +int MCE_handle_MBMS_SESSION_STOP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + typedef struct M2AP_MBSFN_Area_Configuration{ + M2AP_PMCH_Configuration_List_t PMCH_Configuration_List; + M2AP_MBSFN_Subframe_ConfigurationList_t MBSFN_Subframe_ConfigurationList; + M2AP_Common_Subframe_Allocation_Period_t Common_Subframe_Allocation_Period; + M2AP_MBSFN_Area_ID_t MBSFN_Area_ID; + M2AP_MBMS_Suspension_Notification_List_t MBMS_Suspension_Notification_List; + }M2AP_MBSFN_Area_Configuration_t; + + +/* + * MBMS Scheduling Information + */ + uint8_t m2ap_message[] = {0x00, 0x02, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x00, 0x19, 0x00, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x2e, 0x00, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x12, 0x10, 0x00, 0x0c, + 0x00, 0x0d, 0x00, 0x00, 0x3f, 0x13, 0x00, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, + 0x01, 0x08, 0x00, 0x16, 0x00, 0x07, 0x00, 0x00, 0x17, 0x00, 0x02, 0x00, 0x40, + 0x00, 0x18, 0x00, 0x01, 0x80, 0x00, 0x1d, 0x00, 0x01, 0x01}; + + +int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_id,*/m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information){ + + //module_id_t enb_mod_idP=0; + //module_id_t du_mod_idP=0; + + M2AP_M2AP_PDU_t pdu; + M2AP_MbmsSchedulingInformation_t *out; + M2AP_MbmsSchedulingInformation_Ies_t *ie; + + uint8_t *buffer/*,*buffer2*/; + uint32_t len/*,len2*/; + int i=0; + int j=0; + int k=0; + //int l=0; + //int l=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsSchedulingInformation; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsSchedulingInformation; + out = &pdu.choice.initiatingMessage.value.choice.MbmsSchedulingInformation; + + /* mandatory */ + /* c1. MCCH_Update_Time */ //long + ie=(M2AP_MbmsSchedulingInformation_Ies_t*)calloc(1,sizeof(M2AP_MbmsSchedulingInformation_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCCH_Update_Time; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsSchedulingInformation_Ies__value_PR_MCCH_Update_Time; + //ie->value.choice.MCCH_Update_Time = ; + ie->value.choice.MCCH_Update_Time = m2ap_mbms_scheduling_information->mcch_update_time; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. MBSFN_Area_Configuration_List */ //long + ie=(M2AP_MbmsSchedulingInformation_Ies_t*)calloc(1,sizeof(M2AP_MbmsSchedulingInformation_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsSchedulingInformation_Ies__value_PR_MBSFN_Area_Configuration_List; + + for(i=0; i < m2ap_mbms_scheduling_information->num_mbms_area_config_list; i++){ + M2AP_MBSFN_Area_Configuration_List_t * m2ap_mbsfn_area_configuration_list = (M2AP_MBSFN_Area_Configuration_List_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_List_t)); + /*M2AP_MBSFN_Area_Configuration_Item_t*/ + M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie; + mbsfn_area_configuration_item_ie =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); + mbsfn_area_configuration_item_ie->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_List; + mbsfn_area_configuration_item_ie->criticality = M2AP_Criticality_reject; + mbsfn_area_configuration_item_ie->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List; + + for(j=0; j < m2ap_mbms_scheduling_information->mbms_area_config_list[i].num_pmch_config_list; j++){ + + M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); + pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; + pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; + pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; + + M2AP_PMCH_Configuration_Item_t * pmch_configuration_item = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t)); + pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; + { + pmch_configuration_item->pmch_Configuration.dataMCS = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].data_mcs; + pmch_configuration_item->pmch_Configuration.mchSchedulingPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mch_scheduling_period; + pmch_configuration_item->pmch_Configuration.allocatedSubframesEnd = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end; + for(k=0; k < m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list; k++){ + MBMSsessionListPerPMCH_Item__Member *member; + member = (MBMSsessionListPerPMCH_Item__Member*)calloc(1,sizeof(MBMSsessionListPerPMCH_Item__Member)); + MCC_MNC_TO_PLMNID( + m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mcc, + m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc, + m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc_length + ,&member->tmgi.pLMNidentity); + + //INT16_TO_OCTET_STRING(0,&imember->tmgi); + char buf[4]; + INT32_TO_BUFFER(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id,buf); + //uint8_t TMGI[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(&member->tmgi.serviceID,(const char*)&buf[1],3); + + //LOG_D(M2AP,"%p,%p,%p,%li,%ld,%ld\n",pmch_configuration_item,&pmch_configuration_item->mbms_Session_List.list,member, m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid,sizeof(member->lcid),sizeof(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid)); + //long kk = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid; + //uint64_t kk=(m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid); + //memcpy(&member->lcid,&m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid,sizeof(member->lcid)); + // member->lcid = 1; + // for( l=2; l < 28;l++) + // LOG_E(M2AP,"%di\n",l); + // if(l == m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid){ + // member->lcid++;//m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id; + // break; + // } + member->lcid = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid; + //member->lcid = (M2AP_LCID_t*)calloc(1,sizeof(M2AP_LCID_t)); + + ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,member); + } + + } + /*M2AP_MBSFN_Subframe_ConfigurationList_t*/ + // M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie2; + //(mbsfn_area_configuration_item_ie+1) =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); + + ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); + + } + + ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie); + + /*M2AP_MBSFN_Area_Configuration_Item_t*/ + M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_1; + mbsfn_area_configuration_item_ie_1 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); + (mbsfn_area_configuration_item_ie_1)->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_List; + (mbsfn_area_configuration_item_ie_1)->criticality = M2AP_Criticality_reject; + (mbsfn_area_configuration_item_ie_1)->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_MBSFN_Subframe_ConfigurationList; + + for(j=0; j < m2ap_mbms_scheduling_information->mbms_area_config_list[i].num_mbms_sf_config_list; j++){ + M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configuration_item_ies = (M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t)); + mbsfn_subframe_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item; + mbsfn_subframe_configuration_item_ies->criticality = M2AP_Criticality_reject; + mbsfn_subframe_configuration_item_ies->value.present = M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration; + + M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t)); + mbsfn_subframe_configuration = &mbsfn_subframe_configuration_item_ies->value.choice.MBSFN_Subframe_Configuration; + { + mbsfn_subframe_configuration->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period; + mbsfn_subframe_configuration->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset; + if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){ + mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames; + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(3); + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF); + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF); + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation>>16) & 0xFF); + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.size =3; + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.bits_unused = 0; + + }else{ + mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame; + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(1); + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.size = 1; + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.bits_unused = 2; + //mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[0] = 0x38<<2; + mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[0] = (m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation & 0x3F)<<2; + } + + ASN_SEQUENCE_ADD(&(mbsfn_area_configuration_item_ie_1)->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configuration_item_ies); + } + } + + ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie_1); + + + /*M2AP_MBSFN_Area_Configuration_Item_t*/ + M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_2; + mbsfn_area_configuration_item_ie_2 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); + (mbsfn_area_configuration_item_ie_2)->id = M2AP_ProtocolIE_ID_id_Common_Subframe_Allocation_Period; + (mbsfn_area_configuration_item_ie_2)->criticality = M2AP_Criticality_reject; + (mbsfn_area_configuration_item_ie_2)->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_Common_Subframe_Allocation_Period; + (mbsfn_area_configuration_item_ie_2)->value.choice.Common_Subframe_Allocation_Period=m2ap_mbms_scheduling_information->mbms_area_config_list[i].common_sf_allocation_period; + + ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie_2); + + + /*M2AP_MBSFN_Area_Configuration_Item_t*/ + M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_3; + mbsfn_area_configuration_item_ie_3 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); + (mbsfn_area_configuration_item_ie_3)->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_ID; + (mbsfn_area_configuration_item_ie_3)->criticality = M2AP_Criticality_reject; + (mbsfn_area_configuration_item_ie_3)->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_MBSFN_Area_ID; + (mbsfn_area_configuration_item_ie_3)->value.choice.MBSFN_Area_ID = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_area_id; + + ASN_SEQUENCE_ADD(m2ap_mbsfn_area_configuration_list,mbsfn_area_configuration_item_ie_3); + + +ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_configuration_list); +//------------- + + + + +// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); +//------------- +//------------- + +// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie+1); +//------------- + + + +/* xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie); + xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_1); + xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_2); + xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_3); + xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List);*/ + + } + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + // LOG_D(M2AP,"%p\n",&pdu); + // LOG_D(M2AP,"%p\n",out); + // LOG_D(M2AP,"%p\n",ie); + // LOG_D(M2AP,"%p\n",mbsfn_area_configuration_item_ie); + // LOG_D(M2AP,"%p\n",&mbsfn_area_configuration_item_ie->value.choice); + // { + // /* PMCH_Configuration_List */ + // + // M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; + // pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); + // { + // pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; + // pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; + // pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; + // M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; + // pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; + // { + // //pmch_configuration_item->allocatedSubframesEnd; + // pmch_configuration_item->pmch_Configuration.dataMCS=13; + // //pmch_configuration_item->mchSchedulingPeriod; + // MBMSsessionListPerPMCH_Item__Member *member; + // member = (MBMSsessionListPerPMCH_Item__Member*)calloc(1,sizeof(MBMSsessionListPerPMCH_Item__Member)); + // LOG_D(M2AP,"%p,%p,%p\n",pmch_configuration_item,&pmch_configuration_item->mbms_Session_List.list,member); + // ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,member); + // } + // //// + // // //ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies); + // + // } + // + // M2AP_PMCH_Configuration_List_t * pmch_list = &mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List; + // + // ASN_SEQUENCE_ADD(&pmch_list->list,pmch_configuration_item_ies); + // LOG_D(M2AP,"%p,%p\n",&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); + // //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); + // //ASN_SET_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); + // //ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies); + + // /* MBSFN_Subframe_ConfigurationList */ + // M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configurationitem; + // mbsfn_subframe_configurationitem =(M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t)); + // { + // mbsfn_subframe_configurationitem->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item; + // mbsfn_subframe_configurationitem->criticality = M2AP_Criticality_reject; + // mbsfn_subframe_configurationitem->value.present=M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration; + // } + // + // //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configurationitem); + // LOG_D(M2AP,"%p,%p\n",&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,mbsfn_subframe_configurationitem); + // //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configurationitem); +//// +//// M2AP_Common_Subframe_Allocation_Period_t * common_subframe_allocation_period; +//// M2AP_MBSFN_Area_ID_t * mbsfn_area_id; + // } + // LOG_D(M2AP,"%p,%p\n",&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); + // //ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); + // ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); + + // M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_2; + // mbsfn_area_configuration_item_ie_2 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); + // { + // // mbsfn_area_configuration_item_ie->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List; + // /* PMCH_Configuration_List */ + // // M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; + // // pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); + // // pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; + // // pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; + // // pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; + // // M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; + // // pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; + // //// + // // ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies); + + // /* MBSFN_Subframe_ConfigurationList */ + // M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configurationitem; + // mbsfn_subframe_configurationitem =(M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t)); + // { + // mbsfn_subframe_configurationitem->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item; + // mbsfn_subframe_configurationitem->criticality = M2AP_Criticality_reject; + // mbsfn_subframe_configurationitem->value.present=M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration; + // //M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration; + // //mbsfn_subframe_configuration = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t)); + // //ASN_SEQUENCE_ADD(mbsfn_subframe_configurationitem,mbsfn_subframe_configuration); + // M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration; + // mbsfn_subframe_configuration = &mbsfn_subframe_configurationitem->value.choice.MBSFN_Subframe_Configuration; + // } + // + // ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie_2,mbsfn_subframe_configurationitem); + + // } + + // ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie_2); + + + +// M2AP_MBSFN_Area_Configuration_List_t * m2ap_mbsfn_area_configuration_list; +// m2ap_mbsfn_area_configuration_list = &ie->value.choice.MBSFN_Area_Configuration_List; +// { +// M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; +// pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); +// pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; +// pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; +// pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; +// M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; +// pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; +// +// ASN_SEQUENCE_ADD(&m2ap_mbsfn_area_configuration_list->PMCH_Configuration_List.list,pmch_configuration_item_ies); +// } +// +// int num_mbsfn_available =0; // ? +// LOG_I(M2AP, "num_mbsfn_available = %d \n", num_mbsfn_available); +// for (i=0; +// iid = M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_Item; +// //mbms_configuration_data_item_ies>criticality = M2AP_Criticality_reject; +// //mbms_mbsfn_area_configuration_item_ies->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_M2AP_MBSFN_Area_Configuration_Item; +// +// M2AP_MBSFN_Area_Configuration_Item_t * mbsfn_area_configuration_item; +// mbsfn_area_configuration_item = (M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); +// //mbsfn_area_configuration_item = &mbms_mbsfn_area_configuration_item_ies->value.choice.M2AP_MBSFN_Area_Configuration_Item; +// mbsfn_area_configuration_item->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List; +// +// M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; +// pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); +// pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; +// pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; +// pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; +// M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; +// pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; +// //memset((void*)&pmch_configuration_item,0,sizeof(M2AP_PMCH_Configuration_Item_t)); +// +// ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); +//// if(0) +//// { +//// /* PMCH_Configuration_List */ +//// LOG_I(M2AP, "num_pmch_available = %d \n", num_mbsfn_available); +//// int num_pmch_available =0; // ? +//// for (j=0; +//// jid = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); +//// pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; +//// pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; +//// +//// M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; +//// //pmch_configuration_item = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t)); +//// pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; +//// { +//// /* PMCH_Configuration */ +//// /* allocateSubframesEnd */ +//// //pmch_configuration_item.pmch_Configuration.allocatedSubframesEnd=; +//// /* dataMCS */ +//// //pmch_configuration_item.pmch_Configuration.dataMCS=; +//// /* MCH_Scheduling_Period*/ +//// //pmch_configuration_item.pmch_Configuration.mchSchedulingPeriod=; +//// +//// /* MBMSsessionListPerPMCH */ +//// LOG_I(M2AP, "num_mbms_session_available = %d \n", num_mbsfn_available); +//// int num_mbms_session_available =1; // ? +//// for(k=0; +//// ktmgi=; +//// //session_list_per_pmch_item->lcid=; +//// //ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,mbsfn_area_configuration_item); +//// } +//// +//// } +//// ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); +//// } +//// +//// /* MBSFN_Subframe_ConfigurationList */ +//// int num_mbsfn_subframe_available=0; +//// for(j=0; +//// jMBSFN_Subframe_Configuration.radioframeAllocationPeriod=; +//// //mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.radioframeAllocationOffset=; +//// //mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.subframeAllocation.oneFrame=; +//// //mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.subframeAllocation.fourFrames=; +//// +//// ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configuration_item); +//// +//// } +//// /* Common_subframe_Allocation_Period */ +//// mbsfn_area_configuration_item->value.choice.Common_Subframe_Allocation_Period=0; +//// /* MBSFN_Area_ID */ +//// mbsfn_area_configuration_item->value.choice.MBSFN_Area_ID=0; +//// /*MBMS_Suspension_Notification_List*/ +//// //TODO +//// } +// //ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item); +// ASN_SEQUENCE_ADD(&m2ap_mbsfn_area_configuration_list->list,mbsfn_area_configuration_item); +// +// } + + + + /* encode */ + if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + } + /*if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + }*/ + + /*buffer = &m2ap_message[0]; + len = 62; + for(int i=0; i < len; i++ ) + printf("%02X",buffer[i]); + printf("\n");*/ + + + //printf("m2ap_mce_data_from_enb %p %p %d\n",m2ap_mce_data_from_enb, buffer, len); + + m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); + return 0; + + +// buffer2 = &m2ap_message[0]; +// len2 = 62; +// for(int i=0; i < len2; i++ ) +// printf("%02X",buffer2[i]); +// printf("\n"); +// +// M2AP_M2AP_PDU_t pdu2; +// memset(&pdu2, 0, sizeof(pdu2)); +// if (m2ap_decode_pdu(&pdu2, buffer2, len2) < 0) { +// LOG_E(M2AP, "SCHEDULING Failed to decode PDU\n"); +// //return -1; +// }else{ +// LOG_D(M2AP, "SCHEDULING OK to decode PDU\n"); +// } +// +// +// M2AP_MbmsSchedulingInformation_t *container2; +// M2AP_MbmsSchedulingInformation_Ies_t *ie2; +// int i2 = 0; +// container2 = &pdu2.choice.initiatingMessage.value.choice.MbmsSchedulingInformation; +// M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie2, container2,M2AP_ProtocolIE_ID_id_MCCH_Update_Time ,true); +// LOG_D(M2AP, "SCHEDULING id %d\n",ie2->id); +// M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie2, container2,M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List ,true); +// LOG_D(M2AP, "SCHEDULING id %d\n",ie2->id); +// +// +// +// //M2AP_MBSFN_Area_Configuration_Item_t * kk = &ie->value.choice.MBSFN_Area_Configuration_List.list.array[0]; +// //printf("M2AP_MBSFN_Area_Configuration_Item %d\n",kk->id); +// +// const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID((void*)&ie2->value.choice.MBSFN_Area_Configuration_List); +// void * memb_ptr = list->array[0]; +// const asn_anonymous_sequence_ *list2 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr); +// +// +// void * memb_ptr1 = list2->array[0]; +// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item1 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1; +// M2AP_PMCH_Configuration_Item_t * m2ap_pmchconfiguration_item =&(((M2AP_PMCH_Configuration_ItemIEs_t*)m2ap_mbsfn_area_configuration_item1->value.choice.PMCH_Configuration_List.list.array[0])->value.choice.PMCH_Configuration_Item); +// printf("dataMCS %d\n",m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS); +// m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS=4; +// printf("allocatedSubframesEnd %d\n",m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd); +// M2AP_PMCH_Configuration_t * m2ap_pmchconfiguration = &m2ap_pmchconfiguration_item->pmch_Configuration; +// printf("M2AP_PMCH_Configuration_t dataMCS %d\n",m2ap_pmchconfiguration->dataMCS); +// printf("M2AP_PMCH_Configuration_t allocatedSubframesEnd %d\n",m2ap_pmchconfiguration->allocatedSubframesEnd); +// M2AP_MBMSsessionListPerPMCH_Item_t * m2ap_mbsfnsessionlistperPMCH = &m2ap_pmchconfiguration_item->mbms_Session_List; +// M2AP_TMGI_t * tmgi = &m2ap_mbsfnsessionlistperPMCH->list.array[0]->tmgi; +// M2AP_PLMN_Identity_t * pLMNidentity = &tmgi->pLMNidentity; +// MCC_MNC_TO_PLMNID(0,1,3/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/ +// ,pLMNidentity); +// +// +// OCTET_STRING_t * serviceID = &tmgi->serviceID; +// M2AP_LCID_t * lcid = &m2ap_mbsfnsessionlistperPMCH->list.array[0]->lcid; //long +// +// +// void * memb_ptr2 = list2->array[1]; +// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item2 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2; +// M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_subframe_configuration_item =&(((M2AP_MBSFN_Subframe_ConfigurationItem_t*)m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.array[0])->value.choice.MBSFN_Subframe_Configuration); +// //M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_subframe_configuration = &m2ap_mbsfn_subframe_configuration_item->value.choice.MBSFN_Subframe_Configuration; +// printf("oneframe ? %d\n",(m2ap_mbsfn_subframe_configuration_item->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame)); +// +// +// void * memb_ptr3 = list2->array[2]; +// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item3 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3; +// M2AP_Common_Subframe_Allocation_Period_t * m2ap_mbsfn_common_subframe_allocation_period = (M2AP_Common_Subframe_Allocation_Period_t*)m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period; +// +// void * memb_ptr4 = list2->array[3]; +// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item4 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4; +// M2AP_MBSFN_Area_ID_t * m2ap_mbsfn_area_id = (M2AP_MBSFN_Area_ID_t*)m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID; +// +// +// +// //ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,list); +// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_configuration_list); +// +// LOG_D(M2AP,"Morgade\n"); +// xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List); +// +// /* encode */ +// if (m2ap_encode_pdu(&pdu2,&buffer,&len) < 0){ +// return -1; +// } +// +// //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); +// m2ap_MCE_itti_send_sctp_data_req(instance,assoc_id,buffer,len,0); +// return 0; +// +// + +} + +int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + + LOG_D(M2AP, "MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE\n"); + + AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome, + "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M2AP_ProcedureCode_id_mbmsSchedulingInformation, + "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_mbmsSchedulingInformation\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M2AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M2AP_SuccessfulOutcome__value_PR_MbmsSchedulingInformationResponse, + "pdu->choice.successfulOutcome->value.present != M2AP_SuccessfulOutcome__value_PR_MbmsSchedulingInformationResponse\n"); + + + //M2AP_MbmsSchedulingInformationResponse_t *in = &pdu->choice.successfulOutcome.value.choice.MbmsSchedulingInformationResponse; + //M2AP_MbmsSchedulingInformationResponse_Ies_t *ie; + //int MCE_MBMS_M2AP_ID=-1; + //int ENB_MBMS_M2AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SCHEDULING_INFORMATION_RESP); //TODO + +// LOG_D(M2AP, "M2AP: SessionStop-Resp: protocolIEs.list.count %d\n", +// in->protocolIEs.list.count); +// for (int i=0;i < in->protocolIEs.list.count; i++) { +// ie = in->protocolIEs.list.array[i]; +// //switch (ie->id) { +// //case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID: +// // AssertFatal(ie->criticality == M2AP_Criticality_reject, +// // "ie->criticality != M2AP_Criticality_reject\n"); +// // AssertFatal(ie->value.present == M2AP_sessionStopIEs__value_PR_MCE_MBMS_M2AP_ID, +// // "ie->value.present != M2AP_sessionStopIEs__value_PR_MCE_MBMS_M2AP_ID\n"); +// // TransactionId=ie->value.choice.MCE_MBMS_M2AP_ID; +// // LOG_D(M2AP, "M2AP: SessionStop-Resp: MCE_MBMS_M2AP_ID %d\n", +// // MCE_MBMS_M2AP_ID); +// // break; +// // case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID: +// // AssertFatal(ie->criticality == M2AP_Criticality_reject, +// // "ie->criticality != M2AP_Criticality_reject\n"); +// // AssertFatal(ie->value.present == M2AP_sessionStopIEs__value_PR_ENB_MBMS_M2AP_ID, +// // "ie->value.present != M2AP_sessionStopIEs__value_PR_ENB_MBMS_M2AP_ID\n"); +// // TransactionId=ie->value.choice.ENB_MBMS_M2AP_ID; +// // LOG_D(M2AP, "M2AP: SessionStop-Resp: ENB_MBMS_M2AP_ID %d\n", +// // ENB_MBMS_M2AP_ID); +// // break; +// //} +// } +// +// M2AP_SESSION_STOP_RESP(msg_p). +// MSC_LOG_RX_MESSAGE( +// MSC_M2AP_MCE, +// MSC_M2AP_ENB, +// 0, +// 0, +// MSC_AS_TIME_FMT" MCE_handle_M2_SCHEDULING_INFORMATION_RESPONSE successfulOutcome assoc_id %d", +// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +// assoc_id); +// +// LOG_D(M2AP, "Sending M2AP_SCHEDULING_INFO_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", +// assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); +// itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), msg_g); +// + return 0; + +} + +/* + * Reset + */ + +int MCE_send_RESET(instance_t instance, m2ap_reset_t * m2ap_reset) { + AssertFatal(1==0,"Not implemented yet\n"); + //M2AP_Reset_t Reset; + +} + + +int MCE_handle_RESET_ACKKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); + +} + +int MCE_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int MCE_send_RESET_ACKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +/* + * M2 Setup + */ +int MCE_handle_M2_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + LOG_D(M2AP, "MCE_handle_M2_SETUP_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + M2AP_M2SetupRequest_t *container; + M2AP_M2SetupRequest_Ies_t *ie; + int i = 0,j=0; + + DevAssert(pdu != NULL); + + container = &pdu->choice.initiatingMessage.value.choice.M2SetupRequest; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received m2 setup request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message(TASK_MCE_APP, M2AP_SETUP_REQ); + + /* assoc_id */ + M2AP_SETUP_REQ(message_p).assoc_id = assoc_id; + + /* GlobalENB_id */ + // this function exits if the ie is mandatory + M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, + M2AP_ProtocolIE_ID_id_GlobalENB_ID, true); + //asn_INTEGER2ulong(&ie->value.choice.GlobalENB_ID.eNB_ID, &M2AP_SETUP_REQ(message_p).GlobalENB_ID); + if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_macro_eNB_ID){ + }else if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_short_Macro_eNB_ID){ + }else if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_long_Macro_eNB_ID){ + } + + LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).GlobalENB_ID %lu \n", M2AP_SETUP_REQ(message_p).GlobalENB_ID); + + /* ENB_name */ + M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, + M2AP_ProtocolIE_ID_id_ENBname, false); + if(ie!=NULL){ + M2AP_SETUP_REQ(message_p).ENBname = calloc(ie->value.choice.ENBname.size + 1, sizeof(char)); + memcpy(M2AP_SETUP_REQ(message_p).ENBname, ie->value.choice.ENBname.buf, + ie->value.choice.ENBname.size); + + /* Convert the mme name to a printable string */ + M2AP_SETUP_REQ(message_p).ENBname[ie->value.choice.ENBname.size] = '\0'; + LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).gNB_DU_name %s \n", M2AP_SETUP_REQ(message_p).ENBname); + } + /* ENB_MBMS_Configuration_data_List */ + + + M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, + M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List, true); + M2AP_SETUP_REQ(message_p).num_mbms_available = ie->value.choice.ENB_MBMS_Configuration_data_List.list.count; + LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).num_mbms_available %d \n", + M2AP_SETUP_REQ(message_p).num_mbms_available); + int num_mbms_available = M2AP_SETUP_REQ(message_p).num_mbms_available; + for (i=0; ivalue.choice.ENB_MBMS_Configuration_data_List.list.array[i])->value.choice.ENB_MBMS_Configuration_data_Item); + /* eCGI */ + //mbms_configuration_item_p->eCGI ... (M2AP_ECGI_t) + + OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.pLMN_Identity),M2AP_SETUP_REQ(message_p).plmn_identity[i]); + //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.eUTRANcellIdentifier),M2AP_SETUP_REQ(message_p).eutran_cell_identifier[i]); + /* mbsfnSynchronisationArea */ + //mbms_configuration_item_p->mbsfnSynchronisationArea ... (M2AP_MBSFN_SynchronisationArea_ID_t) + + M2AP_SETUP_REQ(message_p).mbsfn_synchronization_area[i]=mbms_configuration_item_p->mbsfnSynchronisationArea; + /* mbmsServiceAreaList */ + //mbms_configuration_item_p->mbmsServiceAreaList ... (M2AP_MBMS_Service_Area_ID_List_t) + for(j=0;j<1;j++){ + //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->mbmsServiceAreaList.list.array[j]), M2AP_SETUP_REQ(message_p).service_area_id[i][j]); + } + + } + +// /* tac */ +// OCTET_STRING_TO_INT16(&(served_celles_item_p->served_Cell_Information.fiveGS_TAC), M2AP_SETUP_REQ(message_p).tac[i]); +// LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).tac[%d] %d \n", +// i, M2AP_SETUP_REQ(message_p).tac[i]); +// +// /* - nRCGI */ +// TBCD_TO_MCC_MNC(&(served_celles_item_p->served_Cell_Information.nRCGI.pLMN_Identity), M2AP_SETUP_REQ(message_p).mcc[i], +// M2AP_SETUP_REQ(message_p).mnc[i], +// M2AP_SETUP_REQ(message_p).mnc_digit_length[i]); +// +// +// // NR cellID +// BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity, +// M2AP_SETUP_REQ(message_p).nr_cellid[i]); +// LOG_D(M2AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id, +// M2AP_SETUP_REQ(message_p).mcc[i], +// M2AP_SETUP_REQ(message_p).mnc[i], +// (long long unsigned int)M2AP_SETUP_REQ(message_p).nr_cellid[i]); +// LOG_D(M2AP, "nr_cellId : %x %x %x %x %x\n", +// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0], +// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1], +// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2], +// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3], +// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]); +// /* - nRPCI */ +// M2AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI; +// LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).nr_pci[%d] %d \n", +// i, M2AP_SETUP_REQ(message_p).nr_pci[i]); +// +// // System Information +// /* mib */ +// M2AP_SETUP_REQ(message_p).mib[i] = calloc(served_celles_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char)); +// memcpy(M2AP_SETUP_REQ(message_p).mib[i], served_celles_item_p->gNB_DU_System_Information->mIB_message.buf, +// served_celles_item_p->gNB_DU_System_Information->mIB_message.size); +// /* Convert the mme name to a printable string */ +// M2AP_SETUP_REQ(message_p).mib[i][served_celles_item_p->gNB_DU_System_Information->mIB_message.size] = '\0'; +// M2AP_SETUP_REQ(message_p).mib_length[i] = served_celles_item_p->gNB_DU_System_Information->mIB_message.size; +// LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).mib[%d] %s , len = %d \n", +// i, M2AP_SETUP_REQ(message_p).mib[i], M2AP_SETUP_REQ(message_p).mib_length[i]); +// +// /* sib1 */ +// M2AP_SETUP_REQ(message_p).sib1[i] = calloc(served_celles_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char)); +// memcpy(M2AP_SETUP_REQ(message_p).sib1[i], served_celles_item_p->gNB_DU_System_Information->sIB1_message.buf, +// served_celles_item_p->gNB_DU_System_Information->sIB1_message.size); +// /* Convert the mme name to a printable string */ +// M2AP_SETUP_REQ(message_p).sib1[i][served_celles_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0'; +// M2AP_SETUP_REQ(message_p).sib1_length[i] = served_celles_item_p->gNB_DU_System_Information->sIB1_message.size; +// LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).sib1[%d] %s , len = %d \n", +// i, M2AP_SETUP_REQ(message_p).sib1[i], M2AP_SETUP_REQ(message_p).sib1_length[i]); +// } + + + //printf("m2ap_mce_data_from_enb->assoc_id %d %d\n",m2ap_mce_data_from_enb->assoc_id,assoc_id); + + *m2ap_mce_data_from_enb = M2AP_SETUP_REQ(message_p); + //printf("m2ap_mce_data_from_enb->assoc_id %d %d\n",m2ap_mce_data_from_enb->assoc_id,assoc_id); + +// MSC_LOG_TX_MESSAGE( +// MSC_M2AP_MCE, +// MSC_RRC_ENB, +// 0, +// 0, +// MSC_AS_TIME_FMT" MCE_handle_M2_SETUP_REQUEST", +// 0,0//MSC_AS_TIME_ARGS(ctxt_pP), +// ); +// + if (num_mbms_available > 0) { + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + } else { + //MCE_send_M2_SETUP_FAILURE(instance); + return -1; + } +// return 0; + //TEST POINT MCE -> eNB +// if(1){ +// printf("instance %d\n",instance); +// //MCE_send_M2_SETUP_RESPONSE(instance,assoc_id,m2ap_mce_data_from_enb->assoc_id); +// //MCE_send_MBMS_SESSION_START_REQUEST(instance,assoc_id); +// //MCE_send_MBMS_SESSION_STOP_REQUEST(instance,assoc_id); +// //MCE_send_MBMS_SCHEDULING_INFORMATION(instance,assoc_id,NULL); //TODO +// } +// else +// MCE_send_M2_SETUP_FAILURE(instance,assoc_id); + + return 0; +} + +int MCE_send_M2_SETUP_RESPONSE(instance_t instance, /*uint32_t assoc_id,*/ + m2ap_setup_resp_t *m2ap_setup_resp) { + + //module_id_t mce_mod_idP; + //module_id_t enb_mod_idP; + + // This should be fixed + //enb_mod_idP = (module_id_t)0; + //mce_mod_idP = (module_id_t)0; + + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupResponse_t *out; + M2AP_M2SetupResponse_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + //int j = 0; + + AssertFatal(m2ap_setup_resp!=NULL,"m2ap_setup_resp = NULL\n"); + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse; + + /* mandatory */ + /* c1. GlobalMCE ID (integer value)*/ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID; + ie->criticality = M2AP_Criticality_reject; //? + ie->value.present = M2AP_M2SetupResponse_Ies__value_PR_GlobalMCE_ID; + //ie->value.choice.TransactionID = M2AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP); + MCC_MNC_TO_PLMNID(m2ap_setup_resp->mcc, m2ap_setup_resp->mnc, m2ap_setup_resp->mnc_digit_length, + &ie->value.choice.GlobalMCE_ID.pLMN_Identity); + + ie->value.choice.GlobalMCE_ID.mCE_ID.buf =calloc(2, sizeof(uint8_t)); + ie->value.choice.GlobalMCE_ID.mCE_ID.buf[0] = (m2ap_setup_resp->MCE_id) >> 8; + ie->value.choice.GlobalMCE_ID.mCE_ID.buf[1] = ((m2ap_setup_resp->MCE_id) & 0x0ff); + ie->value.choice.GlobalMCE_ID.mCE_ID.size=2; + //ie->value.choice.GlobalMCE_ID.mCE_ID.bits_unused=0; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c2. MCEname */ + if (m2ap_setup_resp->MCE_name != NULL) { + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCEname; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_M2SetupResponse_Ies__value_PR_MCEname; + OCTET_STRING_fromBuf(&ie->value.choice.MCEname, m2ap_setup_resp->MCE_name, + strlen(m2ap_setup_resp->MCE_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c3. cells to be Activated list */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_M2SetupResponse_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea; + + for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++) + { + + M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t * mcch_related_bcch_config_per_mbsfn_area_item_ies; + mcch_related_bcch_config_per_mbsfn_area_item_ies = (M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t*)calloc(1,sizeof(M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t)); + mcch_related_bcch_config_per_mbsfn_area_item_ies->id=M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + mcch_related_bcch_config_per_mbsfn_area_item_ies->criticality = M2AP_Criticality_ignore; + mcch_related_bcch_config_per_mbsfn_area_item_ies->value.present=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + + + M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item_t * config_per_mbsfn_area_item; + config_per_mbsfn_area_item = &mcch_related_bcch_config_per_mbsfn_area_item_ies->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + { + config_per_mbsfn_area_item->pdcchLength=m2ap_setup_resp->mcch_config_per_mbsfn[i].pdcch_length;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__pdcchLength_s1; + config_per_mbsfn_area_item->offset=m2ap_setup_resp->mcch_config_per_mbsfn[i].offset;//0; + config_per_mbsfn_area_item->repetitionPeriod=m2ap_setup_resp->mcch_config_per_mbsfn[i].repetition_period;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__repetitionPeriod_rf32; + config_per_mbsfn_area_item->modificationPeriod=m2ap_setup_resp->mcch_config_per_mbsfn[i].modification_period;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modificationPeriod_rf512; + config_per_mbsfn_area_item->subframeAllocationInfo.buf = MALLOC(1); + config_per_mbsfn_area_item->subframeAllocationInfo.size=1; + /*char * t; + int bits=7; + for( t = m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info; *t != '\0'; t++,bits--){ + if(*t=='1'){ + config_per_mbsfn_area_item->subframeAllocationInfo.buf[0] |= (uint8_t)(0x1<subframeAllocationInfo.buf[0] = (uint8_t)((m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info & 0x3F)<<2); + + //config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]=0x1<<7; + config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused=2; + + //memset(&config_per_mbsfn_area_item->subframeAllocationInfo,0,sizeof(BIT_STRING_t)); + + config_per_mbsfn_area_item->modulationAndCodingScheme = m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs;//M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modulationAndCodingScheme_n2; + ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,mcch_related_bcch_config_per_mbsfn_area_item_ies); + } + + } + + //config_per_mbsfn_area_item->cellInformationList = ;//(M2AP_Cell_Information_List*)calloc(1,sizeof(M2AP_Cell_Information_List)); + + + //config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused = 4; + + //ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,config_per_mbsfn_area_item); + //config_per_mbsfn_area_item = &ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea; + //{ + + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_t */ + //... + +// int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate; +// LOG_D(M2AP, "num_cells_to_activate = %d \n", num_cells_to_activate); +// for (i=0; +// iid = M2AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; +// cells_to_be_activated_list_item_ies->criticality = M2AP_Criticality_reject; +// cells_to_be_activated_list_item_ies->value.present = M2AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; +// +// /* 3.1 cells to be Activated list item */ +// M2AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item; +// memset((void *)&cells_to_be_activated_list_item, 0, sizeof(M2AP_Cells_to_be_Activated_List_Item_t)); +// +// /* - nRCGI */ +// M2AP_NRCGI_t nRCGI; +// MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i], +// &nRCGI.pLMN_Identity); +// NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity); +// cells_to_be_activated_list_item.nRCGI = nRCGI; +// +// /* optional */ +// /* - nRPCI */ +// if (1) { +// cells_to_be_activated_list_item.nRPCI = (M2AP_NRPCI_t *)calloc(1, sizeof(M2AP_NRPCI_t)); +// *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i]; // int 0..1007 +// } +// +// /* optional */ +// /* - gNB-MCE System Information */ +// if (1) { +// /* 3.1.2 gNB-MCESystem Information */ +// M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs; +// cells_to_be_activated_list_itemExtIEs = (M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemExtIEs_t)); +// cells_to_be_activated_list_itemExtIEs->id = M2AP_ProtocolIE_ID_id_gNB_MCESystemInformation; +// cells_to_be_activated_list_itemExtIEs->criticality = M2AP_Criticality_reject; +// cells_to_be_activated_list_itemExtIEs->extensionValue.present = M2AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_MCESystemInformation; +// +// M2AP_GNB_MCESystemInformation_t *gNB_MCESystemInformation = (M2AP_GNB_MCESystemInformation_t *)calloc(1, sizeof(M2AP_GNB_MCESystemInformation_t)); +// //LOG_I(M2AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]); +// //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++) +// // printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]); +// //printf("\n"); +// OCTET_STRING_fromBuf(&gNB_MCESystemInformation->sImessage, +// (const char*)f1ap_setup_resp->SI_container[i][0], +// f1ap_setup_resp->SI_container_length[i][0]); +// +// LOG_D(M2AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]); +// cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_MCESystemInformation = *gNB_MCESystemInformation; +// +// +// M2AP_ProtocolExtensionContainer_160P9_t p_160P9_t; +// memset((void *)&p_160P9_t, 0, sizeof(M2AP_ProtocolExtensionContainer_160P9_t)); +// +// ASN_SEQUENCE_ADD(&p_160P9_t.list, +// cells_to_be_activated_list_itemExtIEs); +// cells_to_be_activated_list_item.iE_Extensions = (struct M2AP_ProtocolExtensionContainer*)&p_160P9_t; +// +// } +// /* ADD */ +// cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item; +// ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, +// cells_to_be_activated_list_item_ies); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 response\n"); + return -1; + } + + //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_du->assoc_id, buffer, len, 0); + //printf(",m2ap_mce_data_from_enb->assoc_id %d\n",m2ap_mce_data_from_enb->assoc_id); + + + m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); + + return 0; +} + +int MCE_send_M2_SETUP_FAILURE(instance_t instance,m2ap_setup_failure_t* m2ap_setup_failure) { + + // module_id_t enb_mod_idP; + //module_id_t mce_mod_idP; + + // This should be fixed + //enb_mod_idP = (module_id_t)0; + //mce_mod_idP = (module_id_t)0; + + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupFailure_t *out; + M2AP_M2SetupFailure_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; + //pdu.choice.unsuccessfulOutcome = (M2AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M2AP_UnsuccessfulOutcome_t)); + pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure; + + /* mandatory */ + /* c1. Transaction ID (integer value)*/ + // ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + // ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; + // ie->criticality = M2AP_Criticality_reject; + // ie->value.present = M2AP_M2SetupFailure_Ies__value_PR_GlobalENB_ID; + // ie->value.choice.GlobalENB_ID = M2AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP); + // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. Cause */ + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_Cause; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_M2SetupFailure_Ies__value_PR_Cause; + ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_unspecified; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. TimeToWait */ + if (0) { + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_TimeToWait; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_M2SetupFailure_Ies__value_PR_TimeToWait; + ie->value.choice.TimeToWait = M2AP_TimeToWait_v10s; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c4. CriticalityDiagnostics*/ + if (0) { + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_M2SetupFailure_Ies__value_PR_CriticalityDiagnostics; + ie->value.choice.CriticalityDiagnostics.procedureCode = (M2AP_ProcedureCode_t *)calloc(1, sizeof(M2AP_ProcedureCode_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCode = M2AP_ProcedureCode_id_m2Setup; + ie->value.choice.CriticalityDiagnostics.triggeringMessage = (M2AP_TriggeringMessage_t *)calloc(1, sizeof(M2AP_TriggeringMessage_t)); + *ie->value.choice.CriticalityDiagnostics.triggeringMessage = M2AP_TriggeringMessage_initiating_message; + ie->value.choice.CriticalityDiagnostics.procedureCriticality = (M2AP_Criticality_t *)calloc(1, sizeof(M2AP_Criticality_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCriticality = M2AP_Criticality_reject; + //ie->value.choice.CriticalityDiagnostics.transactionID = (M2AP_TransactionID_t *)calloc(1, sizeof(M2AP_TransactionID_t)); + //*ie->value.choice.CriticalityDiagnostics.transactionID = 0; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 setup request\n"); + return -1; + } + + //mce_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_enb->assoc_id, buffer, len, 0); + m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); + + return 0; +} + +/* + * MCE Configuration Update + */ + +int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP){ + AssertFatal(1==0,"Not implemented yet\n"); + + + M2AP_M2AP_PDU_t pdu; + M2AP_MCEConfigurationUpdate_t *out; + M2AP_MCEConfigurationUpdate_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + //int j = 0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mCEConfigurationUpdate; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MCEConfigurationUpdate; + out = &pdu.choice.initiatingMessage.value.choice.MCEConfigurationUpdate; + + /* mandatory */ + /* c1. Transaction ID (integer value)*/ + ie = (M2AP_MCEConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_MCEConfigurationUpdate_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID; + ie->criticality = M2AP_Criticality_reject; //? + ie->value.present = M2AP_MCEConfigurationUpdate_Ies__value_PR_GlobalMCE_ID; + //ie->value.choice.TransactionID = M2AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP); + MCC_MNC_TO_PLMNID(0,0,3/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/ + ,&ie->value.choice.GlobalMCE_ID.pLMN_Identity); + + ie->value.choice.GlobalMCE_ID.mCE_ID.buf =calloc(2, sizeof(uint8_t)); + ie->value.choice.GlobalMCE_ID.mCE_ID.size=2; + //ie->value.choice.GlobalMCE_ID.mCE_ID.bits_unused=6; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c2. MCEname */ + //if (m2ap_setup_resp->MCEname != NULL) { + // ie = (M2AP_MCEConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_MCEConfigurationUpdate_Ies_t)); + // ie->id = M2AP_ProtocolIE_ID_id_MCEname; + // ie->criticality = M2AP_Criticality_ignore; + // ie->value.present = M2AP_MCEConfigurationUpdate_Ies__value_PR_MCEname; + // OCTET_STRING_fromBuf(&ie->value.choice.MCEname, m2ap_setup_resp->MCEname, + // strlen(m2ap_setup_resp->MCEname)); + // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + //} + + /* mandatory */ + /* c3. cells to be Activated list */ + ie = (M2AP_MCEConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_MCEConfigurationUpdate_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MCEConfigurationUpdate_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea; + + M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t * mcch_related_bcch_config_per_mbsfn_area_item_ies; + mcch_related_bcch_config_per_mbsfn_area_item_ies = (M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t*)calloc(1,sizeof(M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs_t)); + mcch_related_bcch_config_per_mbsfn_area_item_ies->id=M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + mcch_related_bcch_config_per_mbsfn_area_item_ies->criticality = M2AP_Criticality_ignore; + mcch_related_bcch_config_per_mbsfn_area_item_ies->value.present=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_ItemIEs__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + + M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item_t * config_per_mbsfn_area_item; + config_per_mbsfn_area_item = &mcch_related_bcch_config_per_mbsfn_area_item_ies->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + { + config_per_mbsfn_area_item->pdcchLength=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__pdcchLength_s1; + config_per_mbsfn_area_item->offset=0; + config_per_mbsfn_area_item->repetitionPeriod=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__repetitionPeriod_rf32; + config_per_mbsfn_area_item->modificationPeriod=M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modificationPeriod_rf512; + config_per_mbsfn_area_item->subframeAllocationInfo.buf = MALLOC(1); + config_per_mbsfn_area_item->subframeAllocationInfo.size=1; + //config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]=0x1<<7; + config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused=2; + + //memset(&config_per_mbsfn_area_item->subframeAllocationInfo,0,sizeof(BIT_STRING_t)); + + config_per_mbsfn_area_item->modulationAndCodingScheme = M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item__modulationAndCodingScheme_n2; + ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,mcch_related_bcch_config_per_mbsfn_area_item_ies); + } + + //config_per_mbsfn_area_item->cellInformationList = ;//(M2AP_Cell_Information_List*)calloc(1,sizeof(M2AP_Cell_Information_List)); + + + //config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused = 4; + + //ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,config_per_mbsfn_area_item); + //config_per_mbsfn_area_item = &ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea; + //{ + + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_t */ + //... + +// int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate; +// LOG_D(M2AP, "num_cells_to_activate = %d \n", num_cells_to_activate); +// for (i=0; +// iid = M2AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; +// cells_to_be_activated_list_item_ies->criticality = M2AP_Criticality_reject; +// cells_to_be_activated_list_item_ies->value.present = M2AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; +// +// /* 3.1 cells to be Activated list item */ +// M2AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item; +// memset((void *)&cells_to_be_activated_list_item, 0, sizeof(M2AP_Cells_to_be_Activated_List_Item_t)); +// +// /* - nRCGI */ +// M2AP_NRCGI_t nRCGI; +// MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i], +// &nRCGI.pLMN_Identity); +// NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity); +// cells_to_be_activated_list_item.nRCGI = nRCGI; +// +// /* optional */ +// /* - nRPCI */ +// if (1) { +// cells_to_be_activated_list_item.nRPCI = (M2AP_NRPCI_t *)calloc(1, sizeof(M2AP_NRPCI_t)); +// *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i]; // int 0..1007 +// } +// +// /* optional */ +// /* - gNB-MCE System Information */ +// if (1) { +// /* 3.1.2 gNB-MCESystem Information */ +// M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs; +// cells_to_be_activated_list_itemExtIEs = (M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemExtIEs_t)); +// cells_to_be_activated_list_itemExtIEs->id = M2AP_ProtocolIE_ID_id_gNB_MCESystemInformation; +// cells_to_be_activated_list_itemExtIEs->criticality = M2AP_Criticality_reject; +// cells_to_be_activated_list_itemExtIEs->extensionValue.present = M2AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_MCESystemInformation; +// +// M2AP_GNB_MCESystemInformation_t *gNB_MCESystemInformation = (M2AP_GNB_MCESystemInformation_t *)calloc(1, sizeof(M2AP_GNB_MCESystemInformation_t)); +// //LOG_I(M2AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]); +// //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++) +// // printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]); +// //printf("\n"); +// OCTET_STRING_fromBuf(&gNB_MCESystemInformation->sImessage, +// (const char*)f1ap_setup_resp->SI_container[i][0], +// f1ap_setup_resp->SI_container_length[i][0]); +// +// LOG_D(M2AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]); +// cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_MCESystemInformation = *gNB_MCESystemInformation; +// +// +// M2AP_ProtocolExtensionContainer_160P9_t p_160P9_t; +// memset((void *)&p_160P9_t, 0, sizeof(M2AP_ProtocolExtensionContainer_160P9_t)); +// +// ASN_SEQUENCE_ADD(&p_160P9_t.list, +// cells_to_be_activated_list_itemExtIEs); +// cells_to_be_activated_list_item.iE_Extensions = (struct M2AP_ProtocolExtensionContainer*)&p_160P9_t; +// +// } +// /* ADD */ +// cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item; +// ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, +// cells_to_be_activated_list_item_ies); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 response\n"); + return -1; + } + + //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_du->assoc_id, buffer, len, 0); + //printf(",m2ap_mce_data_from_enb->assoc_id %d\n",m2ap_mce_data_from_enb->assoc_id); + + m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); + + + + +} + + +int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + + LOG_D(M2AP, "MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE\n"); + + M2AP_MCEConfigurationUpdateFailure_t *in = &pdu->choice.unsuccessfulOutcome.value.choice.MCEConfigurationUpdateFailure; + + + //M2AP_MCEConfigurationUpdateFailure_Ies_t *ie; + + + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_FAILURE); + + LOG_D(M2AP, "M2AP: MCEConfigurationUpdate-Failure: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + // for (int i=0;i < in->protocolIEs.list.count; i++) { + // ie = in->protocolIEs.list.array[i]; + // // switch (ie->id) { + // // case M2AP_ProtocolIE_ID_id_TimeToWait: + // // AssertFatal(ie->criticality == M2AP_Criticality_ignore, + // // "ie->criticality != M2AP_Criticality_ignore\n"); + // // AssertFatal(ie->value.present == M2AP_M2SetupFailure_Ies__value_PR_TimeToWait, + // // "ie->value.present != M2AP_M2SetupFailure_Ies__value_PR_TimeToWait\n"); + // // LOG_D(M2AP, "M2AP: M2Setup-Failure: TimeToWait %d\n");/*, + // // GlobalMCE_ID);*/ + // // break; + // // } + // } + //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n"); + //AssertFatal(num_cells_to_activate>0,"No cells activated\n"); + //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate; + + //for (int i=0;i 0, "System Information %d is missing",i); + + //MSC_LOG_RX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_CU, + // 0, + // 0, + // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id)); + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + return 0; + +} + + +int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M2AP, "MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_MCEConfigurationUpdateAcknowledge_t *container; + //M2AP_MCEConfigurationUpdateAcknowledge_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.MCEConfigurationUpdate; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_ACK); + + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + return 0; + +} + + +/* + * ENB Configuration Update + */ + + +int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M2AP, "MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_MCEConfigurationUpdateAcknowledge_t *container; + //M2AP_MCEConfigurationUpdateAcknowledge_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.MCEConfigurationUpdate; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_ACK); + + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + return 0; + +} + + +int MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + m2ap_enb_configuration_update_failure_t * m2ap_enb_configuration_update_failure){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + +int MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + m2ap_enb_configuration_update_ack_t *m2ap_enb_configuration_update_ack){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + +/* + * Error Indication + */ + +int MCE_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); + + +} + +int MCE_send_ERROR_INDICATION(instance_t instance, M2AP_ErrorIndication_t *ErrorIndication) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + + + +/* + * Session Update Request + */ +int MCE_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m2ap_mbms_session_update_req_t * m2ap_mbms_session_update_req){ + AssertFatal(1==0,"Not implemented yet\n"); + //M2AP_SessionUpdateRequest_t SessionUpdateRequest; +} + + + +int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + + +int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + +/* + * Service Counting Request + */ +int MCE_send_MBMS_SERVICE_COUNTING_REQUEST(instance_t instance, module_id_t du_mod_idP){ + AssertFatal(1==0,"Not implemented yet\n"); + //M2AP_MbmsServiceCountingRequest_t MbmsServiceCountingRequest; +} + + + +int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + + + +int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + +/* + * Service Counting Results Report + */ + +int MCE_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + +/* + * Overload Notification + */ +int MCE_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + + + diff --git a/openair2/M2AP/m2ap_MCE_interface_management.h b/openair2/M2AP/m2ap_MCE_interface_management.h new file mode 100644 index 0000000000..6b899e9ea2 --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_interface_management.h @@ -0,0 +1,196 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_interface_management.h + * \brief m2ap interface management for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#ifndef M2AP_MCE_INTERFACE_MANAGEMENT_H_ +#define M2AP_MCE_INTERFACE_MANAGEMENT_H_ +/* + * MBMS Session start + */ +int MCE_send_MBMS_SESSION_START_REQUEST(instance_t instance/*, + uint32_t assoc_id*/,m2ap_session_start_req_t* m2ap_session_start_req); +int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_handle_MBMS_SESSION_START_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +/* + * MBMS Session stop + */ +int MCE_send_MBMS_SESSION_STOP_REQUEST(instance_t instance, + m2ap_session_stop_req_t* m2ap_session_stop_req); + +int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * MBMS Scheduling Information + */ +int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, + /*uint32_t assoc_id,*/ m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information ); + +int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + + + +/* + * Reset + */ +int MCE_send_RESET(instance_t instance, m2ap_reset_t * m2ap_reset); + +int MCE_handle_RESET_ACKKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +int MCE_send_RESET_ACKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge); + +/* + * M2AP Setup + */ +int MCE_handle_M2_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_send_M2_SETUP_RESPONSE(instance_t instance,/*uint32_t assoc_id,*/ m2ap_setup_resp_t *m2ap_setup_resp); + +int MCE_send_M2_SETUP_FAILURE(instance_t instance, /*uint32_t assoc_id*/ m2ap_setup_failure_t * m2ap_setup_failure); + + +/* + * MCE Configuration Update + */ + +int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP); + +int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * ENB Configuration Update + */ + + +int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + m2ap_enb_configuration_update_failure_t *m2ap_enb_configuration_update_failure); + +int MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + m2ap_enb_configuration_update_ack_t *m2ap_enb_configuration_update_ack); +/* + * Error Indication + */ +int MCE_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +int MCE_send_ERROR_INDICATION(instance_t instance, M2AP_ErrorIndication_t *ErrorIndication); + + +/* + * Session Update Request + */ +int MCE_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m2ap_mbms_session_update_req_t * m2ap_mbms_session_update_req); + +int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * Service Counting Request + */ +int MCE_send_MBMS_SERVICE_COUNTING_REQUEST(instance_t instance, module_id_t du_mod_idP); + +int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +/* + * Service Counting Results Report + */ + +int MCE_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * Overload Notification + */ +int MCE_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + + + + + +#endif /* M2AP_MCE_INTERFACE_MANAGEMENT_H_ */ + + + diff --git a/openair2/M2AP/m2ap_MCE_management_procedures.c b/openair2/M2AP/m2ap_MCE_management_procedures.c new file mode 100644 index 0000000000..007340501a --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_management_procedures.c @@ -0,0 +1,257 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_management_procedures.c + * \brief m2ap tasks for MCE + * \author Javier Morgade + * \date 2018 + * \version 1.0 + */ + +#include +#include +#include + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "m2ap_common.h" +#include "m2ap_MCE_defs.h" +#include "m2ap_MCE.h" + + +#define M2AP_DEBUG_LIST +#ifdef M2AP_DEBUG_LIST +# define M2AP_MCE_LIST_OUT(x, args...) M2AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args) +#else +# define M2AP_MCE_LIST_OUT(x, args...) +#endif + +static int indent = 0; + + +m2ap_MCE_internal_data_t m2ap_MCE_internal_data; + +RB_GENERATE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id); + +int m2ap_MCE_compare_assoc_id( + struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2) +{ + if (p1->assoc_id == -1) { + if (p1->cnx_id < p2->cnx_id) { + return -1; + } + + if (p1->cnx_id > p2->cnx_id) { + return 1; + } + } else { + if (p1->assoc_id < p2->assoc_id) { + return -1; + } + + if (p1->assoc_id > p2->assoc_id) { + return 1; + } + } + + /* Matching reference */ + return 0; +} + +uint16_t m2ap_MCE_fetch_add_global_cnx_id(void) +{ + return ++m2ap_MCE_internal_data.global_cnx_id; +} + +void m2ap_MCE_prepare_internal_data(void) +{ + memset(&m2ap_MCE_internal_data, 0, sizeof(m2ap_MCE_internal_data)); + STAILQ_INIT(&m2ap_MCE_internal_data.m2ap_MCE_instances_head); +} + +void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&m2ap_MCE_internal_data.m2ap_MCE_instances_head, + new_instance_p, m2ap_MCE_entries); +} + +void dump_mce_tree_m2(m2ap_MCE_data_t *t) +{ + if (t == NULL) return; + printf("-----------------------\n"); + printf("MCE id %d %s\n", t->MCE_id, t->MCE_name); + printf("state %d\n", t->state); + printf("nextstream %d\n", t->nextstream); + printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams); + printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id); + dump_mce_tree_m2(t->entry.rbe_left); + dump_mce_tree_m2(t->entry.rbe_right); +} + +void dump_mce_trees_m2(void) +{ +m2ap_MCE_instance_t *zz; +STAILQ_FOREACH(zz, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, + m2ap_MCE_entries) { +printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +dump_mce_tree_m2(zz->m2ap_mce_head.rbh_root); +printf("---------------------------------------------\n"); +} +} + +struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id) +{ + struct m2ap_MCE_data_s temp; + struct m2ap_MCE_data_s *found; + +printf("m2ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +dump_mce_trees_m2(); + + memset(&temp, 0, sizeof(struct m2ap_MCE_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, + m2ap_MCE_entries) { + found = RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp); + } + + return NULL; +} + + +m2ap_MCE_instance_t *m2ap_MCE_get_instance(instance_t instance) +{ + m2ap_MCE_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, + m2ap_MCE_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} + +/// utility functions + +void m2ap_dump_MCE (m2ap_MCE_data_t * MCE_ref); + +void +m2ap_dump_MCE_list (void) { + m2ap_MCE_instance_t *inst = NULL; + struct m2ap_MCE_data_s *found = NULL; + struct m2ap_MCE_data_s temp; + + memset(&temp, 0, sizeof(struct m2ap_MCE_data_s)); + + STAILQ_FOREACH (inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) { + found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp); + m2ap_dump_MCE (found); + } +} + +void m2ap_dump_MCE (m2ap_MCE_data_t * MCE_ref) { + + if (MCE_ref == NULL) { + return; + } + + M2AP_MCE_LIST_OUT (""); + M2AP_MCE_LIST_OUT ("MCE name: %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name); + M2AP_MCE_LIST_OUT ("MCE STATE: %07x", MCE_ref->state); + M2AP_MCE_LIST_OUT ("MCE ID: %07x", MCE_ref->MCE_id); + indent++; + M2AP_MCE_LIST_OUT ("SCTP cnx id: %d", MCE_ref->cnx_id); + M2AP_MCE_LIST_OUT ("SCTP assoc id: %d", MCE_ref->assoc_id); + M2AP_MCE_LIST_OUT ("SCTP instreams: %d", MCE_ref->in_streams); + M2AP_MCE_LIST_OUT ("SCTP outstreams: %d", MCE_ref->out_streams); + indent--; +} + +m2ap_MCE_data_t * m2ap_is_MCE_pci_in_list (const uint32_t pci) +{ + m2ap_MCE_instance_t *inst; + struct m2ap_MCE_data_s *elm; + + STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) { + RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) { + for (int i = 0; inum_cc; i++) { + if (elm->Nid_cell[i] == pci) { + return elm; + } + } + } + } + return NULL; +} + +m2ap_MCE_data_t * m2ap_is_MCE_id_in_list (const uint32_t MCE_id) +{ + m2ap_MCE_instance_t *inst; + struct m2ap_MCE_data_s *elm; + + STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) { + RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) { + if (elm->MCE_id == MCE_id) + return elm; + } + } + return NULL; +} + +m2ap_MCE_data_t * m2ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id) +{ + m2ap_MCE_instance_t *inst; + struct m2ap_MCE_data_s *found; + struct m2ap_MCE_data_s temp; + + temp.assoc_id = sctp_assoc_id; + temp.cnx_id = -1; + + STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) { + found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp); + if (found != NULL){ + if (found->assoc_id == sctp_assoc_id) { + return found; + } + } + } + return NULL; +} diff --git a/openair2/M2AP/m2ap_MCE_management_procedures.h b/openair2/M2AP/m2ap_MCE_management_procedures.h new file mode 100644 index 0000000000..9e13e723c9 --- /dev/null +++ b/openair2/M2AP/m2ap_MCE_management_procedures.h @@ -0,0 +1,54 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_management_procedures.h + * \brief m2ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_MCE_MANAGEMENT_PROCEDURES_H_ +#define M2AP_MCE_MANAGEMENT_PROCEDURES_H + +void m2ap_MCE_prepare_internal_data(void); + +void dump_trees_m2(void); + +void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p); + +m2ap_MCE_instance_t *m2ap_MCE_get_instance(uint8_t mod_id); + +uint16_t m2ap_MCE_fetch_add_global_cnx_id(void); + +void m2ap_MCE_prepare_internal_data(void); + +m2ap_MCE_data_t* m2ap_is_MCE_id_in_list(uint32_t MCE_id); + +m2ap_MCE_data_t* m2ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id); + +m2ap_MCE_data_t* m2ap_is_MCE_pci_in_list (const uint32_t pci); + +struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id); + +#endif /* M2AP_MCE_MANAGEMENT_PROCEDURES_H_ */ diff --git a/openair2/M2AP/m2ap_common.h b/openair2/M2AP/m2ap_common.h index 3c8fcbc462..95da064b4a 100644 --- a/openair2/M2AP/m2ap_common.h +++ b/openair2/M2AP/m2ap_common.h @@ -41,13 +41,6 @@ #ifndef M2AP_COMMON_H_ #define M2AP_COMMON_H_ -/*! \file m2ap_common.h - * \brief m2ap procedures for both eNB and MCE - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - /** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation * @ingroup _ref_implementation_ * @{ diff --git a/openair2/M2AP/m2ap_decoder.c b/openair2/M2AP/m2ap_decoder.c new file mode 100644 index 0000000000..1237c4ec8e --- /dev/null +++ b/openair2/M2AP/m2ap_decoder.c @@ -0,0 +1,194 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_decoder.c + * \brief m2ap decoder procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "assertions.h" +#include "intertask_interface.h" +#include "m2ap_common.h" +#include "m2ap_decoder.h" + +static int m2ap_decode_initiating_message(M2AP_M2AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage.procedureCode) { + case M2AP_ProcedureCode_id_sessionStart: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + case M2AP_ProcedureCode_id_sessionStop: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + case M2AP_ProcedureCode_id_m2Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + case M2AP_ProcedureCode_id_mbmsSchedulingInformation: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + + + +// case M2AP_ProcedureCode_id_handoverPreparation: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); +// M2AP_INFO("m2ap__decode_initiating_message!\n"); +// break; +// +// case M2AP_ProcedureCode_id_uEContextRelease: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); +// M2AP_INFO("m2ap__decode_initiating_message!\n"); +// break; +// +// case M2AP_ProcedureCode_id_handoverCancel: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); +// M2AP_INFO("m2ap__decode_initiating_message!\n"); +// break; +// + default: + M2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage.procedureCode); + AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage.procedureCode); + return -1; + } + + return 0; +} + +static int m2ap_decode_successful_outcome(M2AP_M2AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome.procedureCode) { + case M2AP_ProcedureCode_id_sessionStart: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_successfuloutcome_message!\n"); + break; + case M2AP_ProcedureCode_id_sessionStop: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n"); + break; + case M2AP_ProcedureCode_id_m2Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n"); + break; + case M2AP_ProcedureCode_id_mbmsSchedulingInformation: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n"); + break; + + +// case M2AP_ProcedureCode_id_handoverPreparation: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); +// M2AP_INFO("m2ap__decode_successfuloutcome_message!\n"); +// break; +// + default: + M2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.successfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +static int m2ap_decode_unsuccessful_outcome(M2AP_M2AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome.procedureCode) { + case M2AP_ProcedureCode_id_sessionStart: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + case M2AP_ProcedureCode_id_sessionStop: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + case M2AP_ProcedureCode_id_m2Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + case M2AP_ProcedureCode_id_mbmsSchedulingInformation: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu); + M2AP_INFO("m2ap__decode_initiating_message!\n"); + break; + + + default: + M2AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +{ + asn_dec_rval_t dec_ret; + + DevAssert(buffer != NULL); + + dec_ret = aper_decode(NULL, + &asn_DEF_M2AP_M2AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, pdu); + } + + if (dec_ret.code != RC_OK) { + M2AP_ERROR("Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case M2AP_M2AP_PDU_PR_initiatingMessage: + return m2ap_decode_initiating_message(pdu); + + case M2AP_M2AP_PDU_PR_successfulOutcome: + return m2ap_decode_successful_outcome(pdu); + + case M2AP_M2AP_PDU_PR_unsuccessfulOutcome: + return m2ap_decode_unsuccessful_outcome(pdu); + + default: + M2AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + + return -1; +} diff --git a/openair2/M2AP/m2ap_decoder.h b/openair2/M2AP/m2ap_decoder.h new file mode 100644 index 0000000000..6ab01fe703 --- /dev/null +++ b/openair2/M2AP/m2ap_decoder.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_decoder.h + * \brief m2ap decoder procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_DECODER_H_ +#define M2AP_DECODER_H_ + +int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +__attribute__ ((warn_unused_result)); + +#endif /* M2AP_DECODER_H_ */ diff --git a/openair2/M2AP/m2ap_default_values.h b/openair2/M2AP/m2ap_default_values.h new file mode 100644 index 0000000000..baae4b963c --- /dev/null +++ b/openair2/M2AP/m2ap_default_values.h @@ -0,0 +1,47 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_default_values.h + * \brief default values for m2ap procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#ifndef M2AP_DEFAULT_VALUES_H_ +#define M2AP_DEFAULT_VALUES_H_ + +#define ENB_TAC (1) +#define ENB_MCC (208) +#define ENB_MNC (92) + +#define ENB_NAME "Eurecom ENB" +#define ENB_NAME_FORMAT (ENB_NAME" %u") + +#define M2AP_PORT_NUMBER (36443) +#define M2AP_SCTP_PPID (43) + +#endif /* M2AP_DEFAULT_VALUES_H_ */ + diff --git a/openair2/M2AP/m2ap_eNB.c b/openair2/M2AP/m2ap_eNB.c new file mode 100644 index 0000000000..206b7cf8ca --- /dev/null +++ b/openair2/M2AP/m2ap_eNB.c @@ -0,0 +1,704 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB.c + * \brief m2ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include +#include +#include + +#include "intertask_interface.h" + +#include "m2ap_eNB.h" +#include "m2ap_eNB_defs.h" +#include "m2ap_eNB_management_procedures.h" +#include "m2ap_eNB_handler.h" +#include "m2ap_eNB_generate_messages.h" +#include "m2ap_common.h" +#include "m2ap_eNB_interface_management.h" +#include "m2ap_ids.h" +#include "m2ap_timers.h" + +#include "queue.h" +#include "assertions.h" +#include "conversions.h" + +struct m2ap_enb_map; +struct m2ap_eNB_data_s; + +m2ap_setup_req_t * m2ap_enb_data_g; + +RB_PROTOTYPE(m2ap_enb_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id); + +static +void m2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); + +static +void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +static +void m2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind); + +static +void m2ap_eNB_handle_register_eNB(instance_t instance, + m2ap_register_enb_req_t *m2ap_register_eNB); +static +void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p, + net_ip_address_t *target_eNB_ip_addr, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t enb_port_for_M2C, + int multi_sd); + +//static +//void m2ap_eNB_handle_handover_req(instance_t instance, +// m2ap_handover_req_t *m2ap_handover_req); +// +//static +//void m2ap_eNB_handle_handover_req_ack(instance_t instance, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack); +// +//static +//void m2ap_eNB_ue_context_release(instance_t instance, +// m2ap_ue_context_release_t *m2ap_ue_context_release); +// + +static +void m2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { + int result; + DevAssert(sctp_data_ind != NULL); + m2ap_eNB_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + +static +void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + m2ap_eNB_instance_t *instance_p; + m2ap_eNB_data_t *m2ap_enb_data_p; + DevAssert(sctp_new_association_resp != NULL); + // printf("m2ap_eNB_handle_sctp_association_resp at 1\n"); + // dump_trees_m2(); + instance_p = m2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + /* if the assoc_id is already known, it is certainly because an IND was received + * before. In this case, just update streams and return + */ + if (sctp_new_association_resp->assoc_id != -1) { + m2ap_enb_data_p = m2ap_get_eNB(instance_p, sctp_new_association_resp->assoc_id, + sctp_new_association_resp->ulp_cnx_id); + + if (m2ap_enb_data_p != NULL) { + /* some sanity check - to be refined at some point */ + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + M2AP_ERROR("m2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); + abort(); + } + + m2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; + m2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams; + return; + } + } + + m2ap_enb_data_p = m2ap_get_eNB(instance_p, -1, + sctp_new_association_resp->ulp_cnx_id); + DevAssert(m2ap_enb_data_p != NULL); + //printf("m2ap_eNB_handle_sctp_association_resp at 2\n"); + //dump_trees_m2(); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + //m2ap_handle_m2_setup_message(instance_p, m2ap_enb_data_p, + // sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; + } + + //printf("m2ap_eNB_handle_sctp_association_resp at 3\n"); + //dump_trees_m2(); + /* Update parameters */ + m2ap_enb_data_p->assoc_id = sctp_new_association_resp->assoc_id; + m2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; + m2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams; + //printf("m2ap_eNB_handle_sctp_association_resp at 4\n"); + //dump_trees_m2(); + + m2ap_enb_data_g->assoc_id = sctp_new_association_resp->assoc_id; + m2ap_enb_data_g->sctp_in_streams = sctp_new_association_resp->in_streams; + m2ap_enb_data_g->sctp_out_streams = sctp_new_association_resp->out_streams; + + /* Prepare new m2 Setup Request */ + //m2ap_eNB_generate_m2_setup_request(instance_p, m2ap_enb_data_p); + eNB_send_M2_SETUP_REQUEST(instance_p, m2ap_enb_data_p); + //eNB_send_M2_SETUP_REQUEST(instance_p, m2ap_enb_data_g); + +} + +static +void m2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { + m2ap_eNB_instance_t *instance_p; + m2ap_eNB_data_t *m2ap_enb_data_p; + //printf("m2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance); + //dump_trees_m2(); + DevAssert(sctp_new_association_ind != NULL); + instance_p = m2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + m2ap_enb_data_p = m2ap_get_eNB(instance_p, sctp_new_association_ind->assoc_id, -1); + + if (m2ap_enb_data_p != NULL) abort(); + + // DevAssert(m2ap_enb_data_p != NULL); + if (m2ap_enb_data_p == NULL) { + /* Create new eNB descriptor */ + m2ap_enb_data_p = calloc(1, sizeof(*m2ap_enb_data_p)); + DevAssert(m2ap_enb_data_p != NULL); + m2ap_enb_data_p->cnx_id = m2ap_eNB_fetch_add_global_cnx_id(); + m2ap_enb_data_p->m2ap_eNB_instance = instance_p; + /* Insert the new descriptor in list of known eNB + * but not yet associated. + */ + RB_INSERT(m2ap_enb_map, &instance_p->m2ap_enb_head, m2ap_enb_data_p); + m2ap_enb_data_p->state = M2AP_ENB_STATE_CONNECTED; + instance_p->m2_target_enb_nb++; + + if (instance_p->m2_target_enb_pending_nb > 0) { + instance_p->m2_target_enb_pending_nb--; + } + } else { + M2AP_WARN("m2ap_enb_data_p already exists\n"); + } + + //printf("m2ap_eNB_handle_sctp_association_ind at 2\n"); + //dump_trees_m2(); + /* Update parameters */ + m2ap_enb_data_p->assoc_id = sctp_new_association_ind->assoc_id; + m2ap_enb_data_p->in_streams = sctp_new_association_ind->in_streams; + m2ap_enb_data_p->out_streams = sctp_new_association_ind->out_streams; + //printf("m2ap_eNB_handle_sctp_association_ind at 3\n"); + //dump_trees_m2(); +} + +int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t enb_port_for_M2C) { + // Create and alloc new message + MessageDef *message; + sctp_init_t *sctp_init = NULL; + DevAssert(instance_p != NULL); + DevAssert(local_ip_addr != NULL); + message = itti_alloc_new_message (TASK_M2AP_ENB, SCTP_INIT_MSG_MULTI_REQ); + sctp_init = &message->ittiMsg.sctp_init_multi; + sctp_init->port = enb_port_for_M2C; + sctp_init->ppid = M2AP_SCTP_PPID; + sctp_init->ipv4 = 1; + sctp_init->ipv6 = 0; + sctp_init->nb_ipv4_addr = 1; +#if 0 + memcpy(&sctp_init->ipv4_address, + local_ip_addr, + sizeof(*local_ip_addr)); +#endif + sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + sctp_init->nb_ipv6_addr = 0; + sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); +} + +static void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p, + net_ip_address_t *target_eNB_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t enb_port_for_M2C, + int multi_sd) { + MessageDef *message = NULL; + sctp_new_association_req_multi_t *sctp_new_association_req = NULL; + m2ap_eNB_data_t *m2ap_enb_data = NULL; + DevAssert(instance_p != NULL); + DevAssert(target_eNB_ip_address != NULL); + message = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_NEW_ASSOCIATION_REQ_MULTI); + sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; + sctp_new_association_req->port = enb_port_for_M2C; + sctp_new_association_req->ppid = M2AP_SCTP_PPID; + sctp_new_association_req->in_streams = in_streams; + sctp_new_association_req->out_streams = out_streams; + sctp_new_association_req->multi_sd = multi_sd; + memcpy(&sctp_new_association_req->remote_address, + target_eNB_ip_address, + sizeof(*target_eNB_ip_address)); + memcpy(&sctp_new_association_req->local_address, + local_ip_addr, + sizeof(*local_ip_addr)); + /* Create new eNB descriptor */ + m2ap_enb_data = calloc(1, sizeof(*m2ap_enb_data)); + DevAssert(m2ap_enb_data != NULL); + m2ap_enb_data->cnx_id = m2ap_eNB_fetch_add_global_cnx_id(); + sctp_new_association_req->ulp_cnx_id = m2ap_enb_data->cnx_id; + m2ap_enb_data->assoc_id = -1; + m2ap_enb_data->m2ap_eNB_instance = instance_p; + + + m2ap_enb_data_g = (m2ap_setup_req_t*)calloc(1,sizeof(m2ap_setup_req_t)); + + + // + m2ap_enb_data->eNB_name = "enb_name"; + /* Insert the new descriptor in list of known eNB + * but not yet associated. + */ + RB_INSERT(m2ap_enb_map, &instance_p->m2ap_enb_head, m2ap_enb_data); + m2ap_enb_data->state = M2AP_ENB_STATE_WAITING; + instance_p->m2_target_enb_nb ++; + instance_p->m2_target_enb_pending_nb ++; + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message); +} + +static +void m2ap_eNB_handle_register_eNB(instance_t instance, + m2ap_register_enb_req_t *m2ap_register_eNB) { + m2ap_eNB_instance_t *new_instance; + DevAssert(m2ap_register_eNB != NULL); + /* Look if the provided instance already exists */ + new_instance = m2ap_eNB_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same eNB */ + DevCheck(new_instance->eNB_id == m2ap_register_eNB->eNB_id, new_instance->eNB_id, m2ap_register_eNB->eNB_id, 0); + DevCheck(new_instance->cell_type == m2ap_register_eNB->cell_type, new_instance->cell_type, m2ap_register_eNB->cell_type, 0); + DevCheck(new_instance->tac == m2ap_register_eNB->tac, new_instance->tac, m2ap_register_eNB->tac, 0); + DevCheck(new_instance->mcc == m2ap_register_eNB->mcc, new_instance->mcc, m2ap_register_eNB->mcc, 0); + DevCheck(new_instance->mnc == m2ap_register_eNB->mnc, new_instance->mnc, m2ap_register_eNB->mnc, 0); + M2AP_WARN("eNB[%d] already registered\n", instance); + } else { + new_instance = calloc(1, sizeof(m2ap_eNB_instance_t)); + DevAssert(new_instance != NULL); + RB_INIT(&new_instance->m2ap_enb_head); + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->eNB_name = m2ap_register_eNB->eNB_name; + new_instance->eNB_id = m2ap_register_eNB->eNB_id; + new_instance->cell_type = m2ap_register_eNB->cell_type; + new_instance->tac = m2ap_register_eNB->tac; + new_instance->mcc = m2ap_register_eNB->mcc; + new_instance->mnc = m2ap_register_eNB->mnc; + new_instance->mnc_digit_length = m2ap_register_eNB->mnc_digit_length; + new_instance->num_cc = m2ap_register_eNB->num_cc; + + m2ap_id_manager_init(&new_instance->id_manager); + m2ap_timers_init(&new_instance->timers, + m2ap_register_eNB->t_reloc_prep, + m2ap_register_eNB->tm2_reloc_overall); + + for (int i = 0; i< m2ap_register_eNB->num_cc; i++) { + new_instance->eutra_band[i] = m2ap_register_eNB->eutra_band[i]; + new_instance->downlink_frequency[i] = m2ap_register_eNB->downlink_frequency[i]; + new_instance->uplink_frequency_offset[i] = m2ap_register_eNB->uplink_frequency_offset[i]; + new_instance->Nid_cell[i] = m2ap_register_eNB->Nid_cell[i]; + new_instance->N_RB_DL[i] = m2ap_register_eNB->N_RB_DL[i]; + new_instance->frame_type[i] = m2ap_register_eNB->frame_type[i]; + new_instance->fdd_earfcn_DL[i] = m2ap_register_eNB->fdd_earfcn_DL[i]; + new_instance->fdd_earfcn_UL[i] = m2ap_register_eNB->fdd_earfcn_UL[i]; + } + + DevCheck(m2ap_register_eNB->nb_m2 <= M2AP_MAX_NB_ENB_IP_ADDRESS, + M2AP_MAX_NB_ENB_IP_ADDRESS, m2ap_register_eNB->nb_m2, 0); + memcpy(new_instance->target_mce_m2_ip_address, + m2ap_register_eNB->target_mce_m2_ip_address, + m2ap_register_eNB->nb_m2 * sizeof(net_ip_address_t)); + new_instance->nb_m2 = m2ap_register_eNB->nb_m2; + new_instance->enb_m2_ip_address = m2ap_register_eNB->enb_m2_ip_address; + new_instance->sctp_in_streams = m2ap_register_eNB->sctp_in_streams; + new_instance->sctp_out_streams = m2ap_register_eNB->sctp_out_streams; + new_instance->enb_port_for_M2C = m2ap_register_eNB->enb_port_for_M2C; + + + new_instance->num_mbms_configuration_data_list = m2ap_register_eNB->num_mbms_configuration_data_list; + for(int j=0; j < m2ap_register_eNB->num_mbms_configuration_data_list;j++){ + new_instance->mbms_configuration_data_list[j].num_mbms_service_area_list = m2ap_register_eNB->mbms_configuration_data_list[j].num_mbms_service_area_list; + for(int i=0; i < m2ap_register_eNB->mbms_configuration_data_list[j].num_mbms_service_area_list; i++ ){ + //strcpy(&new_instance->mbms_configuration_data_list[j].mbms_service_area_list[i],&m2ap_register_eNB->mbms_configuration_data_list[j].mbms_service_area_list[i]); + new_instance->mbms_configuration_data_list[j].mbms_service_area_list[i]=m2ap_register_eNB->mbms_configuration_data_list[j].mbms_service_area_list[i]; + } + } + + /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ + m2ap_eNB_insert_new_instance(new_instance); + M2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n", + instance, + m2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", + m2ap_register_eNB->eNB_id); + + /* initiate the SCTP listener */ + if (m2ap_eNB_init_sctp(new_instance,&m2ap_register_eNB->enb_m2_ip_address,m2ap_register_eNB->enb_port_for_M2C) < 0 ) { + M2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n"); + return; + } + + M2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n", + instance, m2ap_register_eNB->eNB_id); + } +} + +static +void m2ap_eNB_handle_sctp_init_msg_multi_cnf( + instance_t instance_id, + sctp_init_msg_multi_cnf_t *m) { + m2ap_eNB_instance_t *instance; + int index; + DevAssert(m != NULL); + instance = m2ap_eNB_get_instance(instance_id); + DevAssert(instance != NULL); + instance->multi_sd = m->multi_sd; + + /* Exit if CNF message reports failure. + * Failure means multi_sd < 0. + */ + if (instance->multi_sd < 0) { + M2AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n"); + DevAssert(instance->multi_sd >= 0); + } + + /* Trying to connect to the provided list of eNB ip address */ + + for (index = 0; index < instance->nb_m2; index++) { + M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n", + instance_id, instance->eNB_id); + m2ap_eNB_register_eNB(instance, + &instance->target_mce_m2_ip_address[index], + &instance->enb_m2_ip_address, + instance->sctp_in_streams, + instance->sctp_out_streams, + instance->enb_port_for_M2C, + instance->multi_sd); + } +} + +//static +//void m2ap_eNB_handle_handover_req(instance_t instance, +// m2ap_handover_req_t *m2ap_handover_req) +//{ +// m2ap_eNB_instance_t *instance_p; +// m2ap_eNB_data_t *target; +// m2ap_id_manager *id_manager; +// int ue_id; +// +// int target_pci = m2ap_handover_req->target_physCellId; +// +// instance_p = m2ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m2ap_is_eNB_pci_in_list(target_pci); +// DevAssert(target != NULL); +// +// /* allocate m2ap ID */ +// id_manager = &instance_p->id_manager; +// ue_id = m2ap_allocate_new_id(id_manager); +// if (ue_id == -1) { +// M2AP_ERROR("could not allocate a new M2AP UE ID\n"); +// /* TODO: cancel handover: send (to be defined) message to RRC */ +// exit(1); +// } +// /* id_source is ue_id, id_target is unknown yet */ +// m2ap_set_ids(id_manager, ue_id, m2ap_handover_req->rnti, ue_id, -1); +// m2ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE); +// m2ap_set_reloc_prep_timer(id_manager, ue_id, +// m2ap_timer_get_tti(&instance_p->timers)); +// m2ap_id_set_target(id_manager, ue_id, target); +// +// m2ap_eNB_generate_m2_handover_request(instance_p, target, m2ap_handover_req, ue_id); +//} + +//static +//void m2ap_eNB_handle_handover_req_ack(instance_t instance, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack) +//{ +// /* TODO: remove this hack (the goal is to find the correct +// * eNodeB structure for the other end) - we need a proper way for RRC +// * and M2AP to identify eNodeBs +// * RRC knows about mod_id and M2AP knows about eNB_id (eNB_ID in +// * the configuration file) +// * as far as I understand.. CROUX +// */ +// m2ap_eNB_instance_t *instance_p; +// m2ap_eNB_data_t *target; +// int source_assoc_id = m2ap_handover_req_ack->source_assoc_id; +// int ue_id; +// int id_source; +// int id_target; +// +// instance_p = m2ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m2ap_get_eNB(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// /* rnti is a new information, save it */ +// ue_id = m2ap_handover_req_ack->m2_id_target; +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// m2ap_set_ids(&instance_p->id_manager, ue_id, m2ap_handover_req_ack->rnti, id_source, id_target); +// +// m2ap_eNB_generate_m2_handover_request_ack(instance_p, target, m2ap_handover_req_ack); +//} +// +//static +//void m2ap_eNB_ue_context_release(instance_t instance, +// m2ap_ue_context_release_t *m2ap_ue_context_release) +//{ +// m2ap_eNB_instance_t *instance_p; +// m2ap_eNB_data_t *target; +// int source_assoc_id = m2ap_ue_context_release->source_assoc_id; +// int ue_id; +// instance_p = m2ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m2ap_get_eNB(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// m2ap_eNB_generate_m2_ue_context_release(instance_p, target, m2ap_ue_context_release); +// +// /* free the M2AP UE ID */ +// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti); +// exit(1); +// } +// m2ap_release_id(&instance_p->id_manager, ue_id); +//} + +//void MCE_task_send_sctp_init_req(instance_t enb_id) { +// // 1. get the itti msg, and retrive the enb_id from the message +// // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port +// // 3. creat an itti message to init +// +// LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n"); +// MessageDef *message_p = NULL; +// +// message_p = itti_alloc_new_message (M2AP, SCTP_INIT_MSG); +// message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER; +// message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID; +// message_p->ittiMsg.sctp_init.ipv4 = 1; +// message_p->ittiMsg.sctp_init.ipv6 = 0; +// message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; +// //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); +// message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7"); +// /* +// * SR WARNING: ipv6 multi-homing fails sometimes for localhost. +// * * * * Disable it for now. +// */ +// message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; +// message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; +// +// itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); +//} +// +void *m2ap_eNB_task(void *arg) { + MessageDef *received_msg = NULL; + int result; + M2AP_DEBUG("Starting M2AP layer\n"); + m2ap_eNB_prepare_internal_data(); + + itti_mark_task_ready(TASK_M2AP_ENB); + + // MCE_task_send_sctp_init_req(0); + + while (1) { + itti_receive_msg(TASK_M2AP_ENB, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case MESSAGE_TEST: + LOG_D(M2AP,"eNB Received MESSAGE_TEST Message %s\n",itti_get_task_name(ITTI_MSG_ORIGIN_ID(received_msg))); + //MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_ENB, MESSAGE_TEST); + //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p); + break; + case TERMINATE_MESSAGE: + M2AP_WARN(" *** Exiting M2AP thread\n"); + itti_exit_task(); + break; + + case M2AP_SUBFRAME_PROCESS: + m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + break; + + case M2AP_REGISTER_ENB_REQ: + LOG_I(M2AP,"eNB Received M2AP_REGISTER_ENB_REQ Message\n"); + m2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_REGISTER_ENB_REQ(received_msg)); + break; + + + case M2AP_MBMS_SCHEDULING_INFORMATION_RESP: + LOG_I(M2AP,"eNB M2AP_MBMS_SCHEDULING_INFORMATION_RESP Message\n"); + eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SCHEDULING_INFORMATION_RESP(received_msg)); + break; + case M2AP_MBMS_SESSION_START_RESP: + LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_RESP Message\n"); + eNB_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SESSION_START_RESP(received_msg)); + break; + case M2AP_MBMS_SESSION_START_FAILURE: + LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_FAILURE Message\n"); + eNB_send_MBMS_SESSION_START_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SESSION_START_FAILURE(received_msg)); + break; + case M2AP_MBMS_SESSION_STOP_RESP: + LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_STOP_RESP Message\n"); + eNB_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SESSION_STOP_RESP(received_msg)); + break; + case M2AP_ENB_CONFIGURATION_UPDATE: + LOG_I(M2AP,"eNB M2AP_ENB_CONFIGURATION_UPDATE Message\n"); + eNB_send_eNB_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_ENB_CONFIGURATION_UPDATE(received_msg)); + break; + case M2AP_MCE_CONFIGURATION_UPDATE_ACK: + LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_ACK Message\n"); + //eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + // &M2AP_MCE_CONFIGURATION_UPDATE_ACK(received_msg)); + break; + case M2AP_MCE_CONFIGURATION_UPDATE_FAILURE: + LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_FAILURE Message\n"); + //(ITTI_MESSAGE_GET_INSTANCE(received_msg), + //&M2AP_MCE_CONFIGURATION_UPDATE_FAILURE(received_msg)); + break; + case M2AP_MBMS_SESSION_UPDATE_RESP: + LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_RESP Message\n"); + eNB_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SESSION_UPDATE_RESP(received_msg)); + break; + case M2AP_MBMS_SESSION_UPDATE_FAILURE: + LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_FAILURE Message\n"); + eNB_send_MBMS_SESSION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SESSION_UPDATE_FAILURE(received_msg)); + break; + case M2AP_MBMS_SERVICE_COUNTING_REPORT: + LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_REPORT Message\n"); + eNB_send_MBMS_SERVICE_COUNTING_REPORT(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SERVICE_COUNTING_REPORT(received_msg)); + break; + case M2AP_MBMS_OVERLOAD_NOTIFICATION: + LOG_I(M2AP,"eNB M2AP_MBMS_OVERLOAD_NOTIFICATION Message\n"); + eNB_send_MBMS_OVERLOAD_NOTIFICATION(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_OVERLOAD_NOTIFICATION(received_msg)); + break; + case M2AP_MBMS_SERVICE_COUNTING_RESP: + LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_RESP Message\n"); + eNB_send_MBMS_SERVICE_COUNTING_RESP(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SERVICE_COUNTING_RESP(received_msg)); + break; + case M2AP_MBMS_SERVICE_COUNTING_FAILURE: + LOG_I(M2AP,"eNB Message\n"); + eNB_send_MBMS_SERVICE_COUNTING_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M2AP_MBMS_SERVICE_COUNTING_FAILURE(received_msg)); + break; + + + case SCTP_INIT_MSG_MULTI_CNF: + LOG_I(M2AP,"eNB Received SCTP_INIT_MSG_MULTI_CNF Message\n"); + m2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_init_msg_multi_cnf); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION_RESP Message\n"); + m2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_NEW_ASSOCIATION_IND: + LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION Message\n"); + m2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_DATA_IND: + LOG_I(M2AP,"eNB Received SCTP_DATA_IND Message\n"); + m2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + default: + M2AP_ERROR("eNB Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; + } + + return NULL; +} + +#include "common/config/config_userapi.h" + +int is_m2ap_eNB_enabled(void) +{ + static volatile int config_loaded = 0; + static volatile int enabled = 0; + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if (pthread_mutex_lock(&mutex)) goto mutex_error; + + if (config_loaded) { + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + return enabled; + } + + char *enable_m2 = NULL; + paramdef_t p[] = { + { "enable_enb_m2", "yes/no", 0, strptr:&enable_m2, defstrval:"", TYPE_STRING, 0 } + }; + + /* TODO: do it per module - we check only first eNB */ + config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]"); + if (enable_m2 != NULL && strcmp(enable_m2, "yes") == 0) + enabled = 1; + + config_loaded = 1; + + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + + return enabled; + +mutex_error: + LOG_E(M2AP, "mutex error\n"); + exit(1); +} diff --git a/openair2/M2AP/m2ap_eNB.h b/openair2/M2AP/m2ap_eNB.h new file mode 100644 index 0000000000..608da07e7e --- /dev/null +++ b/openair2/M2AP/m2ap_eNB.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB.h + * \brief m2ap tasks for eNB + * \author Konstantinos Alexandris , Cedric Roux , Navid Nikaein + * \date 2018 + * \version 1.0 + */ + +#include +#include + +/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +#ifndef M2AP_ENB_H_ +#define M2AP_ENB_H_ + +#include "m2ap_eNB_defs.h" + + +int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t enb_port_for_M2C); + +void *m2ap_eNB_task(void *arg); + +int is_m2ap_eNB_enabled(void); + +#endif /* M2AP_ENB_H_ */ + +/** + * @} + */ diff --git a/openair2/M2AP/m2ap_eNB_defs.h b/openair2/M2AP/m2ap_eNB_defs.h new file mode 100644 index 0000000000..b8f7e4b3c6 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_defs.h @@ -0,0 +1,221 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_defs.h + * \brief m2ap struct definitions for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#include "m2ap_ids.h" //looks X2AP specific for HO +#include "m2ap_timers.h" + +#ifndef M2AP_ENB_DEFS_H_ +#define M2AP_ENB_DEFS_H_ + +#define M2AP_ENB_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + M2AP_ENB_STATE_DISCONNECTED = 0x0, + + /* State waiting for m2 Setup response message if the target eNB accepts or + * M2 Setup failure if rejects the eNB. + */ + M2AP_ENB_STATE_WAITING = 0x1, + + /* The eNB is successfully connected to another eNB. */ + M2AP_ENB_STATE_CONNECTED = 0x2, + + /* M2AP is ready, and the eNB is successfully connected to another eNB. */ + M2AP_ENB_STATE_READY = 0x3, + + M2AP_ENB_STATE_OVERLOAD = 0x4, + + M2AP_ENB_STATE_RESETTING = 0x5, + + /* Max number of states available */ + M2AP_ENB_STATE_MAX, +} m2ap_eNB_state_t; + +/* Served PLMN identity element */ +/*struct plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + STAILQ_ENTRY(plmn_identity_s) next; +};*/ + +/* Served group id element */ +/*struct served_group_id_s { + uint16_t enb_group_id; + STAILQ_ENTRY(served_group_id_s) next; +};*/ + +/* Served enn code for a particular eNB */ +/*struct enb_code_s { + uint8_t enb_code; + STAILQ_ENTRY(enb_code_s) next; +};*/ + +struct m2ap_eNB_instance_s; + +/* This structure describes association of a eNB to another eNB */ +typedef struct m2ap_eNB_data_s { + /* eNB descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(m2ap_eNB_data_s) entry; + + /* This is the optional name provided by the MME */ + char *eNB_name; + + /* target eNB ID */ + uint32_t eNB_id; + + /* Current eNB load information (if any). */ + //m2ap_load_state_t overload_state; + + /* Current eNB->eNB M2AP association state */ + m2ap_eNB_state_t state; + + /* Next usable stream for UE signalling */ + int32_t nextstream; + + /* Number of input/ouput streams */ + uint16_t in_streams; + uint16_t out_streams; + + /* Connexion id used between SCTP/M2AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Nid cells */ + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + + /* Only meaningfull in virtual mode */ + struct m2ap_eNB_instance_s *m2ap_eNB_instance; +} m2ap_eNB_data_t; + +typedef struct m2ap_eNB_instance_s { + /* used in simulation to store multiple eNB instances*/ + STAILQ_ENTRY(m2ap_eNB_instance_s) m2ap_eNB_entries; + + /* Number of target eNBs requested by eNB (tree size) */ + uint32_t m2_target_enb_nb; + /* Number of target eNBs for which association is pending */ + uint32_t m2_target_enb_pending_nb; + /* Number of target eNB successfully associated to eNB */ + uint32_t m2_target_enb_associated_nb; + /* Tree of M2AP eNB associations ordered by association ID */ + RB_HEAD(m2ap_enb_map, m2ap_eNB_data_s) m2ap_enb_head; + + /* Tree of UE ordered by eNB_ue_m2ap_id's */ + // RB_HEAD(m2ap_ue_map, m2ap_eNB_ue_context_s) m2ap_ue_head; + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + /* Displayable name of eNB */ + char *eNB_name; + + /* Unique eNB_id to identify the eNB within EPC. + * In our case the eNB is a macro eNB so the id will be 20 bits long. + * For Home eNB id, this field should be 28 bits long. + */ + uint32_t eNB_id; + /* The type of the cell */ + cell_type_t cell_type; + + //uint16_t num_mbms_service_area_list; + //uint16_t mbms_service_area_list[8]; + + struct{ + uint16_t mbsfn_sync_area; + uint16_t mbms_service_area_list[8]; + uint16_t num_mbms_service_area_list; + }mbms_configuration_data_list[8]; + uint8_t num_mbms_configuration_data_list; + + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* CC params */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS]; + uint8_t nb_m2; + net_ip_address_t enb_m2_ip_address; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + uint32_t enb_port_for_M2C; + int multi_sd; + + m2ap_id_manager id_manager; + m2ap_timers_t timers; +} m2ap_eNB_instance_t; + +typedef struct { + /* List of served eNBs + * Only used for virtual mode + */ + STAILQ_HEAD(m2ap_eNB_instances_head_s, m2ap_eNB_instance_s) m2ap_eNB_instances_head; + /* Nb of registered eNBs */ + uint8_t nb_registered_eNBs; + + /* Generate a unique connexion id used between M2AP and SCTP */ + uint16_t global_cnx_id; +} m2ap_eNB_internal_data_t; + +int m2ap_eNB_compare_assoc_id(struct m2ap_eNB_data_s *p1, struct m2ap_eNB_data_s *p2); + +/* Generate the tree management functions */ +struct m2ap_eNB_map; +struct m2ap_eNB_data_s; +RB_PROTOTYPE(m2ap_eNB_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id); + + +#endif /* M2AP_ENB_DEFS_H_ */ diff --git a/openair2/M2AP/m2ap_eNB_generate_messages.c b/openair2/M2AP/m2ap_eNB_generate_messages.c new file mode 100644 index 0000000000..b6c821e1ce --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_generate_messages.c @@ -0,0 +1,808 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_generate_messages.c + * \brief m2ap procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +//#include "M2AP_LastVisitedCell-Item.h" + +#include "m2ap_common.h" +#include "m2ap_eNB.h" +#include "m2ap_eNB_generate_messages.h" +#include "m2ap_encoder.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +#include "m2ap_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +//int m2ap_eNB_generate_m2_setup_request( +// m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p) +//{ +// module_id_t enb_mod_idP=0; +// module_id_t du_mod_idP=0; +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_M2SetupRequest_t *out; +// M2AP_M2SetupRequest_Ies_t *ie; +// +// uint8_t *buffer; +// uint32_t len; +// int i = 0; +// int j = 0; +// +// /* Create */ +// /* 0. pdu Type */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest; +// out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest; +// +// /* mandatory */ +// /* c1. GlobalENB_ID (integer value) */ +// ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); +// ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID; +// //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP); +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.GlobalENB_ID.pLMN_Identity); +// ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID; +// MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, +// &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); +// M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, +// ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], +// ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], +// ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// ///* mandatory */ +// ///* c2. GNB_eNB_ID (integrer value) */ +// //ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_gNB_eNB_ID; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID; +// //asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id); +// //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// /* c3. ENBname */ +// if (m2ap_eNB_data_p->eNB_name != NULL) { +// ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); +// ie->id = M2AP_ProtocolIE_ID_id_ENBname; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENBname; +// //OCTET_STRING_fromBuf(&ie->value.choice.ENB_Name, m2ap_eNB_data_p->eNB_name, +// //strlen(m2ap_eNB_data_p->eNB_name)); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* mandatory */ +// /* c4. serverd cells list */ +// ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); +// ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List; +// +// int num_mbms_available = 1;//m2ap_du_data->num_mbms_available; +// LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available); +// +// for (i=0; +// iid = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item; +// mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject; +// mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item; +// +// M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item; +// mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item; +// { +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &mbms_configuration_data_item->eCGI.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, +// &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier); +// M2AP_MBMS_Service_Area_t * mbms_service_area; +// mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); +// ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area); +// +// +// } +// +// +// //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item; +// //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t)); +// +// //M2AP_ECGI_t eCGI; +// //M2AP_PLMN_Identity_t pLMN_Identity; +// //M2AP_EUTRANCellIdentifier_t eUTRANcellIdentifier +// //M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea; +// //M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList; +// +// +// ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies); +// +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// LOG_W(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id); +// /* encode */ +// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// LOG_E(M2AP, "Failed to encode M2 setup request\n"); +// return -1; +// } +// +// +// LOG_W(M2AP,"pdu.present %d\n",pdu.present); +// // MSC_LOG_TX_MESSAGE( +// // MSC_M2AP_eNB, +// // MSC_M2AP_MCE, +// // (const char *)buffer, +// // len, +// // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", +// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +// // m2ap_eNB_data_p->ENBname); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p, m2ap_eNB_data_p->assoc_id, buffer, len, 0); +// +// return 0; +// +// +//} + +//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_M2SetupResponse_t *out; +// M2AP_M2SetupResponse_Ies_t *ie; +// //M2AP_PLMN_Identity_t *plmn; +// //ServedCells__Member *servedCellMember; +// //M2AP_GU_Group_ID_t *gu; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// /* Prepare the M2AP message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; +// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse; +// out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse; +// +// /* mandatory */ +// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalENB_ID; +// //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// // &ie->value.choice.GlobalENB_ID.pLMN_Identity); +// //ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID; +// //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, +// // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); +// //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, +// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], +// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], +// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_ServedCells; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells; +// //{ +// // for (int i = 0; inum_cc; i++){ +// // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); +// // { +// // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; +// +// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); +// // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, +// // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); +// +// // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); +// // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t)); +// // { +// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); +// // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); +// // } +// +// // if (instance_p->frame_type[i] == FDD) { +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; +// // switch (instance_p->N_RB_DL[i]) { +// // case 6: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; +// // break; +// // case 15: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; +// // break; +// // case 25: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; +// // break; +// // case 50: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; +// // break; +// // case 75: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; +// // break; +// // case 100: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; +// // break; +// // default: +// // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); +// // break; +// // } +// // } +// // else { +// // AssertFatal(0,"M2Setupresponse not supported for TDD!"); +// // } +// // } +// // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); +// // } +// //} +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList; +// //{ +// // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t)); +// // { +// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// // &gu->pLMN_Identity); +// // //@TODO: consider to update this value +// // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); +// // } +// // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); +// //} +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode M2 setup response\n"); +// return -1; +// } +// +// m2ap_eNB_data_p->state = M2AP_ENB_STATE_READY; +// +// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0); +// +// return ret; +//} + +//int m2ap_MCE_generate_m2_setup_failure(instance_t instance, +// uint32_t assoc_id, +// M2AP_Cause_PR cause_type, +// long cause_value, +// long time_to_wait) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_M2SetupFailure_t *out; +// M2AP_M2SetupFailure_Ies_t *ie; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// /* Prepare the M2AP message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; +// pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; +// pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure; +// out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure; +// +// /* mandatory */ +// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_Cause; +// //ie->criticality = M2AP_Criticality_ignore; +// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause; +// +// //m2ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional: consider to handle this later */ +// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait; +// //ie->criticality = M2AP_Criticality_ignore; +// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait; +// +// //if (time_to_wait > -1) { +// // ie->value.choice.TimeToWait = time_to_wait; +// //} +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode M2 setup failure\n"); +// return -1; +// } +// +// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, +// // MSC_M2AP_TARGET_ENB, NULL, 0, +// // "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", +// // assoc_id, cause_type, cause_value); +// +// m2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); +// +// return ret; +//} + +int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value) +{ + + DevAssert (cause_p != NULL); + cause_p->present = cause_type; + + switch (cause_type) { + case M2AP_Cause_PR_radioNetwork: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_transport: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_protocol: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_misc: + cause_p->choice.misc = cause_value; + break; + + default: + return -1; + } + + return 0; +} + +//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequest_t *out; +// M2AP_HandoverRequest_IEs_t *ie; +// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; +// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; +// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause; +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.ECGI.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(m2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); +// //@TODO: consider to update these values +// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); +// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; +// //@TODO: consider to update this value +// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id; +// +// KENB_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); +// +// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc; +// } +// else { +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; +// } +// +// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); +// +// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); +// +// //@TODO: update with proper UEAMPR +// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); +// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t)); +// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; +// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; +// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; +// { +// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8); +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = +// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, +// m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); +// } +// } +// +// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; +// //@TODO: consider to update this value +// { +// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t)); +// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); +// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small; +// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover request\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequestAcknowledge_t *out; +// M2AP_HandoverRequestAcknowledge_IEs_t *ie; +// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; +// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// ue_id = m2ap_handover_req_ack->m2_id_target; +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; +// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; +// +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t)); +// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; +// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; +// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; +// { +// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); +// } +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer; +// +// OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover response\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_UEContextRelease_t *out; +// M2AP_UEContextRelease_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti); +// exit(1); +// } +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP ue context relase message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease; +// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 UE Context Release\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverCancel_t *out; +// M2AP_HandoverCancel_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// ue_id = m2_ue_id; +// id_source = ue_id; +// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id); +// +// /* Prepare the M2AP handover cancel message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// if (id_target != -1) { +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause; +// switch (cause) { +// case M2AP_T_RELOC_PREP_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_trelocprep_expiry; +// break; +// case M2AP_TX2_RELOC_OVERALL_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_tx2relocoverall_expiry; +// break; +// default: +// /* we can't come here */ +// M2AP_ERROR("unhandled cancel cause\n"); +// exit(1); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 Handover Cancel\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} diff --git a/openair2/M2AP/m2ap_eNB_generate_messages.h b/openair2/M2AP/m2ap_eNB_generate_messages.h new file mode 100644 index 0000000000..49247405f7 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_generate_messages.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_generate_messages.h + * \brief m2ap procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENB_GENERATE_MESSAGES_H_ +#define M2AP_ENB_GENERATE_MESSAGES_H_ + +#include "m2ap_eNB_defs.h" +#include "m2ap_common.h" + +//int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p, +// m2ap_eNB_data_t *m2ap_eNB_data_p); +// +//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p); +// +/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance, + uint32_t assoc_id, + M2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait);*/ + +int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value); + +//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id); +// +//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack); +// +//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_ue_context_release_t *m2ap_ue_context_release); +// +//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause); + +#endif /* M2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/M2AP/m2ap_eNB_handler.c b/openair2/M2AP/m2ap_eNB_handler.c new file mode 100644 index 0000000000..fe0059f0a5 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_handler.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_handler.c + * \brief m2ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m2ap_common.h" +#include "m2ap_eNB_defs.h" +#include "m2ap_eNB_handler.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +#include "m2ap_eNB_management_procedures.h" +#include "m2ap_eNB_generate_messages.h" + +//#include "m2ap_MCE_interface_management.h" +#include "m2ap_eNB_interface_management.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +/* Handlers matrix. Only eNB related procedure present here */ +m2ap_eNB_message_decoded_callback m2ap_eNB_messages_callback[][3] = { + { eNB_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart */ + { eNB_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */ + { eNB_handle_MBMS_SCHEDULING_INFORMATION, 0, 0 }, /* MBMSSchedulingInformation */ + { 0, 0, 0 }, /* Error Indication */ + { 0, 0, 0 }, /* Reset */ + { 0,eNB_handle_M2_SETUP_RESPONSE,eNB_handle_M2_SETUP_FAILURE }, /* M2 Setup */ + { 0, 0, 0 }, /* eNBConfigurationUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { 0, 0, 0 }, /* privateMessage */ + { 0, 0, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MBMSServiceCounting */ + { 0, 0, 0 }, /* MBMSServiceCountingResultReport */ + { 0, 0, 0 } /* MBMSOverloadNotification */ +}; + +static char *m2ap_direction2String(int m2ap_dir) { +static char *m2ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m2ap_direction_String[m2ap_dir]); +} + + +int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + M2AP_M2AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + if (m2ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(M2AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_eNB_messages_callback) / (3 * sizeof( + m2ap_message_decoded_callback)) + || (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(M2AP, "Calling handler with instance %d\n",instance); + ret = (*m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return ret; +} + + diff --git a/openair2/M2AP/m2ap_eNB_handler.h b/openair2/M2AP/m2ap_eNB_handler.h new file mode 100644 index 0000000000..ea4231a6e3 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_handler.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_handler.h + * \brief m2ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENB_HANDLERS_H_ +#define M2AP_ENB_HANDLERS_H_ + +#include "m2ap_eNB_defs.h" + +//void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + +//int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + //const uint8_t * const data, const uint32_t data_length); + + +#endif /* M2AP_ENB_HANDLERS_H_ */ diff --git a/openair2/M2AP/m2ap_eNB_interface_management.c b/openair2/M2AP/m2ap_eNB_interface_management.c new file mode 100644 index 0000000000..c2659da59d --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_interface_management.c @@ -0,0 +1,1385 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_interface_management.c + * \brief m2ap interface management for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech, Spain + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "intertask_interface.h" + +#include "m2ap_common.h" +#include "m2ap_eNB.h" +#include "m2ap_eNB_generate_messages.h" +#include "m2ap_encoder.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +#include "m2ap_eNB_interface_management.h" + + +#include "m2ap_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +#include "M2AP_MBSFN-Area-Configuration-List.h" + +//#include "m2ap_common.h" +//#include "m2ap_encoder.h" +//#include "m2ap_decoder.h" +//#include "m2ap_itti_messaging.h" +//#include "m2ap_eNB_interface_management.h" +//#include "assertions.h" + +extern m2ap_setup_req_t *m2ap_enb_data_g; + + +//extern m2ap_setup_req_t *m2ap_mce_data_from_enb; +int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + LOG_D(M2AP, "eNB_handle_MBMS_SCHEDULING_INFORMATION assoc_id %d\n",assoc_id); + + MessageDef *message_p/*,*message_p2*/; + M2AP_MbmsSchedulingInformation_t *container; + M2AP_MbmsSchedulingInformation_Ies_t *ie; + int i = 0; + int j = 0; + int k = 0; + //int m = 0; + + DevAssert(pdu != NULL); + + container = &pdu->choice.initiatingMessage.value.choice.MbmsSchedulingInformation; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS scheduling information on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SCHEDULING_INFORMATION); + //message_p2 = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SCHEDULING_INFORMATION); + + + + + + M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie, container,M2AP_ProtocolIE_ID_id_MCCH_Update_Time ,true); + //printf("id %d\n",ie->id); + + M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie, container,M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List ,true); + + if(ie){ + + //printf("id %d\n",ie->id); + //printf("MBSFN_Area_Configuration_List %p\n",ie->value.choice.MBSFN_Area_Configuration_List.list.array); + /*M2AP_MBSFN_Area_Configuration_Item_t * kk = &ie->value.choice.MBSFN_Area_Configuration_List.list.array[0]; + printf("M2AP_MBSFN_Area_Configuration_Item %p\n",kk); + printf("M2AP_MBSFN_Area_Configuration_Item %d\n",kk->id);*/ + + const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID((void*)&ie->value.choice.MBSFN_Area_Configuration_List); + if(list->count > 0 ){ + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).num_mbms_area_config_list = list->count; + } + for(i=0; i < list->count; i++ ){ + void * memb_ptr = list->array[i]; + //printf("%p %d\n", memb_ptr,list->count); + const asn_anonymous_sequence_ *list1 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr); + void * memb_ptr1 = list1->array[0]; + //printf("%p %d\n", memb_ptr1,list1->count); + void * memb_ptr2 = list1->array[1]; + void * memb_ptr3 = list1->array[2]; + void * memb_ptr4 = list1->array[3]; + + //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1)->id); + M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1; + //printf("count %d\n",m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count); + if(m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count > 0){ + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].num_pmch_config_list = m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count; + } + for(j=0; j < m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.count; j++){ + M2AP_PMCH_Configuration_Item_t * m2ap_pmchconfiguration_item =&(((M2AP_PMCH_Configuration_ItemIEs_t*)m2ap_mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list.array[j])->value.choice.PMCH_Configuration_Item); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].data_mcs = m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS; + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mch_scheduling_period = m2ap_pmchconfiguration_item->pmch_Configuration.mchSchedulingPeriod; + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end = m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd; + //printf("dataMCS %lu\n",m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS); + //printf("allocatedSubframesEnd %lu\n",m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd); + if(m2ap_pmchconfiguration_item->mbms_Session_List.list.count > 0){ + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list = m2ap_pmchconfiguration_item->mbms_Session_List.list.count; + } + for(k=0; k < m2ap_pmchconfiguration_item->mbms_Session_List.list.count; k++){ + //long mnc,mcc,mnc_length; + PLMNID_TO_MCC_MNC(&m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.pLMNidentity, + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mcc, + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc, + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc_length); + //char buf[4]; + + //BUFFER_TO_INT32(buf,); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].service_id = ((m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[0]<<16) | (m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[1]<<8) | (m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[2])); // + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].lcid = m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->lcid; //*/ + //LOG_E(M2AP,"buf[0]:%d buf[1]:%d buf[2]:%d\n",m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[0],m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[1],m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.serviceID.buf[2]); + } + } + + //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2)->id); + M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item2 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2; + //printf("count %d\n",m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count); + if(m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count > 0){ + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].num_mbms_sf_config_list = m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count; + } + for(j=0; j < m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count; j++){ + M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_sf_configuration = &(((M2AP_MBSFN_Subframe_ConfigurationItem_t*)m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.array[j])->value.choice.MBSFN_Subframe_Configuration); + //printf("radioframe_allocation_period %lu\n",m2ap_mbsfn_sf_configuration->radioframeAllocationPeriod); + //printf("radioframe_allocation_offset %lu\n",m2ap_mbsfn_sf_configuration->radioframeAllocationOffset); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period = m2ap_mbsfn_sf_configuration->radioframeAllocationPeriod; + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset = m2ap_mbsfn_sf_configuration->radioframeAllocationOffset; + if( m2ap_mbsfn_sf_configuration->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames ) { + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[1]<<8) | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0]<<16); + }else{ + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] >> 2) & 0x3F; + } + } + + + //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3)->id); + M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item3 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3; + //printf("count %d\n",m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.count); + //printf("Common_Subframe_Allocation_Period %lu\n",m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].common_sf_allocation_period = m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period; + + //printf("%lu\n", ((M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4)->id); + M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item4 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4; + //printf("MBMS_Area_ID %lu\n",m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_area_id = m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID; + } + + + //const asn_anonymous_sequence_ *list3 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr2); + //void * memb_ptr3 = list3->array[0]; + //printf("%p\n", memb_ptr3); + + + + + //xer_fprint(stdout, &asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List); + + } + //asn_DEF_M2AP_MBSFN_Area_Configuration_List + + // void * sptr = (void*)&ie->value.choice.MBSFN_Area_Configuration_List; + // asn_TYPE_descriptor_t * td = &asn_DEF_M2AP_MBSFN_Area_Configuration_List; + // asn_enc_rval_t er; + // const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + // const asn_TYPE_member_t *elm = td->elements; + // const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr); + // const char *mname = specs->as_XMLValueList + // ? 0 + // : ((*elm->name) ? elm->name : elm->type->xml_tag); + // size_t mlen = mname ? strlen(mname) : 0; + // //int xcan = (flags & XER_F_CANONICAL); + // //int i; + + // if(!sptr) ASN__ENCODE_FAILED; + + // er.encoded = 0; + + // for(i = 0; i < list->count; i++) { + // asn_enc_rval_t tmper; + // void *memb_ptr = list->array[i]; + // if(!memb_ptr) continue; + + // if(mname) { + // //if(!xcan) ASN__TEXT_INDENT(1, ilevel); + // //ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); + // } + + // tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1, + // flags, cb, app_key); + // if(tmper.encoded == -1) return tmper; + // er.encoded += tmper.encoded; + // if(tmper.encoded == 0 && specs->as_XMLValueList) { + // const char *name = elm->type->xml_tag; + // size_t len = strlen(name); + // //if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1); + // //ASN__CALLBACK3("<", 1, name, len, "/>", 2); + // } + + // if(mname) { + // ASN__CALLBACK3("", 1); + // } + // } + + + + + + + + //M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MBSFN_Area_Configuration_Item_t, &ie->value.choice.MBSFN_Area_Configuration_List.list, container2,M2AP_ProtocolIE_ID_id_PMCH_Configuration_List ,true); + + //printf("count %d\n",((M2AP_MBSFN_Area_Configuration_Item_t*)ie->value.choice.MBSFN_Area_Configuration_List.list.array[0])->value.choice.PMCH_Configuration_List.list.count); + + +// M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, +// M2AP_ProtocolIE_ID_id_GlobalEND_ID, true); + + + //itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p2); + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + +// if(1){ +// printf("m2ap_enb_data_g->assoc_id %d %d\n",m2ap_enb_data_g->assoc_id,assoc_id); +// eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance,NULL); +// }else +// //eNB_send_MBMS_SESSION_START_FAILURE(instance,assoc_id); + return 0; + +} +int eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, m2ap_mbms_scheduling_information_resp_t * m2ap_mbms_scheduling_information_resp){ +// module_id_t mce_mod_idP; + //module_id_t enb_mod_idP; + + // This should be fixed + // enb_mod_idP = (module_id_t)0; + // mce_mod_idP = (module_id_t)0; + + M2AP_M2AP_PDU_t pdu; + //M2AP_MbmsSchedulingInformationResponse_t *out; + //M2AP_MbmsSchedulingInformationResponse_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_mbmsSchedulingInformation; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_MbmsSchedulingInformationResponse; + //out = &pdu.choice.successfulOutcome.value.choice.MbmsSchedulingInformationResponse; + + +// /* mandatory */ +// /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long +// ie = (M2AP_MbmsSchedulingInformationResponse_Ies_t *)calloc(1, sizeof(M2AP_MbmsSchedulingInformationResponse_Ies_t)); +// ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_MbmsSchedulingInformationResponse_Ies__value_PR_MCE_MBMS_M2AP_ID; +// //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long +// ie = (M2AP_SessionStartResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStartResponse_Ies_t)); +// ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_MbmsSchedulingInformationResponse_Ies__value_PR_ENB_MBMS_M2AP_ID; +// //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 SessionStart Response\n"); + return -1; + } + + + LOG_D(M2AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m2ap_eNB_data_p->ENBname); + + m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0); + return 0; +} + + + + +int eNB_handle_MBMS_SESSION_START_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + LOG_D(M2AP, "eNB_handle_MBMS_SESSION_START_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_SessionStartRequest_t *container; + //M2AP_SessionStartRequest_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.SessionStartRequest; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_START_REQ); + + + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + +// if(1){ +// eNB_send_MBMS_SESSION_START_RESPONSE(instance,NULL); +// }else +// eNB_send_MBMS_SESSION_START_FAILURE(instance,NULL); + return 0; + +} + +int eNB_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m2ap_session_start_resp_t * m2ap_session_start_resp){ +// module_id_t mce_mod_idP; +// module_id_t enb_mod_idP; + + // This should be fixed +// enb_mod_idP = (module_id_t)0; +// mce_mod_idP = (module_id_t)0; + + M2AP_M2AP_PDU_t pdu; + M2AP_SessionStartResponse_t *out; + M2AP_SessionStartResponse_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_sessionStart; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_SessionStartResponse; + out = &pdu.choice.successfulOutcome.value.choice.SessionStartResponse; + + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStartResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStartResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartResponse_Ies__value_PR_MCE_MBMS_M2AP_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStartResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStartResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 SessionStart Response\n"); + return -1; + } + + + LOG_D(M2AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m2ap_eNB_data_p->ENBname); + + m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0); + return 0; +} + + +int eNB_send_MBMS_SESSION_START_FAILURE(instance_t instance, m2ap_session_start_failure_t * m2ap_session_start_failure){ + //module_id_t enb_mod_idP; + //module_id_t mce_mod_idP; + + // This should be fixed + //enb_mod_idP = (module_id_t)0; + // mce_mod_idP = (module_id_t)0; + + M2AP_M2AP_PDU_t pdu; + M2AP_SessionStartFailure_t *out; + M2AP_SessionStartFailure_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; + //pdu.choice.unsuccessfulOutcome = (M2AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M2AP_UnsuccessfulOutcome_t)); + pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_sessionStart; + pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_SessionStartFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.SessionStartFailure; + + /* mandatory */ + /* c1. Transaction ID (integer value)*/ + // ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + // ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; + // ie->criticality = M2AP_Criticality_reject; + // ie->value.present = M2AP_M2SetupFailure_Ies__value_PR_GlobalENB_ID; + // ie->value.choice.GlobalENB_ID = M2AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP); + // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStartFailure_Ies_t *)calloc(1, sizeof(M2AP_SessionStartFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStartFailure_Ies__value_PR_MCE_MBMS_M2AP_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + /* mandatory */ + /* c2. Cause */ + ie = (M2AP_SessionStartFailure_Ies_t *)calloc(1, sizeof(M2AP_SessionStartFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_Cause; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_SessionStartFailure_Ies__value_PR_Cause; + ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_unspecified; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 setup request\n"); + return -1; + } + + //mce_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_enb->assoc_id, buffer, len, 0); + m2ap_eNB_itti_send_sctp_data_req(instance,m2ap_enb_data_g->assoc_id,buffer,len,0); + + + return 0; +} + +int eNB_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu){ + LOG_D(M2AP, "eNB_handle_MBMS_SESSION_STOP_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_SessionStopRequest_t *container; + //M2AP_SessionStopRequest_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.SessionStopRequest; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_STOP_REQ); + + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + + +// if(1){ +// eNB_send_MBMS_SESSION_STOP_RESPONSE(instance,NULL); +// }else +// eNB_send_MBMS_SESSION_STOP_FAILURE(instance,NULL); + return 0; + +} +int eNB_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m2ap_session_stop_resp_t * m2ap_session_stop_resp){ + //module_id_t mce_mod_idP; + //module_id_t enb_mod_idP; + + // This should be fixed + //enb_mod_idP = (module_id_t)0; + //mce_mod_idP = (module_id_t)0; + + M2AP_M2AP_PDU_t pdu; + M2AP_SessionStopResponse_t *out; + M2AP_SessionStopResponse_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_sessionStop; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_SessionStopResponse; + out = &pdu.choice.successfulOutcome.value.choice.SessionStopResponse; + + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStopResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStopResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStopResponse_Ies__value_PR_MCE_MBMS_M2AP_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_SessionStopResponse_Ies_t *)calloc(1, sizeof(M2AP_SessionStopResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_SessionStopResponse_Ies__value_PR_ENB_MBMS_M2AP_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 SessionStop Response\n"); + return -1; + } + + + LOG_D(M2AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m2ap_eNB_data_p->ENBname); + + m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0); + return 0; +} + + uint8_t bytes [] = {0x00, 0x05, /* .....+.. */ +0x00, 0x24, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x00, /* .$...... */ +0x08, 0x00, 0x02, 0xf8, 0x39, 0x00, 0x00, 0xe0, /* ....9... */ +0x00, 0x00, 0x0f, 0x00, 0x11, 0x00, 0x00, 0x10, /* ........ */ +0x00, 0x0c, 0x00, 0x02, 0xf8, 0x39, 0x00, 0xe0, /* .....9.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + +/* + M2 Setup +*/ + +// SETUP REQUEST +int eNB_send_M2_SETUP_REQUEST(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t* m2ap_eNB_data_p) { + // module_id_t enb_mod_idP=0; + // module_id_t du_mod_idP=0; + + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupRequest_t *out; + M2AP_M2SetupRequest_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + int j = 0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest; + + /* mandatory */ + /* c1. GlobalENB_ID (integer value) */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID; + //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP); + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie->value.choice.GlobalENB_ID.pLMN_Identity); + ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID; + MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); + M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ///* mandatory */ + ///* c2. GNB_eNB_ID (integrer value) */ + //ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_gNB_eNB_ID; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID; + //asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id); + //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. ENBname */ + if (m2ap_eNB_data_p->eNB_name != NULL) { + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENBname; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENBname; + OCTET_STRING_fromBuf(&ie->value.choice.ENBname, m2ap_eNB_data_p->eNB_name, + strlen(m2ap_eNB_data_p->eNB_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c4. serverd cells list */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List; + + int num_mbms_available = instance_p->num_mbms_configuration_data_list; + LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available); + + for (i=0; + iid = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item; + mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject; + mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item; + + M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item; + mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item; + { + /* M2AP_ECGI_t eCGI */ + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &mbms_configuration_data_item->eCGI.pLMN_Identity); + MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, + &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier); + /* M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea */ + mbms_configuration_data_item->mbsfnSynchronisationArea=instance_p->mbms_configuration_data_list[i].mbsfn_sync_area; //? long + /* M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList */ + for(j=0;jmbms_configuration_data_list[i].num_mbms_service_area_list;j++){ + M2AP_MBMS_Service_Area_t * mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); + + char buf[2]; + INT16_TO_BUFFER(instance_p->mbms_configuration_data_list[i].mbms_service_area_list[j],buf); + OCTET_STRING_fromBuf(mbms_service_area,buf,2); + //LOG_D(M2AP,"%s\n",instance_p->mbms_configuration_data_list[i].mbms_service_area_list[j]); + //OCTET_STRING_fromBuf(mbms_service_area,"03",2); + ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area); + } + /*M2AP_MBMS_Service_Area_t * mbms_service_area,*mbms_service_area2; + mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); + mbms_service_area2 = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); + //memset(mbms_service_area,0,sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(mbms_service_area,"01",2); + ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area); + OCTET_STRING_fromBuf(mbms_service_area2,"02",2); + ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area2);*/ + + + } + + + //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item; + //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t)); + + //M2AP_ECGI_t eCGI; + //M2AP_PLMN_Identity_t pLMN_Identity; + //M2AP_EUTRANCellIdentifier_t eUTRANcellIdentifier + //M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea; + //M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList; + + + ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + LOG_D(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id); + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 setup request\n"); + return -1; + } + + + LOG_D(M2AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m2ap_eNB_data_p->ENBname); + + +// buffer = &bytes[0]; +// len = 40; +// +// for(int i=0; i < len; i++ ) +// printf("%02X",buffer[i]); +// printf("\n"); +// + m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return 0; +} + + +int eNB_handle_M2_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + + LOG_D(M2AP, "eNB_handle_M2_SETUP_RESPONSE\n"); + + AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome, + "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M2AP_ProcedureCode_id_m2Setup, + "pdu->choice.successfulOutcome.procedureCode != M2AP_ProcedureCode_id_M2Setup\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M2AP_Criticality_reject, + "pdu->choice.successfulOutcome.criticality != M2AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M2AP_SuccessfulOutcome__value_PR_M2SetupResponse, + "pdu->choice.successfulOutcome.value.present != M2AP_SuccessfulOutcome__value_PR_M2SetupResponse\n"); + + M2AP_M2SetupResponse_t *in = &pdu->choice.successfulOutcome.value.choice.M2SetupResponse; + + + M2AP_M2SetupResponse_Ies_t *ie; + //int GlobalMCE_ID = -1; + int num_cells_to_activate = 0; + //M2AP_Cells_to_be_Activated_List_Item_t *cell; + int i,j; + + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_RESP); + //MessageDef *msg_p2 = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_RESP); + + LOG_D(M2AP, "M2AP: M2Setup-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (j=0;j < in->protocolIEs.list.count; j++) { + ie = in->protocolIEs.list.array[j]; + switch (ie->id) { + case M2AP_ProtocolIE_ID_id_GlobalMCE_ID: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_M2SetupResponse_Ies__value_PR_GlobalMCE_ID, + "ie->value.present != M2AP_M2SetupResponse_Ies__value_PR_GlobalMCE_ID\n"); + LOG_D(M2AP, "M2AP: M2Setup-Resp: GlobalMCE_ID \n");/*, + GlobalMCE_ID);*/ + /*PLMNID_TO_MCC_MNC(&m2ap_pmchconfiguration_item->mbms_Session_List.list.array[k]->tmgi.pLMNidentity, + &M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mcc, + &M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc, + &M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].pmch_config_list[j].mbms_session_list[k].mnc_length);*/ + + + break; + case M2AP_ProtocolIE_ID_id_MCEname: + AssertFatal(ie->criticality == M2AP_Criticality_ignore, + "ie->criticality != M2AP_Criticality_ignore\n"); + AssertFatal(ie->value.present == M2AP_M2SetupResponse_Ies__value_PR_MCEname, + "ie->value.present != M2AP_M2SetupResponse_Ies__value_PR_MCEname\n"); + //M2AP_SETUP_RESP (msg_p).MCE_name = malloc(ie->value.choice.size+1); + //memcpy(M2AP_SETUP_RESP (msg_p).gNB_CU_name,ie->value.choice.GNB_CU_Name.buf,ie->value.choice.GNB_CU_Name.size); + //M2AP_SETUP_RESP (msg_p).gNB_CU_name[ie->value.choice.GNB_CU_Name.size]='\0'; + //LOG_D(M2AP, "M2AP: M2Setup-Resp: gNB_CU_name %s\n", + //M2AP_SETUP_RESP (msg_p).gNB_CU_name); + break; + case M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_M2SetupResponse_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea, + "ie->value.present != M2AP_M2SetupResponse_Ies__value_PR_MCCHrelatedBCCH_ConfigPerMBSFNArea\n"); + num_cells_to_activate = ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.count; + if(ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.count > 0 ){ + M2AP_SETUP_RESP(msg_p).num_mcch_config_per_mbsfn = ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.count; + } + //LOG_D(M2AP, "M2AP: Activating %d cells\n",num_cells_to_activate); + for (i=0;ivalue.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list.array[i]; + AssertFatal(mcch_related_bcch_config_per_mbms_area_ies->id == M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item, + " mcch_related_bcch_config_per_mbms_area_ies->id != M2AP_ProtocolIE_ID_id_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item "); + M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_Item_t * config_per_mbsfn_area_item = &mcch_related_bcch_config_per_mbms_area_ies->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea_Item; + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].pdcch_length = (uint8_t)config_per_mbsfn_area_item->pdcchLength; + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].offset = (uint8_t)config_per_mbsfn_area_item->offset; + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].modification_period = (uint8_t)config_per_mbsfn_area_item->modificationPeriod; + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].mcs = (uint8_t)config_per_mbsfn_area_item->modulationAndCodingScheme; + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].repetition_period = (uint8_t)config_per_mbsfn_area_item->repetitionPeriod; + + //LOG_E(M2AP,"mcs %lu\n",config_per_mbsfn_area_item->modulationAndCodingScheme); + //LOG_E(M2AP,"pdcch_length %lu\n",config_per_mbsfn_area_item->pdcchLength); + //LOG_E(M2AP,"modification_period %lu\n",config_per_mbsfn_area_item->modificationPeriod); + //LOG_E(M2AP,"repetition_period %lu\n",config_per_mbsfn_area_item->repetitionPeriod); + //LOG_E(M2AP,"offset %lu\n",config_per_mbsfn_area_item->offset); + //LOG_E(M2AP,"subframe_allocation_info %lu\n", config_per_mbsfn_area_item->subframeAllocationInfo.size); + + + if(config_per_mbsfn_area_item->subframeAllocationInfo.size == 1){ + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[i].subframe_allocation_info = config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]>>2; + LOG_D(M2AP,"subframe_allocation_info %d\n", config_per_mbsfn_area_item->subframeAllocationInfo.buf[0]); + } + } + break; + } + } + //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n"); + //AssertFatal(num_cells_to_activate>0,"No cells activated\n"); + //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate; + + //for (int i=0;i 0, "System Information %d is missing",i); + + //MSC_LOG_RX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_CU, + // 0, + // 0, + // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id)); + //itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p2); + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + return 0; +} + +// SETUP FAILURE +int eNB_handle_M2_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) { + LOG_D(M2AP, "eNB_handle_M2_SETUP_FAILURE\n"); + + M2AP_M2SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome.value.choice.M2SetupFailure; + + + M2AP_M2SetupFailure_Ies_t *ie; + + + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_FAILURE); + + LOG_D(M2AP, "M2AP: M2Setup-Failure: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case M2AP_ProtocolIE_ID_id_TimeToWait: + AssertFatal(ie->criticality == M2AP_Criticality_ignore, + "ie->criticality != M2AP_Criticality_ignore\n"); + AssertFatal(ie->value.present == M2AP_M2SetupFailure_Ies__value_PR_TimeToWait, + "ie->value.present != M2AP_M2SetupFailure_Ies__value_PR_TimeToWait\n"); + LOG_D(M2AP, "M2AP: M2Setup-Failure: TimeToWait \n");/*, + GlobalMCE_ID);*/ + break; + } + } + //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n"); + //AssertFatal(num_cells_to_activate>0,"No cells activated\n"); + //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate; + + //for (int i=0;i 0, "System Information %d is missing",i); + + //MSC_LOG_RX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_CU, + // 0, + // 0, + // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id)); + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + return 0; +} + +/* + * eNB Configuration Update + */ +int eNB_send_eNB_CONFIGURATION_UPDATE(instance_t instance, m2ap_enb_configuration_update_t * m2ap_enb_configuration_update) +{ + + AssertFatal(1==0,"Not implemented yet\n"); + + M2AP_M2AP_PDU_t pdu; + M2AP_ENBConfigurationUpdate_t *out; + M2AP_ENBConfigurationUpdate_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + //int j = 0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_eNBConfigurationUpdate; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_ENBConfigurationUpdate; + out = &pdu.choice.initiatingMessage.value.choice.ENBConfigurationUpdate; + + /* mandatory */ + /* c1. GlobalENB_ID (integer value) */ + ie = (M2AP_ENBConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_ENBConfigurationUpdate_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_ENBConfigurationUpdate_Ies__value_PR_GlobalENB_ID; + //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP); + MCC_MNC_TO_PLMNID(0, 0, 3, + &ie->value.choice.GlobalENB_ID.pLMN_Identity); + ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID; + MACRO_ENB_ID_TO_BIT_STRING(10, + &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); + M2AP_INFO("%d -> %02x%02x%02x\n", 10, + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. ENBname */ + if (0) { + ie = (M2AP_ENBConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_ENBConfigurationUpdate_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENBname; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_ENBConfigurationUpdate_Ies__value_PR_ENBname; + //OCTET_STRING_fromBuf(&ie->value.choice.ENBname, m2ap_eNB_data_p->eNB_name, + //strlen(m2ap_eNB_data_p->eNB_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c4. serverd cells list */ + ie = (M2AP_ENBConfigurationUpdate_Ies_t *)calloc(1, sizeof(M2AP_ENBConfigurationUpdate_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List_ConfigUpdate; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_ENBConfigurationUpdate_Ies__value_PR_ENB_MBMS_Configuration_data_List_ConfigUpdate; + + int num_mbms_available = 1;//m2ap_du_data->num_mbms_available; + LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available); + + for (i=0; + iid = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item; + mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject; + mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item; + + M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item; + mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item; + { + /* M2AP_ECGI_t eCGI */ + MCC_MNC_TO_PLMNID(0, 0, 3, + &mbms_configuration_data_item->eCGI.pLMN_Identity); + MACRO_ENB_ID_TO_CELL_IDENTITY(10,0, + &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier); + /* M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea */ + mbms_configuration_data_item->mbsfnSynchronisationArea=10000; //? long + /* M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList */ + M2AP_MBMS_Service_Area_t * mbms_service_area,*mbms_service_area2; + mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); + mbms_service_area2 = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); + //memset(mbms_service_area,0,sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(mbms_service_area,"01",2); + ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area); + OCTET_STRING_fromBuf(mbms_service_area2,"02",2); + ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area2); + + + } + + + //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item; + //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t)); + + //M2AP_ECGI_t eCGI; + //M2AP_PLMN_Identity_t pLMN_Identity; + //M2AP_EUTRANCellIdentifier_t eUTRANcellIdentifier + //M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea; + //M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList; + + + ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List_ConfigUpdate.list,mbms_configuration_data_list_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //LOG_D(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id); + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 setup request\n"); + return -1; + } + + + LOG_D(M2AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m2ap_eNB_data_p->ENBname); + + +// buffer = &bytes[0]; +// len = 40; +// +// for(int i=0; i < len; i++ ) +// printf("%02X",buffer[i]); +// printf("\n"); +// + m2ap_eNB_itti_send_sctp_data_req(instance, m2ap_enb_data_g->assoc_id, buffer, len, 0); + + return 0; +} + +int eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + + AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M2AP, "eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE\n"); + + M2AP_ENBConfigurationUpdateFailure_t *in = &pdu->choice.unsuccessfulOutcome.value.choice.ENBConfigurationUpdateFailure; + + + //M2AP_ENBConfigurationUpdateFailure_Ies_t *ie; + + + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE); + + LOG_D(M2AP, "M2AP: ENBConfigurationUpdate-Failure: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + //for (int i=0;i < in->protocolIEs.list.count; i++) { + // ie = in->protocolIEs.list.array[i]; + // // switch (ie->id) { + // // case M2AP_ProtocolIE_ID_id_TimeToWait: + // // AssertFatal(ie->criticality == M2AP_Criticality_ignore, + // // "ie->criticality != M2AP_Criticality_ignore\n"); + // // AssertFatal(ie->value.present == M2AP_M2SetupFailure_Ies__value_PR_TimeToWait, + // // "ie->value.present != M2AP_M2SetupFailure_Ies__value_PR_TimeToWait\n"); + // // LOG_D(M2AP, "M2AP: M2Setup-Failure: TimeToWait %d\n");/*, + // // GlobalMCE_ID);*/ + // // break; + // // } + //} + //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n"); + //AssertFatal(num_cells_to_activate>0,"No cells activated\n"); + //M2AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate; + + //for (int i=0;i 0, "System Information %d is missing",i); + + //MSC_LOG_RX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_CU, + // 0, + // 0, + // MSC_AS_TIME_FMT" eNB_handle_M2_SETUP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + //LOG_D(M2AP, "Sending M2AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MOeNBLE_ID_TO_INSTANCE(assoc_id)); + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + return 0; +} + + + +int eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + LOG_D(M2AP, "eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_ENBConfigurationUpdateAcknowledge_t *container; + //M2AP_ENBConfigurationUpdateAcknowledge_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.ENBConfigurationUpdate; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_ENB_CONFIGURATION_UPDATE_ACK); + + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + return 0; +} + + +/* + * MCE Configuration Update + */ +int eNB_handle_MCE_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + LOG_D(M2AP, "eNB_handle_MCE_CONFIGURATION_UPDATE assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_MCEConfigurationUpdate_t *container; + //M2AP_MCEConfigurationUpdate_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.MCEConfigurationUpdate; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MCE_CONFIGURATION_UPDATE); + + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + return 0; +} + +int eNB_send_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + M2AP_MCEConfigurationUpdateFailure_t *MCEConfigurationUpdateFailure) +{ + + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + + +int eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + M2AP_MCEConfigurationUpdateAcknowledge_t *MCEConfigurationUpdateAcknowledge) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + + +/* + * Error Indication + */ +int eNB_send_ERROR_INDICATION(instance_t instance, m2ap_error_indication_t * m2ap_error_indication) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + +int eNB_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + + + +/* + * Session Update Request + */ +int eNB_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + LOG_D(M2AP, "eNB_handle_MBMS_SESSION_STOP_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_SessionUpdateRequest_t *container; + //M2AP_SessionUpdateRequest_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.SessionUpdateRequest; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_UPDATE_REQ); + + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + + return 0; +} + + +int eNB_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m2ap_mbms_session_update_resp_t * m2ap_mbms_session_update_resp) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + + +int eNB_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m2ap_mbms_session_update_failure_t * m2ap_mbms_session_update_failure) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + +/* + * Service Counting + */ + +int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu) +{ + LOG_D(M2AP, "eNB_handle_MBMS_SERVICE_COUNTING_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M2AP_MbmsServiceCountingRequest_t *container; + //M2AP_MbmsServiceCountingRequest_Ies_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + // container = &pdu->choice.initiatingMessage.value.choice.MbmsServiceCountingRequest; + + /* M2 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ); + + + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + + + return 0; +} +int eNB_send_MBMS_SERVICE_COUNTING_REPORT(instance_t instance, m2ap_mbms_service_counting_report_t * m2ap_mbms_service_counting_report) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} +int eNB_send_MBMS_SERVICE_COUNTING_RESP(instance_t instance, m2ap_mbms_service_counting_resp_t * m2ap_mbms_service_counting_resp) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} +int eNB_send_MBMS_SERVICE_COUNTING_FAILURE(instance_t instance, m2ap_mbms_service_counting_failure_t * m2ap_mbms_service_counting_failure) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + +/* + * Overload Notification + */ +int eNB_send_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, m2ap_mbms_overload_notification_t * m2ap_mbms_overload_notification) +{ + AssertFatal(1==0,"Not implemented yet\n"); + return 0; +} + + + + diff --git a/openair2/M2AP/m2ap_eNB_interface_management.h b/openair2/M2AP/m2ap_eNB_interface_management.h new file mode 100644 index 0000000000..09bab1f125 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_interface_management.h @@ -0,0 +1,173 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_interface_management.h + * \brief m2ap interface management for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#ifndef M2AP_ENB_INTERFACE_MANAGEMENT_H_ +#define M2AP_ENB_INTERFACE_MANAGEMENT_H_ + +/* + * Session Start + */ + +int eNB_handle_MBMS_SESSION_START_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int eNB_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m2ap_session_start_resp_t * m2ap_session_start_resp); +int eNB_send_MBMS_SESSION_START_FAILURE(instance_t instance, m2ap_session_start_failure_t * m2ap_session_start_failure ); + +/* + * Session Stop + */ + +int eNB_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +int eNB_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m2ap_session_stop_resp_t * m2ap_session_stop_resp); + + +/* + * MBMS Scheduling Information + */ + +int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, m2ap_mbms_scheduling_information_resp_t * m2ap_mbms_scheduling_information_resp); + + +/* + * Reset + */ +int eNB_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +int eNB_send_RESET_ACKKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge); +int eNB_send_RESET(instance_t instance, M2AP_Reset_t *Reset); +int eNB_handle_RESET_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * M2AP Setup + */ +int eNB_send_M2_SETUP_REQUEST( m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p); + +int eNB_handle_M2_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int eNB_handle_M2_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * eNB Configuration Update + */ +int eNB_send_eNB_CONFIGURATION_UPDATE(instance_t instance, m2ap_enb_configuration_update_t * m2ap_enb_configuration_update); + +int eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +/* + * MCE Configuration Update + */ +int eNB_handle_MCE_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int eNB_send_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + M2AP_MCEConfigurationUpdateFailure_t *MCEConfigurationUpdateFailure); + +int eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + M2AP_MCEConfigurationUpdateAcknowledge_t *MCEConfigurationUpdateAcknowledge); + +/* + * Error Indication + */ +int eNB_send_ERROR_INDICATION(instance_t instance, m2ap_error_indication_t * m2ap_error_indication); +int eNB_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + + +/* + * Session Update Request + */ +int eNB_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); + +int eNB_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m2ap_mbms_session_update_resp_t * m2ap_mbms_session_update_resp); //?? + +int eNB_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m2ap_mbms_session_update_failure_t * m2ap_mbms_session_update_failure); + +/* + * Service Counting + */ + +int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M2AP_M2AP_PDU_t *pdu); +int eNB_send_MBMS_SERVICE_COUNTING_REPORT(instance_t instance, m2ap_mbms_service_counting_report_t * m2ap_mbms_service_counting_report); +int eNB_send_MBMS_SERVICE_COUNTING_RESP(instance_t instance, m2ap_mbms_service_counting_resp_t * m2ap_mbms_service_counting_resp); +int eNB_send_MBMS_SERVICE_COUNTING_FAILURE(instance_t instance, m2ap_mbms_service_counting_failure_t * m2ap_mbms_service_counting_failure); + + +/* + * Overload Notification + */ +int eNB_send_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, m2ap_mbms_overload_notification_t * m2ap_mbms_overload_notification); + + +#endif /* M2AP_ENB_INTERFACE_MANAGEMENT_H_ */ + + + diff --git a/openair2/M2AP/m2ap_eNB_management_procedures.c b/openair2/M2AP/m2ap_eNB_management_procedures.c new file mode 100644 index 0000000000..b3ada92fa8 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_management_procedures.c @@ -0,0 +1,257 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_management_procedures.c + * \brief m2ap tasks for eNB + * \author Javier Morgade + * \date 2018 + * \version 1.0 + */ + +#include +#include +#include + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "m2ap_common.h" +#include "m2ap_eNB_defs.h" +#include "m2ap_eNB.h" + + +#define M2AP_DEBUG_LIST +#ifdef M2AP_DEBUG_LIST +# define M2AP_eNB_LIST_OUT(x, args...) M2AP_DEBUG("[eNB]%*s"x"\n", 4*indent, "", ##args) +#else +# define M2AP_eNB_LIST_OUT(x, args...) +#endif + +static int indent = 0; + + +m2ap_eNB_internal_data_t m2ap_eNB_internal_data; + +RB_GENERATE(m2ap_enb_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id); + +int m2ap_eNB_compare_assoc_id( + struct m2ap_eNB_data_s *p1, struct m2ap_eNB_data_s *p2) +{ + if (p1->assoc_id == -1) { + if (p1->cnx_id < p2->cnx_id) { + return -1; + } + + if (p1->cnx_id > p2->cnx_id) { + return 1; + } + } else { + if (p1->assoc_id < p2->assoc_id) { + return -1; + } + + if (p1->assoc_id > p2->assoc_id) { + return 1; + } + } + + /* Matching reference */ + return 0; +} + +uint16_t m2ap_eNB_fetch_add_global_cnx_id(void) +{ + return ++m2ap_eNB_internal_data.global_cnx_id; +} + +void m2ap_eNB_prepare_internal_data(void) +{ + memset(&m2ap_eNB_internal_data, 0, sizeof(m2ap_eNB_internal_data)); + STAILQ_INIT(&m2ap_eNB_internal_data.m2ap_eNB_instances_head); +} + +void m2ap_eNB_insert_new_instance(m2ap_eNB_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&m2ap_eNB_internal_data.m2ap_eNB_instances_head, + new_instance_p, m2ap_eNB_entries); +} + +void dump_tree_m2(m2ap_eNB_data_t *t) +{ + if (t == NULL) return; + printf("-----------------------\n"); + printf("eNB id %d %s\n", t->eNB_id, t->eNB_name); + printf("state %d\n", t->state); + printf("nextstream %d\n", t->nextstream); + printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams); + printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id); + dump_tree_m2(t->entry.rbe_left); + dump_tree_m2(t->entry.rbe_right); +} + +void dump_trees_m2(void) +{ +m2ap_eNB_instance_t *zz; +STAILQ_FOREACH(zz, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, + m2ap_eNB_entries) { +printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +dump_tree_m2(zz->m2ap_enb_head.rbh_root); +printf("---------------------------------------------\n"); +} +} + +struct m2ap_eNB_data_s *m2ap_get_eNB(m2ap_eNB_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id) +{ + struct m2ap_eNB_data_s temp; + struct m2ap_eNB_data_s *found; + +printf("m2ap_get_eNB at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +dump_trees_m2(); + + memset(&temp, 0, sizeof(struct m2ap_eNB_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, + m2ap_eNB_entries) { + found = RB_FIND(m2ap_enb_map, &instance_p->m2ap_enb_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(m2ap_enb_map, &instance_p->m2ap_enb_head, &temp); + } + + return NULL; +} + + +m2ap_eNB_instance_t *m2ap_eNB_get_instance(instance_t instance) +{ + m2ap_eNB_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, + m2ap_eNB_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} + +/// utility functions + +void m2ap_dump_eNB (m2ap_eNB_data_t * eNB_ref); + +void +m2ap_dump_eNB_list (void) { + m2ap_eNB_instance_t *inst = NULL; + struct m2ap_eNB_data_s *found = NULL; + struct m2ap_eNB_data_s temp; + + memset(&temp, 0, sizeof(struct m2ap_eNB_data_s)); + + STAILQ_FOREACH (inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) { + found = RB_FIND(m2ap_enb_map, &inst->m2ap_enb_head, &temp); + m2ap_dump_eNB (found); + } +} + +void m2ap_dump_eNB (m2ap_eNB_data_t * eNB_ref) { + + if (eNB_ref == NULL) { + return; + } + + M2AP_eNB_LIST_OUT (""); + M2AP_eNB_LIST_OUT ("eNB name: %s", eNB_ref->eNB_name == NULL ? "not present" : eNB_ref->eNB_name); + M2AP_eNB_LIST_OUT ("eNB STATE: %07x", eNB_ref->state); + M2AP_eNB_LIST_OUT ("eNB ID: %07x", eNB_ref->eNB_id); + indent++; + M2AP_eNB_LIST_OUT ("SCTP cnx id: %d", eNB_ref->cnx_id); + M2AP_eNB_LIST_OUT ("SCTP assoc id: %d", eNB_ref->assoc_id); + M2AP_eNB_LIST_OUT ("SCTP instreams: %d", eNB_ref->in_streams); + M2AP_eNB_LIST_OUT ("SCTP outstreams: %d", eNB_ref->out_streams); + indent--; +} + +m2ap_eNB_data_t * m2ap_is_eNB_pci_in_list (const uint32_t pci) +{ + m2ap_eNB_instance_t *inst; + struct m2ap_eNB_data_s *elm; + + STAILQ_FOREACH(inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) { + RB_FOREACH(elm, m2ap_enb_map, &inst->m2ap_enb_head) { + for (int i = 0; inum_cc; i++) { + if (elm->Nid_cell[i] == pci) { + return elm; + } + } + } + } + return NULL; +} + +m2ap_eNB_data_t * m2ap_is_eNB_id_in_list (const uint32_t eNB_id) +{ + m2ap_eNB_instance_t *inst; + struct m2ap_eNB_data_s *elm; + + STAILQ_FOREACH(inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) { + RB_FOREACH(elm, m2ap_enb_map, &inst->m2ap_enb_head) { + if (elm->eNB_id == eNB_id) + return elm; + } + } + return NULL; +} + +m2ap_eNB_data_t * m2ap_is_eNB_assoc_id_in_list (const uint32_t sctp_assoc_id) +{ + m2ap_eNB_instance_t *inst; + struct m2ap_eNB_data_s *found; + struct m2ap_eNB_data_s temp; + + temp.assoc_id = sctp_assoc_id; + temp.cnx_id = -1; + + STAILQ_FOREACH(inst, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) { + found = RB_FIND(m2ap_enb_map, &inst->m2ap_enb_head, &temp); + if (found != NULL){ + if (found->assoc_id == sctp_assoc_id) { + return found; + } + } + } + return NULL; +} diff --git a/openair2/M2AP/m2ap_eNB_management_procedures.h b/openair2/M2AP/m2ap_eNB_management_procedures.h new file mode 100644 index 0000000000..fbc49d0169 --- /dev/null +++ b/openair2/M2AP/m2ap_eNB_management_procedures.h @@ -0,0 +1,54 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_management_procedures.h + * \brief m2ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENB_MANAGEMENT_PROCEDURES_H_ +#define M2AP_ENB_MANAGEMENT_PROCEDURES_H + +void m2ap_eNB_prepare_internal_data(void); + +void dump_trees_m2(void); + +void m2ap_eNB_insert_new_instance(m2ap_eNB_instance_t *new_instance_p); + +m2ap_eNB_instance_t *m2ap_eNB_get_instance(uint8_t mod_id); + +uint16_t m2ap_eNB_fetch_add_global_cnx_id(void); + +//void m2ap_eNB_prepare_internal_data(void); + +m2ap_eNB_data_t* m2ap_is_eNB_id_in_list(uint32_t eNB_id); + +m2ap_eNB_data_t* m2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id); + +m2ap_eNB_data_t* m2ap_is_eNB_pci_in_list (const uint32_t pci); + +struct m2ap_eNB_data_s *m2ap_get_eNB(m2ap_eNB_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id); + +#endif /* M2AP_ENB_MANAGEMENT_PROCEDURES_H_ */ diff --git a/openair2/M2AP/m2ap_encoder.c b/openair2/M2AP/m2ap_encoder.c new file mode 100644 index 0000000000..8f798ff55c --- /dev/null +++ b/openair2/M2AP/m2ap_encoder.c @@ -0,0 +1,61 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_encoder.c + * \brief m2ap encoder procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" +#include "intertask_interface.h" +#include "m2ap_common.h" +#include "m2ap_encoder.h" + +int m2ap_encode_pdu(M2AP_M2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + ssize_t encoded; + + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, (void *)pdu); + } + + encoded = aper_encode_to_new_buffer(&asn_DEF_M2AP_M2AP_PDU, 0, pdu, (void **)buffer); + + if (encoded < 0) { + return -1; + } + + *len = encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, pdu); + return encoded; +} diff --git a/openair2/M2AP/m2ap_encoder.h b/openair2/M2AP/m2ap_encoder.h new file mode 100644 index 0000000000..cf844f2983 --- /dev/null +++ b/openair2/M2AP/m2ap_encoder.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_encoder.h + * \brief m2ap encoder procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENCODER_H_ +#define M2AP_ENCODER_H_ + +int m2ap_encode_pdu(M2AP_M2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +__attribute__ ((warn_unused_result)); + +#endif /* M2AP_ENCODER_H_ */ diff --git a/openair2/M2AP/m2ap_handler.c b/openair2/M2AP/m2ap_handler.c new file mode 100644 index 0000000000..1221bcedb5 --- /dev/null +++ b/openair2/M2AP/m2ap_handler.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_handler.c + * \brief m2ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m2ap_common.h" +#include "m2ap_eNB_defs.h" +//#include "m2ap_handler.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +//#include "m2ap_eNB_management_procedures.h" +#include "m2ap_eNB_generate_messages.h" + +#include "m2ap_MCE_interface_management.h" +#include "m2ap_eNB_interface_management.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +/* Handlers matrix. Only eNB related procedure present here */ +m2ap_message_decoded_callback m2ap_messages_callback[][3] = { + { eNB_handle_MBMS_SESSION_START_REQUEST, MCE_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */ + { eNB_handle_MBMS_SESSION_STOP_REQUEST, MCE_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */ + { eNB_handle_MBMS_SCHEDULING_INFORMATION, MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE, 0 }, /* MBMSSchedulingInformation */ + { 0, 0, 0 }, /* Error Indication */ + { 0, 0, 0 }, /* Reset */ + { MCE_handle_M2_SETUP_REQUEST,eNB_handle_M2_SETUP_RESPONSE,eNB_handle_M2_SETUP_FAILURE }, /* M2 Setup */ + { 0, 0, 0 }, /* eNBConfigurationUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { 0, 0, 0 }, /* privateMessage */ + { 0, 0, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MBMSServiceCounting */ + { 0, 0, 0 }, /* MBMSServiceCountingResultReport */ + { 0, 0, 0 } /* MBMSOverloadNotification */ +}; + +static char *m2ap_direction2String(int m2ap_dir) { +static char *m2ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m2ap_direction_String[m2ap_dir]); +} + + +int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + M2AP_M2AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + if (m2ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(M2AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_messages_callback) / (3 * sizeof( + m2ap_message_decoded_callback)) + || (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(M2AP, "Calling handler with instance %d\n",instance); + ret = (*m2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); + return ret; +} + + diff --git a/openair2/M2AP/m2ap_handler.h b/openair2/M2AP/m2ap_handler.h new file mode 100644 index 0000000000..88fb26bc3e --- /dev/null +++ b/openair2/M2AP/m2ap_handler.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_handler.h + * \brief m2ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENB_OLD_HANDLERS_H_ +#define M2AP_ENB_OLD_HANDLERS_H_ + +#include "m2ap_eNB_defs.h" + +void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + +int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + + +#endif /* M2AP_ENB_OLD_HANDLERS_H_ */ diff --git a/openair2/M2AP/m2ap_ids.c b/openair2/M2AP/m2ap_ids.c new file mode 100644 index 0000000000..347ba36d82 --- /dev/null +++ b/openair2/M2AP/m2ap_ids.c @@ -0,0 +1,128 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "m2ap_ids.h" + +#include + +void m2ap_id_manager_init(m2ap_id_manager *m) +{ + int i; + memset(m, 0, sizeof(m2ap_id_manager)); + for (i = 0; i < M2AP_MAX_IDS; i++) + m->ids[i].rnti = -1; +} + +int m2ap_allocate_new_id(m2ap_id_manager *m) +{ + int i; + for (i = 0; i < M2AP_MAX_IDS; i++) + if (m->ids[i].rnti == -1) { + m->ids[i].rnti = 0; + m->ids[i].id_source = -1; + m->ids[i].id_target = -1; + return i; + } + return -1; +} + +void m2ap_release_id(m2ap_id_manager *m, int id) +{ + m->ids[id].rnti = -1; +} + +int m2ap_find_id(m2ap_id_manager *m, int id_source, int id_target) +{ + int i; + for (i = 0; i < M2AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source && + m->ids[i].id_target == id_target) + return i; + return -1; +} + +int m2ap_find_id_from_id_source(m2ap_id_manager *m, int id_source) +{ + int i; + for (i = 0; i < M2AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source) + return i; + return -1; +} + +int m2ap_find_id_from_rnti(m2ap_id_manager *m, int rnti) +{ + int i; + for (i = 0; i < M2AP_MAX_IDS; i++) + if (m->ids[i].rnti == rnti) + return i; + return -1; +} + +void m2ap_set_ids(m2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target) +{ + m->ids[ue_id].rnti = rnti; + m->ids[ue_id].id_source = id_source; + m->ids[ue_id].id_target = id_target; +} + +/* real type of target is m2ap_eNB_data_t * */ +void m2ap_id_set_target(m2ap_id_manager *m, int ue_id, void *target) +{ + m->ids[ue_id].target = target; +} + +void m2ap_id_set_state(m2ap_id_manager *m, int ue_id, m2id_state_t state) +{ + m->ids[ue_id].state = state; +} + +void m2ap_set_reloc_prep_timer(m2ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].t_reloc_prep_start = time; +} + +void m2ap_set_reloc_overall_timer(m2ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].tm2_reloc_overall_start = time; +} + +int m2ap_id_get_id_source(m2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_source; +} + +int m2ap_id_get_id_target(m2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_target; +} + +int m2ap_id_get_rnti(m2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].rnti; +} + +void *m2ap_id_get_target(m2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].target; +} diff --git a/openair2/M2AP/m2ap_ids.h b/openair2/M2AP/m2ap_ids.h new file mode 100644 index 0000000000..8603d67788 --- /dev/null +++ b/openair2/M2AP/m2ap_ids.h @@ -0,0 +1,80 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef M2AP_IDS_H_ +#define M2AP_IDS_H_ + +#include + +/* maximum number of simultaneous handovers, do not set too high */ +#define M2AP_MAX_IDS 16 + +/* + * state: + * - when starting handover in source, UE is in state M2ID_STATE_SOURCE_PREPARE + * - after receiving HO_ack in source, UE is in state M2ID_STATE_SOURCE_OVERALL + * - in target, UE is in state X2ID_STATE_TARGET + * The state is used to check timers. + */ +typedef enum { + M2ID_STATE_SOURCE_PREPARE, + M2ID_STATE_SOURCE_OVERALL, + M2ID_STATE_TARGET +} m2id_state_t; + +typedef struct { + int rnti; /* -1 when free */ + int id_source; + int id_target; + + /* the target eNB. Real type is m2ap_eNB_data_t * */ + void *target; + + /* state: needed to check timers */ + m2id_state_t state; + + /* timers */ + uint64_t t_reloc_prep_start; + uint64_t tm2_reloc_overall_start; +} m2ap_id; + +typedef struct { + m2ap_id ids[M2AP_MAX_IDS]; +} m2ap_id_manager; + +void m2ap_id_manager_init(m2ap_id_manager *m); +int m2ap_allocate_new_id(m2ap_id_manager *m); +void m2ap_release_id(m2ap_id_manager *m, int id); +int m2ap_find_id(m2ap_id_manager *, int id_source, int id_target); +int m2ap_find_id_from_id_source(m2ap_id_manager *, int id_source); +int m2ap_find_id_from_rnti(m2ap_id_manager *, int rnti); +void m2ap_set_ids(m2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target); +void m2ap_id_set_state(m2ap_id_manager *m, int ue_id, m2id_state_t state); +/* real type of target is m2ap_eNB_data_t * */ +void m2ap_id_set_target(m2ap_id_manager *m, int ue_id, void *target); +void m2ap_set_reloc_prep_timer(m2ap_id_manager *m, int ue_id, uint64_t time); +void m2ap_set_reloc_overall_timer(m2ap_id_manager *m, int ue_id, uint64_t time); +int m2ap_id_get_id_source(m2ap_id_manager *m, int ue_id); +int m2ap_id_get_id_target(m2ap_id_manager *m, int ue_id); +int m2ap_id_get_rnti(m2ap_id_manager *m, int ue_id); +void *m2ap_id_get_target(m2ap_id_manager *m, int ue_id); + +#endif /* M2AP_IDS_H_ */ diff --git a/openair2/M2AP/m2ap_itti_messaging.c b/openair2/M2AP/m2ap_itti_messaging.c new file mode 100644 index 0000000000..b9cfd32901 --- /dev/null +++ b/openair2/M2AP/m2ap_itti_messaging.c @@ -0,0 +1,96 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_itti_messaging.c + * \brief m2ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +#include "m2ap_itti_messaging.h" + +void m2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + //LOG_W(M2AP,"assoc_id %d, stream %d\n",assoc_id,stream); + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m2ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m2ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} diff --git a/openair2/M2AP/m2ap_itti_messaging.h b/openair2/M2AP/m2ap_itti_messaging.h new file mode 100644 index 0000000000..bdc416bca7 --- /dev/null +++ b/openair2/M2AP/m2ap_itti_messaging.h @@ -0,0 +1,48 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_itti_messaging.h + * \brief m2ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENB_ITTI_MESSAGING_H_ +#define M2AP_ENB_ITTI_MESSAGING_H_ + +void m2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + + +void m2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); + + +void m2ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + + +void m2ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); + + + + +#endif /* M2AP_ENB_ITTI_MESSAGING_H_ */ diff --git a/openair2/M2AP/m2ap_timers.c b/openair2/M2AP/m2ap_timers.c new file mode 100644 index 0000000000..13ec6423ac --- /dev/null +++ b/openair2/M2AP/m2ap_timers.c @@ -0,0 +1,105 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "m2ap_timers.h" +#include "assertions.h" +#include "PHY/defs_common.h" /* TODO: try to not include this */ +#include "m2ap_messages_types.h" +#include "m2ap_eNB_defs.h" +#include "m2ap_ids.h" +#include "m2ap_eNB_management_procedures.h" +#include "m2ap_eNB_generate_messages.h" + +void m2ap_timers_init(m2ap_timers_t *t, int t_reloc_prep, int tm2_reloc_overall) +{ + t->tti = 0; + t->t_reloc_prep = t_reloc_prep; + t->tm2_reloc_overall = tm2_reloc_overall; +} + +void m2ap_check_timers(instance_t instance) +{ + //m2ap_eNB_instance_t *instance_p; + //m2ap_timers_t *t; + //m2ap_id_manager *m; + //int i; + //m2ap_handover_cancel_cause_t cause; + //void *target; + //MessageDef *msg; + //int m2_ongoing; + + //instance_p = m2ap_eNB_get_instance(instance); + //DevAssert(instance_p != NULL); + + //t = &instance_p->timers; + //m = &instance_p->id_manager; + + ///* increment subframe count */ + //t->tti++; + + //m2_ongoing = 0; + + //for (i = 0; i < M2AP_MAX_IDS; i++) { + // if (m->ids[i].rnti == -1) continue; + // m2_ongoing++; + + // if (m->ids[i].state == M2ID_STATE_SOURCE_PREPARE && + // t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) { + // LOG_I(M2AP, "M2 timeout reloc prep\n"); + // /* t_reloc_prep timed out */ + // cause = M2AP_T_RELOC_PREP_TIMEOUT; + // goto timeout; + // } + + // if (m->ids[i].state == M2ID_STATE_SOURCE_OVERALL && + // t->tti > m->ids[i].tm2_reloc_overall_start + t->tm2_reloc_overall) { + // LOG_I(M2AP, "M2 timeout reloc overall\n"); + // /* tm2_reloc_overall timed out */ + // cause = M2AP_TM2_RELOC_OVERALL_TIMEOUT; + // goto timeout; + // } + + // /* no timeout -> check next UE */ + // continue; + + // timeout: + // /* inform target about timeout */ + // target = m2ap_id_get_target(m, i); + // m2ap_eNB_generate_m2_handover_cancel(instance_p, target, i, cause); + + // /* inform RRC of cancellation */ + // msg = itti_alloc_new_message(TASK_M2AP, M2AP_HANDOVER_CANCEL); + // M2AP_HANDOVER_CANCEL(msg).rnti = m2ap_id_get_rnti(m, i); + // M2AP_HANDOVER_CANCEL(msg).cause = cause; + // itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + // /* remove UE from M2AP */ + // m2ap_release_id(m, i); + //} + + //if (m2_ongoing && t->tti % 1000 == 0) + // LOG_I(M2AP, "M2 has %d process ongoing\n", m2_ongoing); +} + +uint64_t m2ap_timer_get_tti(m2ap_timers_t *t) +{ + return t->tti; +} diff --git a/openair2/M2AP/m2ap_timers.h b/openair2/M2AP/m2ap_timers.h new file mode 100644 index 0000000000..d2875d92af --- /dev/null +++ b/openair2/M2AP/m2ap_timers.h @@ -0,0 +1,45 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef M2AP_TIMERS_H_ +#define M2AP_TIMERS_H_ + +#include +#include "platform_types.h" + +typedef struct { + /* incremented every TTI (every millisecond when in realtime). + * Used to check timers. + * 64 bits gives us more than 500 million years of (realtime) processing. + * It should be enough. + */ + uint64_t tti; + + /* timer values (unit: TTI, ie. millisecond when in realtime) */ + int t_reloc_prep; + int tm2_reloc_overall; +} m2ap_timers_t; + +void m2ap_timers_init(m2ap_timers_t *t, int t_reloc_prep, int tm2_reloc_overall); +void m2ap_check_timers(instance_t instance); +uint64_t m2ap_timer_get_tti(m2ap_timers_t *t); + +#endif /* M2AP_TIMERS_H_ */ diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c new file mode 100644 index 0000000000..32dfa5cc42 --- /dev/null +++ b/openair2/MCE_APP/mce_app.c @@ -0,0 +1,754 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mce_app.c + ------------------- + AUTHOR : Javier Morgade + COMPANY : VICOMTECH Spain + EMAIL : javier.morgade@ieee.org +*/ + +#include +#include + +#include "mce_app.h" +#include "mce_config.h" +#include "assertions.h" +#include "common/ran_context.h" +#include "targets/RT/USER/lte-softmodem.h" + +#include "common/utils/LOG/log.h" + +# include "intertask_interface.h" +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# include "gtpv1u_eNB_task.h" +# include "flexran_agent.h" + +# include "x2ap_eNB.h" +# include "x2ap_messages_types.h" +# include "m2ap_eNB.h" +# include "m2ap_MCE.h" +# include "m2ap_messages_types.h" +# include "m3ap_MCE.h" +# include "m3ap_messages_types.h" +# define X2AP_ENB_REGISTER_RETRY_DELAY 10 + +#include "openair1/PHY/INIT/phy_init.h" +extern unsigned char NB_MCE_INST; + +extern RAN_CONTEXT_t RC; + +# define MCE_REGISTER_RETRY_DELAY 10 + +#include "targets/RT/USER/lte-softmodem.h" + +static m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information_local = NULL; +static m2ap_setup_resp_t * m2ap_setup_resp_local = NULL; +static m2ap_setup_req_t * m2ap_setup_req_local = NULL; + + +/*------------------------------------------------------------------------------*/ + +static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, uint32_t mce_id_end) { + uint32_t mce_id; + MessageDef *msg_p; + uint32_t register_mce_pending = 0; + + for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { + { + // M3AP registration + /* note: there is an implicit relationship between the data structure and the message name */ + msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_REGISTER_MCE_REQ); + //RCconfig_S1(msg_p, mce_id); + + //if (mce_id == 0) + //RCconfig_gtpu(); + + //LOG_I(MCE_APP,"default drx %d\n",((M3AP_REGISTER_MCE_REQ(msg_p)).default_drx)); + + LOG_I(ENB_APP,"[MCE %d] MCE_app_register via M3AP for instance %d\n", mce_id, ENB_MODULE_ID_TO_INSTANCE(mce_id)); + itti_send_msg_to_task (TASK_M3AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); + + //if (NODE_IS_DU(node_type)) { // F1AP registration + // // configure F1AP here for F1C + // LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); + // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); + // RCconfig_DU_F1(msg_p, enb_id); + + // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); + // itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + // // configure GTPu here for F1U + //} + //else { // S1AP registration + // /* note: there is an implicit relationship between the data structure and the message name */ + // msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); + // RCconfig_S1(msg_p, enb_id); + + // if (enb_id == 0) RCconfig_gtpu(); + + // LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx)); + + // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); + // itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + //} + + register_mce_pending++; + } + } + + return register_mce_pending; +} + + +/*------------------------------------------------------------------------------*/ +//static uint32_t MCE_app_register_x2(uint32_t mce_id_start, uint32_t mce_id_end) { +// uint32_t mce_id; +// MessageDef *msg_p; +// uint32_t register_mce_m2_pending = 0; +// +// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { +// { +// msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); +// RCconfig_X2(msg_p, mce_id); +// itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); +// register_mce_x2_pending++; +// } +// } +// +// return register_mce_x2_pending; +//} + +/*------------------------------------------------------------------------------*/ +//static uint32_t MCE_app_register_m2(uint32_t mce_id_start, uint32_t mce_id_end) { +// uint32_t mce_id; +// MessageDef *msg_p; +// uint32_t register_mce_m2_pending = 0; +// +// LOG_W(MCE_APP,"Register ..."); +// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { +// { +// // LOG_W(MCE_APP,"Register commes inside ...\n"); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_REGISTER_MCE_REQ); +// //RCconfig_M2_MCE(msg_p, mce_id); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); +// // LOG_W(MCE_APP,"Register sent ...\n"); +// register_mce_m2_pending++; +// } +// } +// +// return register_mce_m2_pending; +//} +// +/*------------------------------------------------------------------------------*/ +static uint32_t MCE_app_register_m3(uint32_t mce_id_start, uint32_t mce_id_end) { + uint32_t mce_id; + MessageDef *msg_p; + uint32_t register_mce_m3_pending = 0; + + LOG_D(MCE_APP,"Register ...\n"); + for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { + { + // LOG_W(MCE_APP,"Register commes inside ...\n"); + msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_REGISTER_MCE_REQ); + RCconfig_M3(msg_p, mce_id); + itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); + LOG_D(MCE_APP,"Register sent ...\n"); + register_mce_m3_pending++; + } + } + + return register_mce_m3_pending; +} + +/*************************** M3AP MCE handle **********************************/ +//static uint32_t MCE_app_handle_m3ap_mbms_session_start_req(instance_t instance){ +// //uint32_t mce_id=0; +// // MessageDef *msg_p; +// // msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_START_RESP); +// // itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// +// return 0; +//} + +static uint32_t MCE_app_handle_m3ap_mbms_session_stop_req(instance_t instance){ + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_STOP_RESP); + itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} + +static uint32_t MCE_app_handle_m3ap_mbms_session_update_req(instance_t instance){ + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_UPDATE_RESP); + itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} +//// end M3AP MCE handle **********************************/ + + +/*************************** M2AP MCE handle **********************************/ +static uint32_t MCE_app_handle_m2ap_setup_req(instance_t instance){ + + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_SETUP_RESP); + if(m2ap_setup_resp_local) + memcpy(&M2AP_SETUP_RESP(msg_p),m2ap_setup_resp_local,sizeof(m2ap_setup_resp_t)); + else + RCconfig_M2_MCCH(msg_p,0); + + + itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} + +static uint32_t MCE_app_handle_m2ap_mbms_session_start_resp(instance_t instance){ + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_START_RESP); + itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + return 0; +} + +//// end M2AP MCE handle **********************************/ + + +/*************************** M2AP MCE send **********************************/ +static uint32_t MCE_app_send_m2ap_mbms_scheduling_information(instance_t instance){ + + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SCHEDULING_INFORMATION); + if(m2ap_mbms_scheduling_information_local) + memcpy(&M2AP_MBMS_SCHEDULING_INFORMATION(msg_p),m2ap_mbms_scheduling_information_local,sizeof(m2ap_mbms_scheduling_information_t)); + else + RCconfig_M2_SCHEDULING(msg_p,0); + itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} + +static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ + + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SESSION_START_REQ); + itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} +//static uint32_t MCE_app_send_m2ap_session_stop_req(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SESSION_STOP_REQ); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} +//static uint32_t MCE_app_send_m2ap_mce_configuration_update(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MCE_CONFIGURATION_UPDATE); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} +//static uint32_t MCE_app_send_m2ap_enb_configuration_update_ack(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_ENB_CONFIGURATION_UPDATE_ACK); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} +//static uint32_t MCE_app_send_m2ap_enb_configuration_update_failure(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} //// end M2AP MCE send **********************************/ + +//static uint32_t MCE_app_send_MME_APP(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MCE_APP, MESSAGE_TEST); +// itti_send_msg_to_task (TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} + +//static uint32_t MCE_app_send_MME_APP2(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MCE_APP, MESSAGE_TEST); +// itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} + +/*------------------------------------------------------------------------------*/ +void *MCE_app_task(void *args_p) { + uint32_t mce_nb = 1;//RC.nb_inst; + uint32_t mce_id_start = 0; + uint32_t mce_id_end = mce_id_start + mce_nb; + uint32_t register_mce_pending=0; + uint32_t registered_mce=0; + //long mce_register_retry_timer_id; + long mce_scheduling_info_timer_id; + //uint32_t m3_register_mce_pending = 0; + // uint32_t x2_registered_mce = 0; + // long x2_mce_register_retry_timer_id; + // uint32_t m2_register_mce_pending = 0; + // uint32_t m2_registered_mce = 0; + // long m2_mce_register_retry_timer_id; + MessageDef *msg_p = NULL; + instance_t instance; + int result; + /* for no gcc warnings */ + (void)instance; + itti_mark_task_ready (TASK_MCE_APP); + + /* Try to register each MCE */ + // This assumes that node_type of all RRC instances is the same + if (EPC_MODE_ENABLED) { + register_mce_pending = MCE_app_register(RC.rrc[0]->node_type, mce_id_start, mce_id_end); + } + + /* Try to register each MCE with each other */ + // if (is_x2ap_enabled() && !NODE_IS_DU(RC.rrc[0]->node_type)) { + // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end); + // } + // MCE_app_send_MME_APP2(0); + + + if (is_m2ap_MCE_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) { + RCconfig_MCE(); + + if(!m2ap_mbms_scheduling_information_local) + m2ap_mbms_scheduling_information_local = (m2ap_mbms_scheduling_information_t*)calloc(1,sizeof(m2ap_mbms_scheduling_information_t)); + if(m2ap_mbms_scheduling_information_local) + RCconfig_m2_scheduling(m2ap_mbms_scheduling_information_local,0); + + if(!m2ap_setup_resp_local) + m2ap_setup_resp_local = (m2ap_setup_resp_t*)calloc(1,sizeof(m2ap_setup_resp_t)); + if(m2ap_setup_resp_local) + RCconfig_m2_mcch(m2ap_setup_resp_local,0); + } + + // /* Try to register each MCE with MCE each other */ + if (is_m3ap_MCE_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) { + ///*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end); + } + + do { + // Wait for a message + itti_receive_msg (TASK_MCE_APP, &msg_p); + instance = ITTI_MSG_INSTANCE (msg_p); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(MCE_APP, " *** Exiting MCE_APP thread\n"); + itti_exit_task (); + break; + + case MESSAGE_TEST: + LOG_I(MCE_APP, "Received %s\n", ITTI_MSG_NAME(msg_p)); + break; + + case SOFT_RESTART_MESSAGE: + //handle_reconfiguration(instance); + break; + + case M3AP_REGISTER_MCE_CNF: + //AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n"); + LOG_I(MCE_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + M3AP_REGISTER_MCE_CNF(msg_p).nb_mme); + DevAssert(register_mce_pending > 0); + register_mce_pending--; + + /* Check if at least MCE is registered with one MME */ + if (M3AP_REGISTER_MCE_CNF(msg_p).nb_mme > 0) { + registered_mce++; + } + + /* Check if all register MCE requests have been processed */ + if (register_mce_pending == 0) { + if (registered_mce == mce_nb) { + /* If all MCE are registered, start L2L1 task */ + // MessageDef *msg_init_p; + // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + } else { + LOG_W(MCE_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n", + mce_nb - registered_mce, MCE_REGISTER_RETRY_DELAY); + + // /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &mce_register_retry_timer_id) < 0) { + // LOG_E(MCE_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n"); + // sleep(MCE_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // registered_mce = 0; + // register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end); + // } + } + } + + break; + + case M3AP_MBMS_SESSION_START_REQ: + LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_START_REQ message %s\n", ITTI_MSG_NAME (msg_p)); + //MCE_app_handle_m3ap_mbms_session_start_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + if(m2ap_setup_req_local) + if (timer_setup (2, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &mce_scheduling_info_timer_id) < 0) { + } + + + break; + + case M3AP_MBMS_SESSION_STOP_REQ: + LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_STOP_REQ message %s\n", ITTI_MSG_NAME (msg_p)); + MCE_app_handle_m3ap_mbms_session_stop_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + break; + + case M3AP_MBMS_SESSION_UPDATE_REQ: + LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_UPDATE_REQ message %s\n", ITTI_MSG_NAME (msg_p)); + MCE_app_handle_m3ap_mbms_session_update_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + break; + + + + case M3AP_SETUP_RESP: + LOG_I(MCE_APP, "Received M3AP_SETUP_RESP message %s\n", ITTI_MSG_NAME (msg_p)); + // //AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/MCE\n"); + + // //LOG_I(MCE_APP, "Received %s: associated ngran_MCE_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), + // //F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate); + // + // //handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p)); + // handle_m3ap_setup_resp(&M3AP_SETUP_RESP(msg_p)); + + // DevAssert(register_mce_pending > 0); + // register_mce_pending--; + + // /* Check if at least MCE is registered with one MME */ + // //if (M3AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) { + // // registered_enb++; + // //} + + // /* Check if all register MCE requests have been processed */ + // if (register_mce_pending == 0) { + // if (registered_mce == mce_nb) { + // /* If all MCE cells are registered, start L2L1 task */ + // MessageDef *msg_init_p; + + // //msg_init_p = itti_alloc_new_message (TASK_MCE_APP, INITIALIZE_MESSAGE); + // //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + + // } else { + // LOG_W(MCE_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n", + // mce_nb - registered_mce, MCE_REGISTER_RETRY_DELAY); + + // /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &mce_register_retry_timer_id) < 0) { + // LOG_E(ENB_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n"); + + // sleep(MCE_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // registered_mce = 0; + // register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end);//, enb_properties_p); + // } + // } + // } + + break; + + case M3AP_DEREGISTERED_MCE_IND: + if (EPC_MODE_ENABLED) { + LOG_W(MCE_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme); + /* TODO handle recovering of registration */ + } + + break; + + case TIMER_HAS_EXPIRED: + LOG_I(MCE_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); + + if (TIMER_HAS_EXPIRED (msg_p).timer_id == mce_scheduling_info_timer_id/*mce_register_retry_timer_id*/) { + /* Restart the registration process */ + //registered_mce = 0; + //register_mce_pending = MCE_app_register (RC.rrc[0]->node_type, mce_id_start, mce_id_end); + MCE_app_send_m2ap_mbms_scheduling_information(0); + } + + //if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_mce_register_retry_timer_id) { + // /* Restart the registration process */ + // x2_registered_mce = 0; + // x2_register_mce_pending = MCE_app_register_x2 (mce_id_start, mce_id_end); + //} + + break; + + // case X2AP_DEREGISTERED_ENB_IND: + // LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2); + // /* TODO handle recovering of registration */ + // break; + + // case X2AP_REGISTER_ENB_CNF: + // LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // X2AP_REGISTER_ENB_CNF(msg_p).nb_x2); + // DevAssert(x2_register_enb_pending > 0); + // x2_register_enb_pending--; + + // /* Check if at least MCE is registered with one target MCE */ + // if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) { + // x2_registered_enb++; + // } + + // /* Check if all register MCE requests have been processed */ + // if (x2_register_enb_pending == 0) { + // if (x2_registered_enb == enb_nb) { + // /* If all MCE are registered, start RRC HO task */ + // } else { + // uint32_t x2_not_associated = enb_nb - x2_registered_enb; + // LOG_W(ENB_APP, " %d MCE %s not associated with the target\n", + // x2_not_associated, x2_not_associated > 1 ? "are" : "is"); + + // // timer to retry + // /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, + // INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, + // &x2_enb_register_retry_timer_id) < 0) { + // LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n"); + // sleep(X2AP_ENB_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // x2_registered_enb = 0; + // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end); + // } + // } + // } + + // break; + + // case M2AP_DEREGISTERED_ENB_IND: + // LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2); + // /* TODO handle recovering of registration */ + // break; + + // case M2AP_REGISTER_ENB_CNF: + // LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // M2AP_REGISTER_ENB_CNF(msg_p).nb_m2); + // DevAssert(m2_register_enb_pending > 0); + // m2_register_enb_pending--; + + // /* Check if at least MCE is registered with one target MCE */ + // if (M2AP_REGISTER_ENB_CNF(msg_p).nb_m2 > 0) { + // m2_registered_enb++; + // } + + // /* Check if all register MCE requests have been processed */ + // if (m2_register_enb_pending == 0) { + // if (m2_registered_enb == enb_nb) { + // /* If all MCE are registered, start RRC HO task */ + // } else { + // uint32_t m2_not_associated = enb_nb - m2_registered_enb; + // LOG_W(ENB_APP, " %d MCE %s not associated with the target\n", + // m2_not_associated, m2_not_associated > 1 ? "are" : "is"); + + // // timer to retry + // /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */ + // //if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, + // // INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, + // // &x2_enb_register_retry_timer_id) < 0) { + // // LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n"); + // // sleep(X2AP_ENB_REGISTER_RETRY_DELAY); + // // /* Restart the registration process */ + // // x2_registered_enb = 0; + // // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end); + // //} + // } + // } + + // break; + case M2AP_RESET: + LOG_I(MCE_APP, "Received M2AP_RESET message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_SETUP_REQ: + LOG_I(MCE_APP, "Received M2AP_SETUP_REQ message %s\n", ITTI_MSG_NAME (msg_p)); + if(!m2ap_setup_req_local) + m2ap_setup_req_local = (m2ap_setup_req_t*)calloc(1,sizeof(m2ap_setup_req_t)); + if(m2ap_setup_req_local) + memcpy(m2ap_setup_req_local,&M2AP_SETUP_REQ(msg_p),sizeof(m2ap_setup_req_t)); + MCE_app_handle_m2ap_setup_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + //MCE_app_send_m2ap_mbms_scheduling_information(0); + //if (timer_setup (2, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &mce_scheduling_info_timer_id) < 0) { + //} + + + /*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end); + + //MCE_app_send_m2ap_session_start_req(0); + break; + + case M2AP_MBMS_SESSION_START_RESP: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_START_RESP message %s\n", ITTI_MSG_NAME (msg_p)); + //MCE_app_send_m2ap_session_stop_req(0); + MCE_app_handle_m2ap_mbms_session_start_resp(0); + break; + + case M2AP_MBMS_SESSION_STOP_RESP: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_STOP_RESP message %s\n", ITTI_MSG_NAME (msg_p)); + //MCE_app_send_m2ap_session_start_req(0); + //MCE_app_handle_m2ap_mbms_session_start_resp(0); + //MCE_app_send_MME_APP(0); + break; + + case M2AP_MBMS_SCHEDULING_INFORMATION_RESP: + LOG_I(MCE_APP, "Received M2AP_MBMS_SCHEDULING_INFORMATION_RESP message %s\n", ITTI_MSG_NAME (msg_p)); + MCE_app_send_m2ap_session_start_req(0); + break; + + case M2AP_ENB_CONFIGURATION_UPDATE: + LOG_I(MCE_APP, "Received M2AP_ENB_CONFIGURATION_UPDATE message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_ERROR_INDICATION: + LOG_I(MCE_APP, "Received M2AP_ERROR_INDICATION message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MBMS_SESSION_UPDATE_RESP: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_RESP message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MBMS_SESSION_UPDATE_FAILURE: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_FAILURE message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MBMS_SERVICE_COUNTING_REPORT: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_REPORT message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MBMS_OVERLOAD_NOTIFICATION: + LOG_I(MCE_APP, "Received M2AP_MBMS_OVERLOAD_NOTIFICATION message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MBMS_SERVICE_COUNTING_RESP: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_RESP message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MBMS_SERVICE_COUNTING_FAILURE: + LOG_I(MCE_APP, "Received M2AP_MBMS_SESSION_UPDATE_FAILURE message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + case M2AP_MCE_CONFIGURATION_UPDATE_ACK: + LOG_I(MCE_APP, "Received M2AP_MCE_CONFIGURATION_UPDATE_ACK message %s\n", ITTI_MSG_NAME (msg_p)); + break; + case M2AP_MCE_CONFIGURATION_UPDATE_FAILURE: + LOG_I(MCE_APP, "Received M2AP_MCE_CONFIGURATION_UPDATE_FAILURE message %s\n", ITTI_MSG_NAME (msg_p)); + break; + + default: + LOG_E(MCE_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while (1); + + return NULL; +} + +//void handle_reconfiguration(module_id_t mod_id) { +// struct timespec start, end; +// clock_gettime(CLOCK_MONOTONIC, &start); +// flexran_agent_info_t *flexran = RC.flexran[mod_id]; +// LOG_I(ENB_APP, "lte-softmodem soft-restart requested\n"); +// +// if (ENB_WAIT == flexran->node_ctrl_state) { +// /* this is already waiting, just release */ +// pthread_mutex_lock(&flexran->mutex_node_ctrl); +// flexran->node_ctrl_state = ENB_NORMAL_OPERATION; +// pthread_mutex_unlock(&flexran->mutex_node_ctrl); +// pthread_cond_signal(&flexran->cond_node_ctrl); +// return; +// } +// +// if (stop_L1L2(mod_id) < 0) { +// LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); +// return; +// } +// +// /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not +// * executed by the FlexRAN thread */ +// if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { +// LOG_I(ENB_APP, " * MCE %d: Waiting for FlexRAN RTController command *\n", mod_id); +// pthread_mutex_lock(&flexran->mutex_node_ctrl); +// flexran->node_ctrl_state = ENB_WAIT; +// +// while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) +// pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); +// +// pthread_mutex_unlock(&flexran->mutex_node_ctrl); +// } +// +// if (restart_L1L2(mod_id) < 0) { +// LOG_E(ENB_APP, "can not restart, killing lte-softmodem\n"); +// exit_fun("can not restart L1L2, killing lte-softmodem"); +// return; +// } +// +// clock_gettime(CLOCK_MONOTONIC, &end); +// end.tv_sec -= start.tv_sec; +// +// if (end.tv_nsec >= start.tv_nsec) { +// end.tv_nsec -= start.tv_nsec; +// } else { +// end.tv_sec -= 1; +// end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; +// } +// +// LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); +//} + + diff --git a/openair2/MCE_APP/mce_app.h b/openair2/MCE_APP/mce_app.h new file mode 100644 index 0000000000..59146b9d0d --- /dev/null +++ b/openair2/MCE_APP/mce_app.h @@ -0,0 +1,41 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mce_app.h + ------------------- + AUTHOR : Javier Morgade + COMPANY : VICOMTECH Spain + EMAIL : javier.morgade@ieee.org +*/ + +#ifndef MCE_APP_H_ +#define MCE_APP_H_ + +#include +#include "platform_types.h" + + +void *MCE_app_task(void *args_p); + +//void handle_reconfiguration(module_id_t mod_id); + +#endif /* ENB_APP_H_ */ diff --git a/openair2/MCE_APP/mce_config.c b/openair2/MCE_APP/mce_config.c new file mode 100644 index 0000000000..975f524ebd --- /dev/null +++ b/openair2/MCE_APP/mce_config.c @@ -0,0 +1,512 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mce_config.c + ------------------- + AUTHOR : Javier Morgade + COMPANY : Vicomtech, Spain + EMAIL : javier.morgade@ieee.org +*/ + +#include +#include + +#include "common/utils/LOG/log.h" +#include "assertions.h" +#include "enb_config.h" +#include "UTIL/OTG/otg.h" +#include "UTIL/OTG/otg_externs.h" +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" +#include "common/ran_context.h" +#include "sctp_default_values.h" +#include "LTE_SystemInformationBlockType2.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "PHY/phy_extern.h" +#include "PHY/INIT/phy_init.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "nfapi_vnf.h" +#include "nfapi_pnf.h" + +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "enb_paramdef.h" +#include "proto_agent.h" + +#include "m3ap_MCE.h" + + + +int RCconfig_MCE(void ) { + //int num_enbs = 0; + //char *enb_interface_name_for_S1U = NULL; + char *mce_interface_name_for_m2_enb = NULL; + char *mce_interface_name_for_m3_mme = NULL; + //char *enb_ipv4_address_for_S1U = NULL; + char *mce_ipv4_address_for_m2c = NULL; + char *mce_ipv4_address_for_m3c = NULL; + //uint32_t enb_port_for_S1U = 0; + uint32_t mce_port_for_m2c = 0; + uint32_t mce_port_for_m3c = 0; + char *address = NULL; + char *cidr = NULL; + //char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; + char mcepath[MAX_OPTNAME_SIZE*2 + 8]; + //paramdef_t ENBSParams[] = ENBSPARAMS_DESC; + //paramdef_t GTPUParams[] = GTPUPARAMS_DESC; + + paramdef_t MCEParams[] = MCE_NETPARAMS_DESC; + + ///* get number of active eNodeBs */ + //config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + //num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; + //AssertFatal (num_enbs >0, + // "Failed to parse config file no active eNodeBs in %s \n", ENB_CONFIG_STRING_ACTIVE_ENBS); + //sprintf(gtpupath,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,0,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + //config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); + config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath); + //cidr = enb_ipv4_address_for_S1U; + cidr = mce_ipv4_address_for_m2c; + address = strtok(cidr, "/"); + + //LOG_W(MCE_APP,"cidr %s\n",cidr); + //LOG_W(MCE_APP,"address %s\n",address); + //LOG_W(MCE_APP,"mce_interface_name_for_m2_enb %s\n",mce_interface_name_for_m2_enb); + //LOG_W(MCE_APP,"mce_ipv4_address_for_m2c %s\n",mce_ipv4_address_for_m2c); + //LOG_W(MCE_APP,"mce_ipv4_address_for_m2c %s\n",*(MCEParams[1/*MCE_IPV4_ADDRESS_FOR_M2C_IDX*/].strptr)); + //LOG_W(MCE_APP,"mce_port_for_m2c %d\n",mce_port_for_m2c); + //LOG_W(MCE_APP,"mce_interface_name_for_m3_mme %s\n",mce_interface_name_for_m3_mme); + //LOG_W(MCE_APP,"mce_ipv4_address_for_m3c %s\n",mce_ipv4_address_for_m3c); + //LOG_W(MCE_APP,"mce_port_for_m3c %d\n",mce_port_for_m3c); + +// strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr)); + + + if (address) { + MessageDef *message; + AssertFatal((message = itti_alloc_new_message(TASK_MCE_APP, M2AP_MCE_SCTP_REQ))!=NULL,""); + //IPV4_STR_ADDR_TO_INT_NWBO ( address, M2AP_MCE_SCTP_REQ(message).mce_m2_ip_address, "BAD IP ADDRESS FORMAT FOR MCE M2_C !\n" ); + M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv6 = 0; + M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv4 = 1; + strcpy( M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv4_address, address); + //LOG_I(MCE_APP,"Configuring M2_C address : %s -> %x\n",address,M2AP_MCE_SCTP_REQ(message).mce_m2_ip_address); + M2AP_MCE_SCTP_REQ(message).mce_port_for_M2C = mce_port_for_m2c; + itti_send_msg_to_task (TASK_M2AP_MCE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + } else + LOG_E(MCE_APP,"invalid address for M2AP\n"); + + return 0; +} + + +int RCconfig_M3(MessageDef *msg_p, uint32_t i) { + int l; + //int num_enbs = 0; + //char *enb_interface_name_for_S1U = NULL; + char *mce_interface_name_for_m2_enb = NULL; + char *mce_interface_name_for_m3_mme = NULL; + //char *enb_ipv4_address_for_S1U = NULL; + char *mce_ipv4_address_for_m2c = NULL; + char *mce_ipv4_address_for_m3c = NULL; + //uint32_t enb_port_for_S1U = 0; + uint32_t mce_port_for_m2c = 0; + uint32_t mce_port_for_m3c = 0; + char *address = NULL; + char *cidr = NULL; + + + char mcepath[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MCEParams[] = MCE_NETPARAMS_DESC; + paramdef_t M3Params[] = M3PARAMS_DESC; + paramdef_t MCCHParams[] = MCCH_PARAMS_DESC; + + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath); + + paramlist_def_t M3ParamList = {MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS,NULL,0}; + paramlist_def_t MCCHParamList = {MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA,NULL,0}; + + char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(aprefix,"%s.[%i]","MCEs",0); + /* Some default/random parameters */ + M3AP_REGISTER_MCE_REQ (msg_p).MCE_id = i; + //M3AP_REGISTER_MCE_REQ (msg_p).MME_name = "kk"; + sprintf(aprefix,"%s.[%i]","MCEs",0); + config_getlist( &M3ParamList,M3Params,sizeof(M3Params)/sizeof(paramdef_t),aprefix); + //printf("M3ParamList.numelt %d\n",M3ParamList.numelt); + M3AP_REGISTER_MCE_REQ (msg_p).nb_m3 = 0; + for (l = 0; l < M3ParamList.numelt; l++) { + M3AP_REGISTER_MCE_REQ (msg_p).nb_m3 += 1; + M3AP_REGISTER_MCE_REQ (msg_p).MCE_name = strdup(*(M3ParamList.paramarray[l][MCE_MCE_NAME_IDX].strptr)); + + strcpy(M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4_address,*(M3ParamList.paramarray[l][MCE2_M3_IPV4_ADDRESS_IDX].strptr)); + strcpy(M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6_address,*(M3ParamList.paramarray[l][MCE2_M3_IPV6_ADDRESS_IDX].strptr)); + + if (strcmp(*(M3ParamList.paramarray[l][MCE2_M3_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4 = 1; + M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6 = 0; + } else if (strcmp(*(M3ParamList.paramarray[l][MCE2_M3_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4 = 0; + M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6 = 1; + } else if (strcmp(*(M3ParamList.paramarray[l][MCE2_M3_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv4 = 1; + M3AP_REGISTER_MCE_REQ (msg_p).target_mme_m3_ip_address[l].ipv6 = 1; + } + M3AP_REGISTER_MCE_REQ (msg_p).sctp_out_streams = 2; + M3AP_REGISTER_MCE_REQ (msg_p).sctp_in_streams = 2; + } + + sprintf(aprefix,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + config_get( MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),aprefix); + M3AP_REGISTER_MCE_REQ (msg_p).mme_port_for_M3C = (uint32_t)*(MCEParams[MCE2_PORT_FOR_M3C_IDX].uptr); + + if ((MCEParams[MCE2_IPV4_ADDR_FOR_M3C_IDX].strptr == NULL) || (M3AP_REGISTER_MCE_REQ (msg_p).mme_port_for_M3C == 0)) { + LOG_E(RRC,"Add eNB IPv4 address and/or port for M3C in the CONF file!\n"); + exit(1); + } + + cidr = *(MCEParams[MCE2_IPV4_ADDR_FOR_M3C_IDX].strptr); + address = strtok(cidr, "/"); + M3AP_REGISTER_MCE_REQ (msg_p).mme_m3_ip_address.ipv6 = 0; + M3AP_REGISTER_MCE_REQ (msg_p).mme_m3_ip_address.ipv4 = 1; + strcpy(M3AP_REGISTER_MCE_REQ (msg_p).mme_m3_ip_address.ipv4_address, address); + + sprintf(aprefix,"%s.[%i]","MCEs",0); + config_getlist( &MCCHParamList,MCCHParams,sizeof(MCCHParams)/sizeof(paramdef_t),aprefix); + //printf("MCCHParamList.numelt %d\n",MCCHParamList.numelt); + for (l = 0; l < MCCHParamList.numelt; l++) { + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mbsfn_area = *(MCCHParamList.paramarray[l][MCCH_MBSFN_AREA_IDX].uptr); + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].pdcch_length = *(MCCHParamList.paramarray[l][MCCH_PDCCH_LENGTH_IDX].uptr); + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].repetition_period = *(MCCHParamList.paramarray[l][MCCH_REPETITION_PERIOD_IDX].uptr); + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].offset = *(MCCHParamList.paramarray[l][MCCH_OFFSET_IDX].uptr); + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].modification_period = *(MCCHParamList.paramarray[l][MCCH_MODIFICATION_PERIOD_IDX].uptr); + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].subframe_allocation_info = *(MCCHParamList.paramarray[l][MCCH_SF_ALLOCATION_INFO_IDX].uptr); + //M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mcs = strdup(*(MCCHParamList.paramarray[l][MCCH_MCS_IDX].strptr)); + } + + + + + + return 0; +} +int RCconfig_m2_mcch(m2ap_setup_resp_t * m2ap_setup_resp, uint32_t i) { + int l; + + char mcepath[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MCCHParams[] = MCCH_PARAMS_DESC; + paramdef_t MCEParams[] = MCE_PARAMS_DESC; + paramdef_t PLNMParams[] = MCE_PLMN_PARAMS_DESC; + paramlist_def_t MCCHParamList = {MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA,NULL,0}; + char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(mcepath,"%s.[%i]","MCEs",0); + config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath); + m2ap_setup_resp->MCE_id = *(MCEParams[MCE_MCE_ID_IDX].uptr); + m2ap_setup_resp->MCE_name = strdup(*(MCEParams[MCE_MCE_NAME_IDX].strptr));; + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_PLMN); + config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath); + m2ap_setup_resp->mcc = *(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr); + m2ap_setup_resp->mnc = *(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr); + m2ap_setup_resp->mnc_digit_length = *(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr); + //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr)); + //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr)); + + + sprintf(aprefix,"%s.[%i]","MCEs",0); + config_getlist( &MCCHParamList,MCCHParams,sizeof(MCCHParams)/sizeof(paramdef_t),aprefix); + //printf("MCCHParamList.numelt %d\n",MCCHParamList.numelt); + AssertFatal(MCCHParamList.numelt <= 8, "File wrong parsed\n"); + for (l = 0; l < MCCHParamList.numelt; l++) { + m2ap_setup_resp->mcch_config_per_mbsfn[l].mbsfn_area = *(MCCHParamList.paramarray[l][MCCH_MBSFN_AREA_IDX].uptr); + m2ap_setup_resp->mcch_config_per_mbsfn[l].pdcch_length = *(MCCHParamList.paramarray[l][MCCH_PDCCH_LENGTH_IDX].uptr); + m2ap_setup_resp->mcch_config_per_mbsfn[l].repetition_period = *(MCCHParamList.paramarray[l][MCCH_REPETITION_PERIOD_IDX].uptr); + m2ap_setup_resp->mcch_config_per_mbsfn[l].offset = *(MCCHParamList.paramarray[l][MCCH_OFFSET_IDX].uptr); + m2ap_setup_resp->mcch_config_per_mbsfn[l].modification_period = *(MCCHParamList.paramarray[l][MCCH_MODIFICATION_PERIOD_IDX].uptr); + m2ap_setup_resp->mcch_config_per_mbsfn[l].subframe_allocation_info = *(MCCHParamList.paramarray[l][MCCH_SF_ALLOCATION_INFO_IDX].uptr); + m2ap_setup_resp->mcch_config_per_mbsfn[l].mcs = *(MCCHParamList.paramarray[l][MCCH_MCS_IDX].uptr); + } + m2ap_setup_resp->num_mcch_config_per_mbsfn = MCCHParamList.numelt; + return 0; +} +int RCconfig_M2_MCCH(MessageDef *msg_p, uint32_t i) { + int l; + + char mcepath[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MCCHParams[] = MCCH_PARAMS_DESC; + paramdef_t MCEParams[] = MCE_PARAMS_DESC; + paramdef_t PLNMParams[] = MCE_PLMN_PARAMS_DESC; + paramlist_def_t MCCHParamList = {MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA,NULL,0}; + char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(mcepath,"%s.[%i]","MCEs",0); + config_get(MCEParams,sizeof(MCEParams)/sizeof(paramdef_t),mcepath); + M2AP_SETUP_RESP (msg_p).MCE_id = *(MCEParams[MCE_MCE_ID_IDX].uptr); + M2AP_SETUP_RESP (msg_p).MCE_name = strdup(*(MCEParams[MCE_MCE_NAME_IDX].strptr));; + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_PLMN); + config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath); + M2AP_SETUP_RESP (msg_p).mcc = *(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr); + M2AP_SETUP_RESP (msg_p).mnc = *(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr); + M2AP_SETUP_RESP (msg_p).mnc_digit_length = *(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr); + //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr)); + //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr)); + + + sprintf(aprefix,"%s.[%i]","MCEs",0); + config_getlist( &MCCHParamList,MCCHParams,sizeof(MCCHParams)/sizeof(paramdef_t),aprefix); + //printf("MCCHParamList.numelt %d\n",MCCHParamList.numelt); + AssertFatal(MCCHParamList.numelt <= 8, "File wrong parsed\n"); + for (l = 0; l < MCCHParamList.numelt; l++) { + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mbsfn_area = *(MCCHParamList.paramarray[l][MCCH_MBSFN_AREA_IDX].uptr); + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].pdcch_length = *(MCCHParamList.paramarray[l][MCCH_PDCCH_LENGTH_IDX].uptr); + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].repetition_period = *(MCCHParamList.paramarray[l][MCCH_REPETITION_PERIOD_IDX].uptr); + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].offset = *(MCCHParamList.paramarray[l][MCCH_OFFSET_IDX].uptr); + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].modification_period = *(MCCHParamList.paramarray[l][MCCH_MODIFICATION_PERIOD_IDX].uptr); + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].subframe_allocation_info = *(MCCHParamList.paramarray[l][MCCH_SF_ALLOCATION_INFO_IDX].uptr); + M2AP_SETUP_RESP(msg_p).mcch_config_per_mbsfn[l].mcs = *(MCCHParamList.paramarray[l][MCCH_MCS_IDX].uptr); + } + M2AP_SETUP_RESP(msg_p).num_mcch_config_per_mbsfn = MCCHParamList.numelt; + + + return 0; +} +int RCconfig_m2_scheduling( m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information, uint32_t i) { + int l,j,k/*,m*/; + char mcepath[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MBMS_SCHE_Params[] = MCE_MBMS_SCHEDULING_INFO_PARAMS_DESC; + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO); + //LOG_E(MCE_APP,"%s\n",mcepath); + config_get(MBMS_SCHE_Params,sizeof(MBMS_SCHE_Params)/sizeof(paramdef_t),mcepath); + //LOG_E(MCE_APP,"%s %d\n",mcepath, *(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr)); + m2ap_mbms_scheduling_information->mcch_update_time=*(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr); + + paramdef_t MBMS_CONFIGURATION_Params[] = MCE_MBMS_AREA_CONFIGURATION_LIST_PARAMS_DESC; + paramlist_def_t MBMS_AREA_CONFIGURATION_ParamList = {MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,NULL,0}; + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO); + config_getlist(&MBMS_AREA_CONFIGURATION_ParamList,MBMS_CONFIGURATION_Params,sizeof(MBMS_CONFIGURATION_Params)/sizeof(paramdef_t),mcepath); + AssertFatal(MBMS_AREA_CONFIGURATION_ParamList.numelt <= 8, "File wrong parsed\n"); + //LOG_E(MCE_APP,"%s\n",mcepath); + //LOG_E(MCE_APP,"MBMS_AREA_CONFIGURATION_ParamList.numelt %d\n",MBMS_AREA_CONFIGURATION_ParamList.numelt); + + m2ap_mbms_scheduling_information->num_mbms_area_config_list = MBMS_AREA_CONFIGURATION_ParamList.numelt; + for (l = 0; l < MBMS_AREA_CONFIGURATION_ParamList.numelt; l++) { + m2ap_mbms_scheduling_information->mbms_area_config_list[l].common_sf_allocation_period = *(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_area_id=*(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_MBMS_AREA_ID_IDX].uptr); + char mcepath2[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t PMCH_Params[] = MCE_MBMS_PMCH_CONFIGURATION_LIST_PARAMS_DESC; + paramlist_def_t PMCH_ParamList = {MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,NULL,0}; + sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l); + //LOG_E(MCE_APP,"%s\n",mcepath2); + config_getlist(&PMCH_ParamList,PMCH_Params,sizeof(PMCH_Params)/sizeof(paramdef_t),mcepath2); + AssertFatal(PMCH_ParamList.numelt <= 8, "File wrong parsed\n"); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].num_pmch_config_list=PMCH_ParamList.numelt; + for(j = 0; j < PMCH_ParamList.numelt; j++){ + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].allocated_sf_end = *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_ALLOCATED_SF_END_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].data_mcs = *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_DATA_MCS_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mch_scheduling_period= *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD_IDX].uptr); + char mcepath3[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MBMS_SESSION_LIST_Params[] = MCE_MBMS_MBMS_SESSION_LIST_DESC; + paramlist_def_t MBMS_SESSION_LIST_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST,NULL,0}; + sprintf(mcepath3,"%s.[%i].%s.%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j); + config_getlist(&MBMS_SESSION_LIST_ParamList,MBMS_SESSION_LIST_Params,sizeof(MBMS_SESSION_LIST_Params)/sizeof(paramdef_t),mcepath3); + //LOG_E(MCE_APP,"%s ---- %d\n",mcepath3, MBMS_SESSION_LIST_ParamList.numelt); + AssertFatal(MBMS_SESSION_LIST_ParamList.numelt <= 8, "File wrong parsed\n"); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].num_mbms_session_list = MBMS_SESSION_LIST_ParamList.numelt; + for(k = 0; k < MBMS_SESSION_LIST_ParamList.numelt; k++ ){ + + //char mcepath4[MAX_OPTNAME_SIZE*8 + 8]; + //paramdef_t MBMS_SESSION_LIST_PER_PMCH_Params[] = MCE_MBMS_MBMS_SESSION_LIST_PER_PMCH_PARAMS_DESC; + //paramlist_def_t MBMS_SESSION_LIST_PER_PMCH_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST_PER_PMCH,NULL,0}; + //sprintf(mcepath4,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k); + //LOG_E(MCE_APP,"%s\n",mcepath4); + //config_getlist(&MBMS_SESSION_LIST_PER_PMCH_ParamList,MBMS_SESSION_LIST_PER_PMCH_Params,sizeof(MBMS_SESSION_LIST_PER_PMCH_Params)/sizeof(paramdef_t),mcepath4); + //m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].num_mbms_session_per_pmch = MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt; + //for(m = 0; m < MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt; m++){ + + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id = + *(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr); + uint32_t lcid =*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].lcid =lcid; + //uint32_t service_id2=*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr); + //m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id2 =service_id2; + //LOG_E(MCE_APP,"lcid %ld\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr)); + //LOG_E(MCE_APP,"service_id %d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr)); + + char mcepath5[MAX_OPTNAME_SIZE*8 + 8]; + paramdef_t PLNMParams[] = MCE_PLMN_PARAMS_DESC; + sprintf(mcepath5,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i].%s","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k,MCE_CONFIG_STRING_PLMN); + config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath5); + //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr)); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mcc = *(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc = *(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc_length = *(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr); + + //} + //LOG_E(MCE_APP,"MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt %d\n",MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt); + //AssertFatal(MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt <= 8, "File wrong parsed\n"); + + //printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_PLNM_IDENTITY_IDX].uptr)); + //printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_SERVICE_ID_IDX].uptr)); + //printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_LCID_IDX].uptr)); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + } + } + paramdef_t MBSFN_SF_Params[] = MCE_MBMS_MBMS_SF_CONFIGURATION_LIST_PARAMS_DESC; + paramlist_def_t MBSFN_SF_ParamList = {MCE_CONFIG_STRING_MBMS_SF_CONFIGURATION_LIST,NULL,0}; + sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l); + //LOG_E(MCE_APP,"%s\n",mcepath2); + config_getlist(&MBSFN_SF_ParamList,MBSFN_SF_Params,sizeof(MBSFN_SF_Params)/sizeof(paramdef_t),mcepath2); + AssertFatal(MBSFN_SF_ParamList.numelt <= 8, "File wrong parsed\n"); + + m2ap_mbms_scheduling_information->mbms_area_config_list[l].num_mbms_sf_config_list=MBSFN_SF_ParamList.numelt; + for(j = 0; j < MBSFN_SF_ParamList.numelt; j++){ + m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_period=*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD_IDX].uptr); + m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_offset = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET_IDX].uptr); + if(strcmp(*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_NUM_FRAME_IDX].strptr),"oneFrame")==0){ + m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 0; + }else{ + m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 1; + } + m2ap_mbms_scheduling_information->mbms_area_config_list[l].mbms_sf_config_list[j].subframe_allocation = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX].uptr); + } + + + } + return 0; +} +int RCconfig_M2_SCHEDULING(MessageDef *msg_p, uint32_t i) { + int l,j,k/*,m*/; + char mcepath[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MBMS_SCHE_Params[] = MCE_MBMS_SCHEDULING_INFO_PARAMS_DESC; + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO); + //LOG_E(MCE_APP,"%s\n",mcepath); + config_get(MBMS_SCHE_Params,sizeof(MBMS_SCHE_Params)/sizeof(paramdef_t),mcepath); + //LOG_E(MCE_APP,"%s %d\n",mcepath, *(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr)); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mcch_update_time=*(MBMS_SCHE_Params[MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX].uptr); + + paramdef_t MBMS_CONFIGURATION_Params[] = MCE_MBMS_AREA_CONFIGURATION_LIST_PARAMS_DESC; + paramlist_def_t MBMS_AREA_CONFIGURATION_ParamList = {MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,NULL,0}; + sprintf(mcepath,"%s.[%i].%s","MCEs",0,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO); + config_getlist(&MBMS_AREA_CONFIGURATION_ParamList,MBMS_CONFIGURATION_Params,sizeof(MBMS_CONFIGURATION_Params)/sizeof(paramdef_t),mcepath); + AssertFatal(MBMS_AREA_CONFIGURATION_ParamList.numelt <= 8, "File wrong parsed\n"); + //LOG_E(MCE_APP,"%s\n",mcepath); + //LOG_E(MCE_APP,"MBMS_AREA_CONFIGURATION_ParamList.numelt %d\n",MBMS_AREA_CONFIGURATION_ParamList.numelt); + + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).num_mbms_area_config_list = MBMS_AREA_CONFIGURATION_ParamList.numelt; + for (l = 0; l < MBMS_AREA_CONFIGURATION_ParamList.numelt; l++) { + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].common_sf_allocation_period = *(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_area_id=*(MBMS_AREA_CONFIGURATION_ParamList.paramarray[l][MCE_CONFIG_STRING_MBMS_AREA_ID_IDX].uptr); + char mcepath2[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t PMCH_Params[] = MCE_MBMS_PMCH_CONFIGURATION_LIST_PARAMS_DESC; + paramlist_def_t PMCH_ParamList = {MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,NULL,0}; + sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l); + //LOG_E(MCE_APP,"%s\n",mcepath2); + config_getlist(&PMCH_ParamList,PMCH_Params,sizeof(PMCH_Params)/sizeof(paramdef_t),mcepath2); + AssertFatal(PMCH_ParamList.numelt <= 8, "File wrong parsed\n"); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].num_pmch_config_list=PMCH_ParamList.numelt; + for(j = 0; j < PMCH_ParamList.numelt; j++){ + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].allocated_sf_end = *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_ALLOCATED_SF_END_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].data_mcs = *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_DATA_MCS_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mch_scheduling_period= *(PMCH_ParamList.paramarray[j][MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD_IDX].uptr); + char mcepath3[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t MBMS_SESSION_LIST_Params[] = MCE_MBMS_MBMS_SESSION_LIST_DESC; + paramlist_def_t MBMS_SESSION_LIST_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST,NULL,0}; + sprintf(mcepath3,"%s.[%i].%s.%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j); + config_getlist(&MBMS_SESSION_LIST_ParamList,MBMS_SESSION_LIST_Params,sizeof(MBMS_SESSION_LIST_Params)/sizeof(paramdef_t),mcepath3); + //LOG_E(MCE_APP,"%s ---- %d\n",mcepath3, MBMS_SESSION_LIST_ParamList.numelt); + AssertFatal(MBMS_SESSION_LIST_ParamList.numelt <= 8, "File wrong parsed\n"); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].num_mbms_session_list = MBMS_SESSION_LIST_ParamList.numelt; + for(k = 0; k < MBMS_SESSION_LIST_ParamList.numelt; k++ ){ + + //char mcepath4[MAX_OPTNAME_SIZE*8 + 8]; + //paramdef_t MBMS_SESSION_LIST_PER_PMCH_Params[] = MCE_MBMS_MBMS_SESSION_LIST_PER_PMCH_PARAMS_DESC; + //paramlist_def_t MBMS_SESSION_LIST_PER_PMCH_ParamList = {MCE_CONFIG_STRING_MBMS_SESSION_LIST_PER_PMCH,NULL,0}; + //sprintf(mcepath4,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k); + //LOG_E(MCE_APP,"%s\n",mcepath4); + //config_getlist(&MBMS_SESSION_LIST_PER_PMCH_ParamList,MBMS_SESSION_LIST_PER_PMCH_Params,sizeof(MBMS_SESSION_LIST_PER_PMCH_Params)/sizeof(paramdef_t),mcepath4); + //M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].num_mbms_session_per_pmch = MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt; + //for(m = 0; m < MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt; m++){ + + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id = + *(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr); + uint32_t lcid =*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].lcid =lcid; + //uint32_t service_id2=*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr); + //M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].service_id2 =service_id2; + //LOG_E(MCE_APP,"lcid %ld\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_LCID_IDX].uptr)); + //LOG_E(MCE_APP,"service_id %d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX].uptr)); + + char mcepath5[MAX_OPTNAME_SIZE*8 + 8]; + paramdef_t PLNMParams[] = MCE_PLMN_PARAMS_DESC; + sprintf(mcepath5,"%s.[%i].%s.%s.[%i].%s.[%i].%s.[%i].%s","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l,MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST,j,MCE_CONFIG_STRING_MBMS_SESSION_LIST,k,MCE_CONFIG_STRING_PLMN); + config_get(PLNMParams,sizeof(PLNMParams)/sizeof(paramdef_t),mcepath5); + //LOG_E(MCE_APP,"PLNM %d\n",*(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr)); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mcc = *(PLNMParams[MCE_CONFIG_STRING_MCC_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc = *(PLNMParams[MCE_CONFIG_STRING_MNC_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].pmch_config_list[j].mbms_session_list[k].mnc_length = *(PLNMParams[MCE_CONFIG_STRING_MNC_LENGTH_IDX].uptr); + + //} + //LOG_E(MCE_APP,"MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt %d\n",MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt); + //AssertFatal(MBMS_SESSION_LIST_PER_PMCH_ParamList.numelt <= 8, "File wrong parsed\n"); + + //printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_PLNM_IDENTITY_IDX].uptr)); + //printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_SERVICE_ID_IDX].uptr)); + //printf("%d\n",*(MBMS_SESSION_LIST_ParamList.paramarray[k][MCE_CONFIG_STRING_LCID_IDX].uptr)); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + //*((MBMS_SESSION_LIST_ParamList[k][].uptr); + } + } + paramdef_t MBSFN_SF_Params[] = MCE_MBMS_MBMS_SF_CONFIGURATION_LIST_PARAMS_DESC; + paramlist_def_t MBSFN_SF_ParamList = {MCE_CONFIG_STRING_MBMS_SF_CONFIGURATION_LIST,NULL,0}; + sprintf(mcepath2,"%s.[%i].%s.%s.[%i]","MCEs",i,MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO,MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST,l); + //LOG_E(MCE_APP,"%s\n",mcepath2); + config_getlist(&MBSFN_SF_ParamList,MBSFN_SF_Params,sizeof(MBSFN_SF_Params)/sizeof(paramdef_t),mcepath2); + AssertFatal(MBSFN_SF_ParamList.numelt <= 8, "File wrong parsed\n"); + + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].num_mbms_sf_config_list=MBSFN_SF_ParamList.numelt; + for(j = 0; j < MBSFN_SF_ParamList.numelt; j++){ + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_period=*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD_IDX].uptr); + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].radioframe_allocation_offset = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET_IDX].uptr); + if(strcmp(*(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_NUM_FRAME_IDX].strptr),"oneFrame")==0){ + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 0; + }else{ + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].is_four_sf = 1; + } + M2AP_MBMS_SCHEDULING_INFORMATION(msg_p).mbms_area_config_list[l].mbms_sf_config_list[j].subframe_allocation = *(MBSFN_SF_ParamList.paramarray[j][MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX].uptr); + } + + + } + + return 0; +} + diff --git a/openair2/MCE_APP/mce_config.h b/openair2/MCE_APP/mce_config.h new file mode 100644 index 0000000000..f339401540 --- /dev/null +++ b/openair2/MCE_APP/mce_config.h @@ -0,0 +1,71 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mce_config.h + ------------------- + AUTHOR : Javier Morgade + COMPANY : VICOMTECH, Spain + EMAIL : javier.morgade@ieee.org +*/ + +#ifndef MCE_CONFIG_H_ +#define MCE_CONFIG_H_ +#include +#include +#include +#include + +#include "commonDef.h" +#include "platform_types.h" +#include "platform_constants.h" +#include "PHY/impl_defs_lte.h" +#include "PHY/defs_eNB.h" +#include "s1ap_messages_types.h" +#include "f1ap_messages_types.h" +#include "LTE_SystemInformationBlockType2.h" +#include "rrc_messages_types.h" +#include "RRC/LTE/rrc_defs.h" +#include +#include "enb_paramdef.h" + +#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ + struct in_addr inp;\ + if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\ + AssertFatal (0, MeSsAgE);\ + } else {\ + NwBo = inp.s_addr;\ + }\ + } while (0); + + +void read_config_and_init(void); + +int RCconfig_MCE(void); +int RCconfig_M3(MessageDef *msg_p, uint32_t i); +int RCconfig_M2_MCCH(MessageDef *msg_p, uint32_t i); +int RCconfig_m2_mcch(m2ap_setup_resp_t * m2ap_setup_resp, uint32_t i); +int RCconfig_M2_SCHEDULING(MessageDef *msg_p, uint32_t i); +int RCconfig_m2_scheduling(m2ap_mbms_scheduling_information_t *m2ap_mbms_scheduling_information, uint32_t i); + + +#endif /* MCE_CONFIG_H_ */ +/** @} */ From 365527d401449f16399ca8f4395e94e7a2750d88 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:53:39 +0200 Subject: [PATCH 019/134] M3AP 3GPP TS 36.444 interface implemented: 1.MME entity developed to handle M3 side (new dedicated task developed: TASK_MME_APP) (these procedures should be moved to OPENAIR-CN ... just implemented to easy the E-UTRAN MBMS stuff development) 2.MCE side M3 interface procedures (new dedicated task developed: TASK_M3AP_MCE) 3.MME side M3 interface procedures (new dedicated task developed: TASK_M2AP_MME) (these procedures should be moved to OPENAIR-CN ... just implemented to easy the E-UTRAN MBMS stuff development) 4.ASN1 bindings for m3ap-14.0.0.asn1 implemented and tested 5.MME config parameters ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair3/M3AP/m3ap_MCE.c | 689 ++++++++++ openair3/M3AP/m3ap_MCE.h | 55 + openair3/M3AP/m3ap_MCE_defs.h | 210 +++ openair3/M3AP/m3ap_MCE_generate_messages.h | 63 + openair3/M3AP/m3ap_MCE_generate_messsages.c | 808 ++++++++++++ openair3/M3AP/m3ap_MCE_handler.c | 118 ++ openair3/M3AP/m3ap_MCE_handler.h | 43 + openair3/M3AP/m3ap_MCE_interface_management.c | 756 +++++++++++ openair3/M3AP/m3ap_MCE_interface_management.h | 119 ++ .../M3AP/m3ap_MCE_management_procedures.c | 257 ++++ .../M3AP/m3ap_MCE_management_procedures.h | 53 + openair3/M3AP/m3ap_MME.c | 730 +++++++++++ openair3/M3AP/m3ap_MME.h | 55 + openair3/M3AP/m3ap_MME_defs.h | 210 +++ openair3/M3AP/m3ap_MME_generate_messages.c | 804 ++++++++++++ openair3/M3AP/m3ap_MME_generate_messages.h | 63 + openair3/M3AP/m3ap_MME_handler.c | 118 ++ openair3/M3AP/m3ap_MME_handler.h | 43 + openair3/M3AP/m3ap_MME_interface_management.c | 1162 +++++++++++++++++ openair3/M3AP/m3ap_MME_interface_management.h | 111 ++ .../M3AP/m3ap_MME_management_procedures.c | 257 ++++ .../M3AP/m3ap_MME_management_procedures.h | 54 + openair3/M3AP/m3ap_common.c | 2 +- openair3/M3AP/m3ap_common.h | 8 - openair3/M3AP/m3ap_decoder.c | 217 +++ openair3/M3AP/m3ap_decoder.h | 35 + openair3/M3AP/m3ap_default_values.h | 47 + openair3/M3AP/m3ap_eNB_decoder.c | 155 +++ openair3/M3AP/m3ap_eNB_decoder.h | 35 + openair3/M3AP/m3ap_eNB_encoder.c | 61 + openair3/M3AP/m3ap_eNB_encoder.h | 35 + openair3/M3AP/m3ap_eNB_generate_messages.c | 804 ++++++++++++ openair3/M3AP/m3ap_eNB_generate_messages.h | 63 + openair3/M3AP/m3ap_eNB_handler.c | 985 ++++++++++++++ openair3/M3AP/m3ap_eNB_handler.h | 39 + openair3/M3AP/m3ap_eNB_itti_messaging.c | 62 + openair3/M3AP/m3ap_eNB_itti_messaging.h | 39 + openair3/M3AP/m3ap_encoder.c | 61 + openair3/M3AP/m3ap_encoder.h | 35 + openair3/M3AP/m3ap_handler.c | 123 ++ openair3/M3AP/m3ap_handler.h | 43 + openair3/M3AP/m3ap_ids.c | 128 ++ openair3/M3AP/m3ap_ids.h | 80 ++ openair3/M3AP/m3ap_itti_messaging.c | 96 ++ openair3/M3AP/m3ap_itti_messaging.h | 48 + openair3/M3AP/m3ap_timers.c | 105 ++ openair3/M3AP/m3ap_timers.h | 45 + openair3/MME_APP/enb_paramdef_mme.h | 174 +++ openair3/MME_APP/mme_app.c | 580 ++++++++ openair3/MME_APP/mme_app.h | 41 + openair3/MME_APP/mme_config.c | 111 ++ openair3/MME_APP/mme_config.h | 52 + 52 files changed, 11078 insertions(+), 9 deletions(-) create mode 100644 openair3/M3AP/m3ap_MCE.c create mode 100644 openair3/M3AP/m3ap_MCE.h create mode 100644 openair3/M3AP/m3ap_MCE_defs.h create mode 100644 openair3/M3AP/m3ap_MCE_generate_messages.h create mode 100644 openair3/M3AP/m3ap_MCE_generate_messsages.c create mode 100644 openair3/M3AP/m3ap_MCE_handler.c create mode 100644 openair3/M3AP/m3ap_MCE_handler.h create mode 100644 openair3/M3AP/m3ap_MCE_interface_management.c create mode 100644 openair3/M3AP/m3ap_MCE_interface_management.h create mode 100644 openair3/M3AP/m3ap_MCE_management_procedures.c create mode 100644 openair3/M3AP/m3ap_MCE_management_procedures.h create mode 100644 openair3/M3AP/m3ap_MME.c create mode 100644 openair3/M3AP/m3ap_MME.h create mode 100644 openair3/M3AP/m3ap_MME_defs.h create mode 100644 openair3/M3AP/m3ap_MME_generate_messages.c create mode 100644 openair3/M3AP/m3ap_MME_generate_messages.h create mode 100644 openair3/M3AP/m3ap_MME_handler.c create mode 100644 openair3/M3AP/m3ap_MME_handler.h create mode 100644 openair3/M3AP/m3ap_MME_interface_management.c create mode 100644 openair3/M3AP/m3ap_MME_interface_management.h create mode 100644 openair3/M3AP/m3ap_MME_management_procedures.c create mode 100644 openair3/M3AP/m3ap_MME_management_procedures.h create mode 100644 openair3/M3AP/m3ap_decoder.c create mode 100644 openair3/M3AP/m3ap_decoder.h create mode 100644 openair3/M3AP/m3ap_default_values.h create mode 100644 openair3/M3AP/m3ap_eNB_decoder.c create mode 100644 openair3/M3AP/m3ap_eNB_decoder.h create mode 100644 openair3/M3AP/m3ap_eNB_encoder.c create mode 100644 openair3/M3AP/m3ap_eNB_encoder.h create mode 100644 openair3/M3AP/m3ap_eNB_generate_messages.c create mode 100644 openair3/M3AP/m3ap_eNB_generate_messages.h create mode 100644 openair3/M3AP/m3ap_eNB_handler.c create mode 100644 openair3/M3AP/m3ap_eNB_handler.h create mode 100644 openair3/M3AP/m3ap_eNB_itti_messaging.c create mode 100644 openair3/M3AP/m3ap_eNB_itti_messaging.h create mode 100644 openair3/M3AP/m3ap_encoder.c create mode 100644 openair3/M3AP/m3ap_encoder.h create mode 100644 openair3/M3AP/m3ap_handler.c create mode 100644 openair3/M3AP/m3ap_handler.h create mode 100644 openair3/M3AP/m3ap_ids.c create mode 100644 openair3/M3AP/m3ap_ids.h create mode 100644 openair3/M3AP/m3ap_itti_messaging.c create mode 100644 openair3/M3AP/m3ap_itti_messaging.h create mode 100644 openair3/M3AP/m3ap_timers.c create mode 100644 openair3/M3AP/m3ap_timers.h create mode 100644 openair3/MME_APP/enb_paramdef_mme.h create mode 100644 openair3/MME_APP/mme_app.c create mode 100644 openair3/MME_APP/mme_app.h create mode 100644 openair3/MME_APP/mme_config.c create mode 100644 openair3/MME_APP/mme_config.h diff --git a/openair3/M3AP/m3ap_MCE.c b/openair3/M3AP/m3ap_MCE.c new file mode 100644 index 0000000000..232b0c0ece --- /dev/null +++ b/openair3/M3AP/m3ap_MCE.c @@ -0,0 +1,689 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE.c + * \brief m3ap tasks for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include +#include +#include + +#include "intertask_interface.h" + +#include "m3ap_MCE.h" +#include "m3ap_MCE_defs.h" +#include "m3ap_MCE_management_procedures.h" +#include "m3ap_MCE_handler.h" +//#include "m3ap_MCE_generate_messages.h" +#include "m3ap_common.h" +#include "m3ap_MCE_interface_management.h" +#include "m3ap_ids.h" +#include "m3ap_timers.h" + +#include "queue.h" +#include "assertions.h" +#include "conversions.h" + +struct m3ap_mce_map; +struct m3ap_MCE_data_s; + +m3ap_setup_req_t * m3ap_mce_data_g; + +RB_PROTOTYPE(m3ap_mce_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id); + +static +void m3ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); + +static +void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +static +void m3ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind); + +static +void m3ap_MCE_handle_register_MCE(instance_t instance, + m3ap_register_mce_req_t *m3ap_register_MME); +static +void m3ap_MCE_register_MCE(m3ap_MCE_instance_t *instance_p, + net_ip_address_t *target_MME_ip_addr, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t mce_port_for_M3C, + int multi_sd); + +//static +//void m3ap_eNB_handle_handover_req(instance_t instance, +// m3ap_handover_req_t *m3ap_handover_req); +// +//static +//void m3ap_eNB_handle_handover_req_ack(instance_t instance, +// m3ap_handover_req_ack_t *m3ap_handover_req_ack); +// +//static +//void m3ap_eNB_ue_context_release(instance_t instance, +// m3ap_ue_context_release_t *m3ap_ue_context_release); +// + +static +void m3ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { + int result; + DevAssert(sctp_data_ind != NULL); + m3ap_MCE_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + +static +void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + m3ap_MCE_instance_t *instance_p; + m3ap_MCE_data_t *m3ap_mce_data_p; + DevAssert(sctp_new_association_resp != NULL); + //printf("m3ap_eNB_handle_sctp_association_resp at 1\n"); + //dump_trees(); + instance_p = m3ap_MCE_get_instance(instance); + DevAssert(instance_p != NULL); + + /* if the assoc_id is already known, it is certainly because an IND was received + * before. In this case, just update streams and return + */ + if (sctp_new_association_resp->assoc_id != -1) { + m3ap_mce_data_p = m3ap_get_MCE(instance_p, sctp_new_association_resp->assoc_id, + sctp_new_association_resp->ulp_cnx_id); + + if (m3ap_mce_data_p != NULL) { + /* some sanity check - to be refined at some point */ + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + M3AP_ERROR("m3ap_mce_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); + abort(); + } + + m3ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams; + m3ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams; + return; + } + } + + m3ap_mce_data_p = m3ap_get_MCE(instance_p, -1, + sctp_new_association_resp->ulp_cnx_id); + DevAssert(m3ap_mce_data_p != NULL); + //printf("m3ap_MCE_handle_sctp_association_resp at 2\n"); + //dump_trees_m3(); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + //m3ap_handle_m3_setup_message(instance_p, m3ap_enb_data_p, + //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; + } + + //printf("m3ap_MCE_handle_sctp_association_resp at 3\n"); + //dump_trees_m3(); + /* Update parameters */ + m3ap_mce_data_p->assoc_id = sctp_new_association_resp->assoc_id; + m3ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams; + m3ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams; + //printf("m3ap_MCE_handle_sctp_association_resp at 4\n"); + //dump_trees_m3(); + + m3ap_mce_data_g->assoc_id = sctp_new_association_resp->assoc_id; + m3ap_mce_data_g->sctp_in_streams = sctp_new_association_resp->in_streams; + m3ap_mce_data_g->sctp_out_streams = sctp_new_association_resp->out_streams; + + /* Prepare new m3 Setup Request */ + //m3ap_eNB_generate_m3_setup_request(instance_p, m3ap_enb_data_p); + MCE_send_M3_SETUP_REQUEST(instance_p, m3ap_mce_data_p); +} + +static +void m3ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { + m3ap_MCE_instance_t *instance_p; + m3ap_MCE_data_t *m3ap_mce_data_p; + //printf("m3ap_MCE_handle_sctp_association_ind at 1 (called for instance %d)\n", instance); + //dump_trees_m3(); + DevAssert(sctp_new_association_ind != NULL); + instance_p = m3ap_MCE_get_instance(instance); + DevAssert(instance_p != NULL); + m3ap_mce_data_p = m3ap_get_MCE(instance_p, sctp_new_association_ind->assoc_id, -1); + + if (m3ap_mce_data_p != NULL) abort(); + + // DevAssert(m3ap_mce_data_p != NULL); + if (m3ap_mce_data_p == NULL) { + /* Create new MCE descriptor */ + m3ap_mce_data_p = calloc(1, sizeof(*m3ap_mce_data_p)); + DevAssert(m3ap_mce_data_p != NULL); + m3ap_mce_data_p->cnx_id = m3ap_MCE_fetch_add_global_cnx_id(); + m3ap_mce_data_p->m3ap_MCE_instance = instance_p; + /* Insert the new descriptor in list of known eNB + * but not yet associated. + */ + RB_INSERT(m3ap_mce_map, &instance_p->m3ap_mce_head, m3ap_mce_data_p); + m3ap_mce_data_p->state = M3AP_MCE_STATE_CONNECTED; + instance_p->m3_target_mme_nb++; + + if (instance_p->m3_target_mme_pending_nb > 0) { + instance_p->m3_target_mme_pending_nb--; + } + } else { + M3AP_WARN("m3ap_mce_data_p already exists\n"); + } + + //printf("m3ap_MCE_handle_sctp_association_ind at 2\n"); + //dump_trees_m3(); + /* Update parameters */ + m3ap_mce_data_p->assoc_id = sctp_new_association_ind->assoc_id; + m3ap_mce_data_p->in_streams = sctp_new_association_ind->in_streams; + m3ap_mce_data_p->out_streams = sctp_new_association_ind->out_streams; + //printf("m3ap_MCE_handle_sctp_association_ind at 3\n"); + //dump_trees_m3(); +} + +int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t mce_port_for_M3C) { + // Create and alloc new message + MessageDef *message; + sctp_init_t *sctp_init = NULL; + DevAssert(instance_p != NULL); + DevAssert(local_ip_addr != NULL); + message = itti_alloc_new_message (TASK_M3AP_MCE, SCTP_INIT_MSG_MULTI_REQ); + sctp_init = &message->ittiMsg.sctp_init_multi; + sctp_init->port = mce_port_for_M3C; + sctp_init->ppid = M3AP_SCTP_PPID; + sctp_init->ipv4 = 1; + sctp_init->ipv6 = 0; + sctp_init->nb_ipv4_addr = 1; +#if 0 + memcpy(&sctp_init->ipv4_address, + local_ip_addr, + sizeof(*local_ip_addr)); +#endif + sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + sctp_init->nb_ipv6_addr = 0; + sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); +} + +static void m3ap_MCE_register_MCE(m3ap_MCE_instance_t *instance_p, + net_ip_address_t *target_MCE_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t mce_port_for_M3C, + int multi_sd) { + MessageDef *message = NULL; + sctp_new_association_req_multi_t *sctp_new_association_req = NULL; + m3ap_MCE_data_t *m3ap_mce_data = NULL; + DevAssert(instance_p != NULL); + DevAssert(target_MCE_ip_address != NULL); + message = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI); + sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; + sctp_new_association_req->port = mce_port_for_M3C; + sctp_new_association_req->ppid = M3AP_SCTP_PPID; + sctp_new_association_req->in_streams = in_streams; + sctp_new_association_req->out_streams = out_streams; + sctp_new_association_req->multi_sd = multi_sd; + memcpy(&sctp_new_association_req->remote_address, + target_MCE_ip_address, + sizeof(*target_MCE_ip_address)); + memcpy(&sctp_new_association_req->local_address, + local_ip_addr, + sizeof(*local_ip_addr)); + /* Create new MCE descriptor */ + m3ap_mce_data = calloc(1, sizeof(*m3ap_mce_data)); + DevAssert(m3ap_mce_data != NULL); + m3ap_mce_data->cnx_id = m3ap_MCE_fetch_add_global_cnx_id(); + sctp_new_association_req->ulp_cnx_id = m3ap_mce_data->cnx_id; + m3ap_mce_data->assoc_id = -1; + m3ap_mce_data->m3ap_MCE_instance = instance_p; + /* Insert the new descriptor in list of known eNB + * but not yet associated. + */ + + m3ap_mce_data_g = (m3ap_setup_req_t*)calloc(1,sizeof(m3ap_setup_req_t)); + + + + RB_INSERT(m3ap_mce_map, &instance_p->m3ap_mce_head, m3ap_mce_data); + m3ap_mce_data->state = M3AP_MCE_STATE_WAITING; + instance_p->m3_target_mme_nb ++; + instance_p->m3_target_mme_pending_nb ++; + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message); +} + +static +void m3ap_MCE_handle_register_MCE(instance_t instance, + m3ap_register_mce_req_t *m3ap_register_MCE) { + m3ap_MCE_instance_t *new_instance; + DevAssert(m3ap_register_MCE != NULL); + /* Look if the provided instance already exists */ + new_instance = m3ap_MCE_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same MCE */ + DevCheck(new_instance->MCE_id == m3ap_register_MCE->MCE_id, new_instance->MCE_id, m3ap_register_MCE->MCE_id, 0); + DevCheck(new_instance->cell_type == m3ap_register_MCE->cell_type, new_instance->cell_type, m3ap_register_MCE->cell_type, 0); + DevCheck(new_instance->tac == m3ap_register_MCE->tac, new_instance->tac, m3ap_register_MCE->tac, 0); + DevCheck(new_instance->mcc == m3ap_register_MCE->mcc, new_instance->mcc, m3ap_register_MCE->mcc, 0); + DevCheck(new_instance->mnc == m3ap_register_MCE->mnc, new_instance->mnc, m3ap_register_MCE->mnc, 0); + M3AP_WARN("MCE[%d] already registered\n", instance); + } else { + new_instance = calloc(1, sizeof(m3ap_MCE_instance_t)); + DevAssert(new_instance != NULL); + RB_INIT(&new_instance->m3ap_mce_head); + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->MCE_name = m3ap_register_MCE->MCE_name; + new_instance->MCE_id = m3ap_register_MCE->MCE_id; + new_instance->cell_type = m3ap_register_MCE->cell_type; + new_instance->tac = m3ap_register_MCE->tac; + new_instance->mcc = m3ap_register_MCE->mcc; + new_instance->mnc = m3ap_register_MCE->mnc; + new_instance->mnc_digit_length = m3ap_register_MCE->mnc_digit_length; + new_instance->num_cc = m3ap_register_MCE->num_cc; + + m3ap_id_manager_init(&new_instance->id_manager); + m3ap_timers_init(&new_instance->timers, + m3ap_register_MCE->t_reloc_prep, + m3ap_register_MCE->tm3_reloc_overall); + + for (int i = 0; i< m3ap_register_MCE->num_cc; i++) { + new_instance->eutra_band[i] = m3ap_register_MCE->eutra_band[i]; + new_instance->downlink_frequency[i] = m3ap_register_MCE->downlink_frequency[i]; + new_instance->uplink_frequency_offset[i] = m3ap_register_MCE->uplink_frequency_offset[i]; + new_instance->Nid_cell[i] = m3ap_register_MCE->Nid_cell[i]; + new_instance->N_RB_DL[i] = m3ap_register_MCE->N_RB_DL[i]; + new_instance->frame_type[i] = m3ap_register_MCE->frame_type[i]; + new_instance->fdd_earfcn_DL[i] = m3ap_register_MCE->fdd_earfcn_DL[i]; + new_instance->fdd_earfcn_UL[i] = m3ap_register_MCE->fdd_earfcn_UL[i]; + } + + DevCheck(m3ap_register_MCE->nb_m3 <= M3AP_MAX_NB_MCE_IP_ADDRESS, + M3AP_MAX_NB_MCE_IP_ADDRESS, m3ap_register_MCE->nb_m3, 0); + memcpy(new_instance->target_mme_m3_ip_address, + m3ap_register_MCE->target_mme_m3_ip_address, + m3ap_register_MCE->nb_m3 * sizeof(net_ip_address_t)); + new_instance->nb_m3 = m3ap_register_MCE->nb_m3; + new_instance->mme_m3_ip_address = m3ap_register_MCE->mme_m3_ip_address; + new_instance->sctp_in_streams = m3ap_register_MCE->sctp_in_streams; + new_instance->sctp_out_streams = m3ap_register_MCE->sctp_out_streams; + new_instance->mce_port_for_M3C = m3ap_register_MCE->mme_port_for_M3C; + /* Add the new instance to the list of MCE (meaningfull in virtual mode) */ + m3ap_MCE_insert_new_instance(new_instance); + M3AP_INFO("Registered new MCE[%d] and %s MCE id %u\n", + instance, + m3ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home", + m3ap_register_MCE->MCE_id); + + + printf("ipv4_address %s\n",m3ap_register_MCE->mme_m3_ip_address.ipv4_address); + /* initiate the SCTP listener */ + if (m3ap_MCE_init_sctp(new_instance,&m3ap_register_MCE->mme_m3_ip_address,m3ap_register_MCE->mme_port_for_M3C) < 0 ) { + M3AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n"); + return; + } + + M3AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n", + instance, m3ap_register_MCE->MCE_id); + } +} + +static +void m3ap_MCE_handle_sctp_init_msg_multi_cnf( + instance_t instance_id, + sctp_init_msg_multi_cnf_t *m) { + m3ap_MCE_instance_t *instance; + int index; + DevAssert(m != NULL); + instance = m3ap_MCE_get_instance(instance_id); + DevAssert(instance != NULL); + instance->multi_sd = m->multi_sd; + + /* Exit if CNF message reports failure. + * Failure means multi_sd < 0. + */ + if (instance->multi_sd < 0) { + M3AP_ERROR("Error: be sure to properly configure M3 in your configuration file.\n"); + DevAssert(instance->multi_sd >= 0); + } + + /* Trying to connect to the provided list of MCE ip address */ + + for (index = 0; index < instance->nb_m3; index++) { + M3AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n", + instance_id, instance->MCE_id); + m3ap_MCE_register_MCE(instance, + &instance->target_mme_m3_ip_address[index], + &instance->mme_m3_ip_address, + instance->sctp_in_streams, + instance->sctp_out_streams, + instance->mce_port_for_M3C, + instance->multi_sd); + } +} + +//static +//void m3ap_eNB_handle_handover_req(instance_t instance, +// m3ap_handover_req_t *m3ap_handover_req) +//{ +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *target; +// m3ap_id_manager *id_manager; +// int ue_id; +// +// int target_pci = m3ap_handover_req->target_physCellId; +// +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m3ap_is_eNB_pci_in_list(target_pci); +// DevAssert(target != NULL); +// +// /* allocate m3ap ID */ +// id_manager = &instance_p->id_manager; +// ue_id = m3ap_allocate_new_id(id_manager); +// if (ue_id == -1) { +// M3AP_ERROR("could not allocate a new M3AP UE ID\n"); +// /* TODO: cancel handover: send (to be defined) message to RRC */ +// exit(1); +// } +// /* id_source is ue_id, id_target is unknown yet */ +// m3ap_set_ids(id_manager, ue_id, m3ap_handover_req->rnti, ue_id, -1); +// m3ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE); +// m3ap_set_reloc_prep_timer(id_manager, ue_id, +// m3ap_timer_get_tti(&instance_p->timers)); +// m3ap_id_set_target(id_manager, ue_id, target); +// +// m3ap_eNB_generate_m3_handover_request(instance_p, target, m3ap_handover_req, ue_id); +//} + +//static +//void m3ap_eNB_handle_handover_req_ack(instance_t instance, +// m3ap_handover_req_ack_t *m3ap_handover_req_ack) +//{ +// /* TODO: remove this hack (the goal is to find the correct +// * eNodeB structure for the other end) - we need a proper way for RRC +// * and M3AP to identify eNodeBs +// * RRC knows about mod_id and M3AP knows about eNB_id (eNB_ID in +// * the configuration file) +// * as far as I understand.. CROUX +// */ +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *target; +// int source_assoc_id = m3ap_handover_req_ack->source_assoc_id; +// int ue_id; +// int id_source; +// int id_target; +// +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m3ap_get_eNB(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// /* rnti is a new information, save it */ +// ue_id = m3ap_handover_req_ack->m3_id_target; +// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// m3ap_set_ids(&instance_p->id_manager, ue_id, m3ap_handover_req_ack->rnti, id_source, id_target); +// +// m3ap_eNB_generate_m3_handover_request_ack(instance_p, target, m3ap_handover_req_ack); +//} +// +//static +//void m3ap_eNB_ue_context_release(instance_t instance, +// m3ap_ue_context_release_t *m3ap_ue_context_release) +//{ +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *target; +// int source_assoc_id = m3ap_ue_context_release->source_assoc_id; +// int ue_id; +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m3ap_get_eNB(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// m3ap_eNB_generate_m3_ue_context_release(instance_p, target, m3ap_ue_context_release); +// +// /* free the M3AP UE ID */ +// ue_id = m3ap_find_id_from_rnti(&instance_p->id_manager, m3ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M3AP_ERROR("could not find UE %x\n", m3ap_ue_context_release->rnti); +// exit(1); +// } +// m3ap_release_id(&instance_p->id_manager, ue_id); +//} + +uint8_t m3ap_m3setup[] = { + 0x00, 0x07, 0x00, 0x23, 0x00, 0x00, 0x03, 0x00, + 0x12, 0x00, 0x07, 0x40, 0x55, 0xf5, 0x01, 0x00, + 0x25, 0x00, 0x00, 0x13, 0x40, 0x0a, 0x03, 0x80, + 0x4d, 0x33, 0x2d, 0x65, 0x4e, 0x42, 0x33, 0x37, + 0x00, 0x14, 0x00, 0x03, 0x01, 0x00, 0x01 +}; + +uint8_t m3ap_start[] = { + 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x07, 0x00, 0x55, 0xf5, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x04, 0x00, 0x0d, 0x60, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x01, + 0x7a, 0x00, 0x05, 0x00, 0x03, 0x07, 0x08, 0x00, + 0x00, 0x06, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, + 0x0e, 0x00, 0xe8, 0x0a, 0x0a, 0x0a, 0x00, 0x0a, + 0xc8, 0x0a, 0xfe, 0x00, 0x00, 0x00, 0x01 +}; + + +void *m3ap_MCE_task(void *arg) { + MessageDef *received_msg = NULL; + int result; + M3AP_DEBUG("Starting M3AP MCE layer\n"); + m3ap_MCE_prepare_internal_data(); + itti_mark_task_ready(TASK_M3AP_MCE); + + while (1) { + itti_receive_msg(TASK_M3AP_MCE, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case MESSAGE_TEST: +// LOG_W(M3AP,"MCE Received Test Message ... TODO\n"); +// //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP, MESSAGE_TEST); +// //itti_send_msg_to_task(TASK_M2AP_ENB, 1/*ctxt_pP->module_id*/, message_p); +// +// asn_dec_rval_t dec_ret; +// +// +// uint8_t *buffer; +// uint32_t len; +// M3AP_M3AP_PDU_t pdu; +// memset(&pdu, 0, sizeof(pdu)); +// +// buffer = &m3ap_m3setup[0]; +// //buffer = &m3ap_start[0]; +// len=8*4+7; +// //len=8*9+7; +// +// //if (m3ap_decode_pdu(&pdu, buffer, len) < 0) { +// // LOG_E(M3AP, "Failed to decode PDU\n"); +// //re//turn -1; +// //} +// M3AP_M3AP_PDU_t *pdu2 = &pdu; +// dec_ret = aper_decode(NULL, +// &asn_DEF_M3AP_M3AP_PDU, +// (void **)&pdu2, +// buffer, +// len, +// 0, +// 0); +// +// LOG_W(M3AP,"Trying to print %d\n",(dec_ret.code == RC_OK)); +// xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, &pdu); +// LOG_W(M3AP,"Trying to print out \n"); + + break; + case TERMINATE_MESSAGE: + M3AP_WARN(" *** Exiting M3AP thread\n"); + itti_exit_task(); + break; + + case M3AP_SUBFRAME_PROCESS: + m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + break; + + case M3AP_REGISTER_MCE_REQ: + LOG_I(M3AP,"MCE Received M3AP_REGISTER_MCE_REQ Message\n"); + + m3ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_REGISTER_MCE_REQ(received_msg)); + break; + + case M3AP_MBMS_SESSION_START_RESP: + LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_START_RESP Message\n"); + MCE_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_MBMS_SESSION_START_RESP(received_msg)); + + break; + + case M3AP_MBMS_SESSION_STOP_RESP: + LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_STOP_RESP Message\n"); + MCE_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_MBMS_SESSION_START_RESP(received_msg)); + + break; + + case M3AP_MBMS_SESSION_UPDATE_RESP: + LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_UPDATE_RESP Message\n"); + //MCE_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + //&M3AP_MBMS_SESSION_START_RESP(received_msg)); + + break; + + +// case M3AP_HANDOVER_REQ: +// m3ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_HANDOVER_REQ(received_msg)); +// break; +// +// case M3AP_HANDOVER_REQ_ACK: +// m3ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_HANDOVER_REQ_ACK(received_msg)); +// break; +// +// case M3AP_UE_CONTEXT_RELEASE: +// m3ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_UE_CONTEXT_RELEASE(received_msg)); +// break; +// + case SCTP_INIT_MSG_MULTI_CNF: + LOG_D(M3AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n"); + + m3ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_init_msg_multi_cnf); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n"); + + m3ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_NEW_ASSOCIATION_IND: + LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n"); + + m3ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_DATA_IND: + LOG_D(M3AP,"MCE Received SCTP_DATA_IND Message\n"); + + m3ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + default: + M3AP_ERROR("Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; + } + + return NULL; +} + +#include "common/config/config_userapi.h" + +int is_m3ap_MCE_enabled(void) +{ + static volatile int config_loaded = 0; + static volatile int enabled = 0; + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if (pthread_mutex_lock(&mutex)) goto mutex_error; + + if (config_loaded) { + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + return enabled; + } + + char *enable_m3 = NULL; + paramdef_t p[] = { + { "enable_mce_m3", "yes/no", 0, strptr:&enable_m3, defstrval:"", TYPE_STRING, 0 } + }; + + /* TODO: do it per module - we check only first MCE */ + config_get(p, sizeof(p)/sizeof(paramdef_t), "MCEs.[0]"); + if (enable_m3 != NULL && strcmp(enable_m3, "yes") == 0) + enabled = 1; + + config_loaded = 1; + + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + + return enabled; + +mutex_error: + LOG_E(M3AP, "mutex error\n"); + exit(1); +} diff --git a/openair3/M3AP/m3ap_MCE.h b/openair3/M3AP/m3ap_MCE.h new file mode 100644 index 0000000000..3a617776e3 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB.h + * \brief m3ap tasks for eNB + * \author Konstantinos Alexandris , Cedric Roux , Navid Nikaein + * \date 2018 + * \version 1.0 + */ + +#include +#include + +/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +#ifndef M3AP_MCE_H_ +#define M3AP_MCE_H_ + +#include "m3ap_MCE_defs.h" + + +int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t mce_port_for_M3C); + +void *m3ap_MCE_task(void *arg); + +int is_m3ap_MCE_enabled(void); + +#endif /* M3AP_H_ */ + +/** + * @} + */ diff --git a/openair3/M3AP/m3ap_MCE_defs.h b/openair3/M3AP/m3ap_MCE_defs.h new file mode 100644 index 0000000000..18ad70a408 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_defs.h @@ -0,0 +1,210 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE_defs.h + * \brief m3ap struct definitions for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#include "m3ap_ids.h" //looks X2AP specific for HO +#include "m3ap_timers.h" + +#ifndef M3AP_MCE_DEFS_H_ +#define M3AP_MCE_DEFS_H_ + +#define M3AP_MCE_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + M3AP_MCE_STATE_DISCONNECTED = 0x0, + + /* State waiting for m2 Setup response message if the target MCE accepts or + * M3 Setup failure if rejects the MCE. + */ + M3AP_MCE_STATE_WAITING = 0x1, + + /* The MCE is successfully connected to another MCE. */ + M3AP_MCE_STATE_CONNECTED = 0x2, + + /* M3AP is ready, and the MCE is successfully connected to another MCE. */ + M3AP_MCE_STATE_READY = 0x3, + + M3AP_MCE_STATE_OVERLOAD = 0x4, + + M3AP_MCE_STATE_RESETTING = 0x5, + + /* Max number of states available */ + M3AP_MCE_STATE_MAX, +} m3ap_MCE_state_t; + +/* Served PLMN identity element */ +/*struct plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + STAILQ_ENTRY(plmn_identity_s) next; +};*/ + +/* Served group id element */ +/*struct served_group_id_s { + uint16_t mce_group_id; + STAILQ_ENTRY(served_group_id_s) next; +};*/ + +/* Served enn code for a particular MCE */ +/*struct mce_code_s { + uint8_t mce_code; + STAILQ_ENTRY(mce_code_s) next; +};*/ + +struct m3ap_MCE_instance_s; + +/* This structure describes association of a MCE to another MCE */ +typedef struct m3ap_MCE_data_s { + /* MCE descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(m3ap_MCE_data_s) entry; + + /* This is the optional name provided by the MME */ + char *MCE_name; + + /* target MCE ID */ + uint32_t MCE_id; + + /* Current MCE load information (if any). */ + //m3ap_load_state_t overload_state; + + /* Current MCE->MCE M3AP association state */ + m3ap_MCE_state_t state; + + /* Next usable stream for UE signalling */ + int32_t nextstream; + + /* Number of input/ouput streams */ + uint16_t in_streams; + uint16_t out_streams; + + /* Connexion id used between SCTP/M3AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Nid cells */ + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + + /* Only meaningfull in virtual mode */ + struct m3ap_MCE_instance_s *m3ap_MCE_instance; +} m3ap_MCE_data_t; + +typedef struct m3ap_MCE_instance_s { + /* used in simulation to store multiple MCE instances*/ + STAILQ_ENTRY(m3ap_MCE_instance_s) m3ap_MCE_entries; + + /* Number of target MCEs requested by MCE (tree size) */ + uint32_t m3_target_mme_nb; + /* Number of target MCEs for which association is pending */ + uint32_t m3_target_mme_pending_nb; + /* Number of target MCE successfully associated to MCE */ + uint32_t m3_target_mme_associated_nb; + /* Tree of M3AP MCE associations ordered by association ID */ + RB_HEAD(m3ap_mce_map, m3ap_MCE_data_s) m3ap_mce_head; + + /* Tree of UE ordered by MCE_ue_m3ap_id's */ + // RB_HEAD(m3ap_ue_map, m3ap_MCE_ue_context_s) m3ap_ue_head; + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + /* Displayable name of MCE */ + char *MCE_name; + + /* Unique MCE_id to identify the MCE within EPC. + * In our case the MCE is a macro MCE so the id will be 20 bits long. + * For Home MCE id, this field should be 28 bits long. + */ + uint32_t MCE_id; + /* The type of the cell */ + cell_type_t cell_type; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* CC params */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MCE_IP_ADDRESS]; + uint8_t nb_m3; + net_ip_address_t mme_m3_ip_address; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + uint32_t mce_port_for_M3C; + int multi_sd; + + m3ap_id_manager id_manager; + m3ap_timers_t timers; +} m3ap_MCE_instance_t; + +typedef struct { + /* List of served MCEs + * Only used for virtual mode + */ + STAILQ_HEAD(m3ap_MCE_instances_head_s, m3ap_MCE_instance_s) m3ap_MCE_instances_head; + /* Nb of registered MCEs */ + uint8_t nb_registered_MCEs; + + /* Generate a unique connexion id used between M3AP and SCTP */ + uint16_t global_cnx_id; +} m3ap_MCE_internal_data_t; + +int m3ap_MCE_compare_assoc_id(struct m3ap_MCE_data_s *p1, struct m3ap_MCE_data_s *p2); + +/* Generate the tree management functions */ +struct m3ap_MCE_map; +struct m3ap_MCE_data_s; +RB_PROTOTYPE(m3ap_MCE_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id); + + +#endif /* M3AP_MCE_DEFS_H_ */ diff --git a/openair3/M3AP/m3ap_MCE_generate_messages.h b/openair3/M3AP/m3ap_MCE_generate_messages.h new file mode 100644 index 0000000000..0884e8216e --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_generate_messages.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_generate_messages.h + * \brief m2ap procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_ENB_GENERATE_MESSAGES_H_ +#define M2AP_ENB_GENERATE_MESSAGES_H_ + +#include "m2ap_eNB_defs.h" +#include "m2ap_common.h" + +int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p, + m2ap_eNB_data_t *m2ap_eNB_data_p); + +int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p); + +/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance, + uint32_t assoc_id, + M2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait);*/ + +int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value); + +//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id); +// +//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack); +// +//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_ue_context_release_t *m2ap_ue_context_release); +// +//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause); + +#endif /* M2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair3/M3AP/m3ap_MCE_generate_messsages.c b/openair3/M3AP/m3ap_MCE_generate_messsages.c new file mode 100644 index 0000000000..8d8c7f3853 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_generate_messsages.c @@ -0,0 +1,808 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_eNB_generate_messages.c + * \brief m2ap procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +//#include "M2AP_LastVisitedCell-Item.h" + +#include "m2ap_common.h" +#include "m2ap_eNB.h" +#include "m2ap_eNB_generate_messages.h" +#include "m2ap_encoder.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +#include "m2ap_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +int m2ap_eNB_generate_m2_setup_request( + m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p) +{ + module_id_t enb_mod_idP=0; + module_id_t du_mod_idP=0; + + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupRequest_t *out; + M2AP_M2SetupRequest_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + int j = 0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest; + + /* mandatory */ + /* c1. GlobalENB_ID (integer value) */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID; + //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP); + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie->value.choice.GlobalENB_ID.pLMN_Identity); + ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID; + MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); + M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], + ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ///* mandatory */ + ///* c2. GNB_eNB_ID (integrer value) */ + //ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_gNB_eNB_ID; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID; + //asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id); + //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. ENBname */ + if (m2ap_eNB_data_p->eNB_name != NULL) { + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENBname; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENBname; + //OCTET_STRING_fromBuf(&ie->value.choice.ENB_Name, m2ap_eNB_data_p->eNB_name, + //strlen(m2ap_eNB_data_p->eNB_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c4. serverd cells list */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List; + + int num_mbms_available = 1;//m2ap_du_data->num_mbms_available; + LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available); + + for (i=0; + iid = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item; + mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject; + mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item; + + M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item; + mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item; + { + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &mbms_configuration_data_item->eCGI.pLMN_Identity); + MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, + &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier); + M2AP_MBMS_Service_Area_t * mbms_service_area; + mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t)); + ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area); + + + } + + + //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item; + //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t)); + + //M2AP_ECGI_t eCGI; + //M2AP_PLMN_Identity_t pLMN_Identity; + //M2AP_EUTRANCellIdentifier_t eUTRANcellIdentifier + //M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea; + //M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList; + + + ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + LOG_W(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id); + /* encode */ + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode M2 setup request\n"); + return -1; + } + + + LOG_W(M2AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M2AP_eNB, + // MSC_M2AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m2ap_eNB_data_p->ENBname); + + m2ap_eNB_itti_send_sctp_data_req(instance_p, m2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return 0; + + +} + +//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_M2SetupResponse_t *out; +// M2AP_M2SetupResponse_Ies_t *ie; +// //M2AP_PLMN_Identity_t *plmn; +// //ServedCells__Member *servedCellMember; +// //M2AP_GU_Group_ID_t *gu; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// /* Prepare the M2AP message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; +// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse; +// out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse; +// +// /* mandatory */ +// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalENB_ID; +// //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// // &ie->value.choice.GlobalENB_ID.pLMN_Identity); +// //ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID; +// //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, +// // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); +// //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, +// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], +// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], +// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_ServedCells; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells; +// //{ +// // for (int i = 0; inum_cc; i++){ +// // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); +// // { +// // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; +// +// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); +// // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, +// // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); +// +// // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); +// // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t)); +// // { +// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); +// // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); +// // } +// +// // if (instance_p->frame_type[i] == FDD) { +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; +// // switch (instance_p->N_RB_DL[i]) { +// // case 6: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; +// // break; +// // case 15: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; +// // break; +// // case 25: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; +// // break; +// // case 50: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; +// // break; +// // case 75: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; +// // break; +// // case 100: +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; +// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; +// // break; +// // default: +// // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); +// // break; +// // } +// // } +// // else { +// // AssertFatal(0,"M2Setupresponse not supported for TDD!"); +// // } +// // } +// // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); +// // } +// //} +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList; +// //ie->criticality = M2AP_Criticality_reject; +// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList; +// //{ +// // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t)); +// // { +// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// // &gu->pLMN_Identity); +// // //@TODO: consider to update this value +// // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); +// // } +// // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); +// //} +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode M2 setup response\n"); +// return -1; +// } +// +// m2ap_eNB_data_p->state = M2AP_ENB_STATE_READY; +// +// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0); +// +// return ret; +//} + +//int m2ap_MCE_generate_m2_setup_failure(instance_t instance, +// uint32_t assoc_id, +// M2AP_Cause_PR cause_type, +// long cause_value, +// long time_to_wait) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_M2SetupFailure_t *out; +// M2AP_M2SetupFailure_Ies_t *ie; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// /* Prepare the M2AP message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; +// pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; +// pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure; +// out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure; +// +// /* mandatory */ +// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_Cause; +// //ie->criticality = M2AP_Criticality_ignore; +// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause; +// +// //m2ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional: consider to handle this later */ +// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); +// //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait; +// //ie->criticality = M2AP_Criticality_ignore; +// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait; +// +// //if (time_to_wait > -1) { +// // ie->value.choice.TimeToWait = time_to_wait; +// //} +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode M2 setup failure\n"); +// return -1; +// } +// +// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, +// // MSC_M2AP_TARGET_ENB, NULL, 0, +// // "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", +// // assoc_id, cause_type, cause_value); +// +// m2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); +// +// return ret; +//} + +int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value) +{ + + DevAssert (cause_p != NULL); + cause_p->present = cause_type; + + switch (cause_type) { + case M2AP_Cause_PR_radioNetwork: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_transport: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_protocol: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_misc: + cause_p->choice.misc = cause_value; + break; + + default: + return -1; + } + + return 0; +} + +//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequest_t *out; +// M2AP_HandoverRequest_IEs_t *ie; +// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; +// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; +// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause; +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.ECGI.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(m2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); +// //@TODO: consider to update these values +// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); +// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; +// //@TODO: consider to update this value +// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id; +// +// KENB_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); +// +// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc; +// } +// else { +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; +// } +// +// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); +// +// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); +// +// //@TODO: update with proper UEAMPR +// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); +// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t)); +// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; +// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; +// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; +// { +// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8); +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = +// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, +// m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); +// } +// } +// +// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; +// //@TODO: consider to update this value +// { +// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t)); +// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); +// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small; +// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover request\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequestAcknowledge_t *out; +// M2AP_HandoverRequestAcknowledge_IEs_t *ie; +// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; +// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// ue_id = m2ap_handover_req_ack->m2_id_target; +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; +// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; +// +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t)); +// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; +// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; +// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; +// { +// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); +// } +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer; +// +// OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover response\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_UEContextRelease_t *out; +// M2AP_UEContextRelease_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti); +// exit(1); +// } +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP ue context relase message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease; +// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 UE Context Release\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverCancel_t *out; +// M2AP_HandoverCancel_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_eNB_data_p != NULL); +// +// ue_id = m2_ue_id; +// id_source = ue_id; +// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id); +// +// /* Prepare the M2AP handover cancel message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// if (id_target != -1) { +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause; +// switch (cause) { +// case M2AP_T_RELOC_PREP_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_trelocprep_expiry; +// break; +// case M2AP_TX2_RELOC_OVERALL_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_tx2relocoverall_expiry; +// break; +// default: +// /* we can't come here */ +// M2AP_ERROR("unhandled cancel cause\n"); +// exit(1); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 Handover Cancel\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id); +// +// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} diff --git a/openair3/M3AP/m3ap_MCE_handler.c b/openair3/M3AP/m3ap_MCE_handler.c new file mode 100644 index 0000000000..e733af28db --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_handler.c @@ -0,0 +1,118 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_handler.c + * \brief m3ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m3ap_common.h" +#include "m3ap_MCE_defs.h" +#include "m3ap_handler.h" +#include "m3ap_decoder.h" +#include "m3ap_ids.h" + +//#include "m3ap_MCE_management_procedures.h" +#include "m3ap_MCE_generate_messages.h" + +//#include "m3ap_MME_interface_management.h" +#include "m3ap_MCE_interface_management.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +/* Handlers matrix. Only eNB related procedure present here */ +m3ap_MCE_message_decoded_callback m3ap_MCE_messages_callback[][3] = { + { MCE_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart */ + { MCE_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */ + { 0, 0, 0 }, /* Error Indication */ + { 0, 0, 0 }, /* Reset */ + { 0, 0, 0 }, /* ??? */ + { MCE_handle_MBMS_SESSION_UPDATE_REQUEST, 0, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { 0, MCE_handle_M3_SETUP_RESPONSE, 0 } /* M3 Setup */ +}; + +static char *m3ap_direction2String(int m3ap_dir) { +static char *m3ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m3ap_direction_String[m3ap_dir]); +} + + +int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + M3AP_M3AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + if (m3ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(M3AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_MCE_messages_callback) / (3 * sizeof( + m3ap_message_decoded_callback)) + || (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m3ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(M3AP, "Calling handler with instance %d\n",instance); + ret = (*m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return ret; +} + + diff --git a/openair3/M3AP/m3ap_MCE_handler.h b/openair3/M3AP/m3ap_MCE_handler.h new file mode 100644 index 0000000000..ce4997e80d --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_handler.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_handler.h + * \brief m2ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_MCE_HANDLERS_H_ +#define M2AP_MCE_HANDLERS_H_ + +#include "m2ap_MCE_defs.h" + +//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + //const uint8_t * const data, const uint32_t data_length); + +int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + + +#endif /* M2AP_MCE_HANDLERS_H_ */ diff --git a/openair3/M3AP/m3ap_MCE_interface_management.c b/openair3/M3AP/m3ap_MCE_interface_management.c new file mode 100644 index 0000000000..2694846526 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_interface_management.c @@ -0,0 +1,756 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE_interface_management.c + * \brief m3ap interface management for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "intertask_interface.h" + +#include "m3ap_common.h" +#include "m3ap_MCE.h" +//#include "m3ap_MCE_generate_messages.h" +#include "m3ap_encoder.h" +#include "m3ap_decoder.h" +#include "m3ap_ids.h" + +#include "m3ap_MCE_interface_management.h" + + +#include "m3ap_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + + +//#include "m3ap_common.h" +//#include "m3ap_encoder.h" +//#include "m3ap_decoder.h" +//#include "m3ap_itti_messaging.h" +//#include "m3ap_MCE_interface_management.h" +//#include "assertions.h" + +extern m3ap_setup_req_t * m3ap_mce_data_g; + + +int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ +// LOG_W(M3AP, "MCE_handle_MBMS_SESSION_START_REQUEST assoc_id %d\n",assoc_id); +// + MessageDef *message_p; +// M3AP_SessionStartRequest_t *container; +// M3AP_SessionStartRequest_Ies_t *ie; +// int i = 0; +// +// DevAssert(pdu != NULL); +// +// container = &pdu->choice.initiatingMessage.value.choice.SessionStartRequest; + + message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_START_REQ); + +// +// /* M3 Setup Request == Non UE-related procedure -> stream 0 */ +// if (stream != 0) { +// LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", +// assoc_id, stream); +// } +// + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + +// if(1){ +// MCE_send_MBMS_SESSION_START_RESPONSE(instance,assoc_id); +// }else +// MCE_send_MBMS_SESSION_START_FAILURE(instance,assoc_id); + return 0; + +} + +int MCE_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp){ + //AssertFatal(1==0,"Not implemented yet\n"); + +// module_id_t mce_mod_idP; +// module_id_t enb_mod_idP; +// +// // This should be fixed +// enb_mod_idP = (module_id_t)0; +// mce_mod_idP = (module_id_t)0; +// + M3AP_M3AP_PDU_t pdu; + M3AP_MBMSSessionStartResponse_t *out; + M3AP_MBMSSessionStartResponse_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_mBMSsessionStart; + pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_MBMSSessionStartResponse; + out = &pdu.choice.successfulOutcome.value.choice.MBMSSessionStartResponse; + + + /* mandatory */ + /* c1. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStartResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartResponse_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartResponse_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MME_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStartResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartResponse_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartResponse_IEs__value_PR_MME_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M3AP, "Failed to encode M3 SessionStart Response\n"); + return -1; + } +// +// +// LOG_W(M3AP,"pdu.present %d\n",pdu.present); +// // MSC_LOG_TX_MESSAGE( +// // MSC_M3AP_MCE, +// // MSC_M3AP_MCE, +// // (const char *)buffer, +// // len, +// // MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s", +// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +// // m3ap_MCE_data_p->MCEname); +// + m3ap_MCE_itti_send_sctp_data_req(instance, m3ap_mce_data_g->assoc_id, buffer, len, 0); + return 0; +} + + +int MCE_send_MBMS_SESSION_START_FAILURE(instance_t instance, m3ap_session_start_failure_t * m3ap_session_start_failure){ +// module_id_t enb_mod_idP; +// module_id_t mce_mod_idP; +// +// // This should be fixed +// enb_mod_idP = (module_id_t)0; +// mce_mod_idP = (module_id_t)0; +// +// M3AP_M3AP_PDU_t pdu; +// M3AP_SessionStartFailure_t *out; +// M3AP_SessionStartFailure_Ies_t *ie; +// +// uint8_t *buffer; +// uint32_t len; +// +// /* Create */ +// /* 0. Message Type */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome; +// //pdu.choice.unsuccessfulOutcome = (M3AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M3AP_UnsuccessfulOutcome_t)); +// pdu.choice.unsuccessfulOutcome.procedureCode = M3AP_ProcedureCode_id_sessionStart; +// pdu.choice.unsuccessfulOutcome.criticality = M3AP_Criticality_reject; +// pdu.choice.unsuccessfulOutcome.value.present = M3AP_UnsuccessfulOutcome__value_PR_SessionStartFailure; +// out = &pdu.choice.unsuccessfulOutcome.value.choice.SessionStartFailure; +// +// /* mandatory */ +// /* c1. Transaction ID (integer value)*/ +// // ie = (M3AP_M3SetupFailure_Ies_t *)calloc(1, sizeof(M3AP_M3SetupFailure_Ies_t)); +// // ie->id = M3AP_ProtocolIE_ID_id_GlobalMCE_ID; +// // ie->criticality = M3AP_Criticality_reject; +// // ie->value.present = M3AP_M3SetupFailure_Ies__value_PR_GlobalMCE_ID; +// // ie->value.choice.GlobalMCE_ID = M3AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP); +// // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// /* c2. Cause */ +// ie = (M3AP_M3SetupFailure_Ies_t *)calloc(1, sizeof(M3AP_SessionStartFailure_Ies_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_SessionStartFailure_Ies__value_PR_Cause; +// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M3AP_CauseRadioNetwork_unspecified; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// +// /* encode */ +// if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// LOG_E(M3AP, "Failed to encode M3 setup request\n"); +// return -1; +// } +// +// //mce_m3ap_itti_send_sctp_data_req(instance, m3ap_mce_data_from_enb->assoc_id, buffer, len, 0); +// m3ap_MCE_itti_send_sctp_data_req(instance,assoc_id,buffer,len,0); +// + + return 0; +} + +int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M3AP, "MCE_handle_MBMS_SESSION_STOP_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M3AP_MBMSSessionStopRequest_t *container; + //M3AP_MBMSSessionStopRequest_IEs_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.MBMSSessionStopRequest; + + /* M3 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + //if(1){ + //MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id); + //}else + //MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_STOP_REQ); + +// +// /* M3 Setup Request == Non UE-related procedure -> stream 0 */ +// if (stream != 0) { +// LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", +// assoc_id, stream); +// } +// + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + + return 0; + +} +int MCE_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp){ +// module_id_t mce_mod_idP; +// module_id_t enb_mod_idP; +// +// // This should be fixed +// enb_mod_idP = (module_id_t)0; +// mce_mod_idP = (module_id_t)0; +// + M3AP_M3AP_PDU_t pdu; + M3AP_MBMSSessionStopResponse_t *out; + M3AP_MBMSSessionStopResponse_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_mBMSsessionStop; + pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_MBMSSessionStopResponse; + out = &pdu.choice.successfulOutcome.value.choice.MBMSSessionStopResponse; + + + /* mandatory */ + /* c1. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStopResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStopResponse_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStopResponse_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStopResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStopResponse_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStopResponse_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M3AP, "Failed to encode M3 SessionStop Response\n"); + return -1; + } + + + LOG_D(M3AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M3AP_MCE, + // MSC_M3AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m3ap_MCE_data_p->MCEname); + + m3ap_MCE_itti_send_sctp_data_req(instance, m3ap_mce_data_g->assoc_id, buffer, len, 0); + return 0; +} + +/* + * Session Update + */ +int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) +{ + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M3AP, "MCE_handle_MBMS_SESSION_UPDATE_REQUEST assoc_id %d\n",assoc_id); + + MessageDef *message_p; + //M3AP_MBMSSessionUpdateRequest_t *container; + //M3AP_MBMSSessionUpdateRequest_IEs_t *ie; + //int i = 0; + + DevAssert(pdu != NULL); + + //container = &pdu->choice.initiatingMessage.value.choice.MBMSSessionUpdateRequest; + + /* M3 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_D(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + assoc_id, stream); + } + + //if(1){ + //MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id); + //}else + //MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_UPDATE_REQ); + +// +// /* M3 Setup Request == Non UE-related procedure -> stream 0 */ +// if (stream != 0) { +// LOG_W(M3AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", +// assoc_id, stream); +// } +// + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + + + + + return 0; +} + +int MCE_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m3ap_mbms_session_update_resp_t * m3ap_mbms_session_update_resp){ + M3AP_M3AP_PDU_t pdu; + M3AP_MBMSSessionUpdateResponse_t *out; + M3AP_MBMSSessionUpdateResponse_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_mBMSsessionUpdate; + pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_MBMSSessionUpdateResponse; + out = &pdu.choice.successfulOutcome.value.choice.MBMSSessionUpdateResponse; + + + /* mandatory */ + /* c1. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionUpdateResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateResponse_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateResponse_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionUpdateResponse_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateResponse_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateResponse_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M3AP, "Failed to encode M3 SessionUpdate Response\n"); + return -1; + } + + + LOG_D(M3AP,"pdu.present %d\n",pdu.present); + // MSC_LOG_TX_MESSAGE( + // MSC_M3AP_MCE, + // MSC_M3AP_MCE, + // (const char *)buffer, + // len, + // MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // m3ap_MCE_data_p->MCEname); + + m3ap_MCE_itti_send_sctp_data_req(instance, m3ap_mce_data_g->assoc_id, buffer, len, 0); + return 0; +} +int MCE_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m3ap_mbms_session_update_failure_t * m3ap_mbms_session_update_failure){ + return 0; +} + +/* + M3 Setup +*/ + +//uint8_t m3ap_m3setup_message[] = {0x00,0x07,0x00,0x23,0x00,0x00,0x03,0x00,0x12,0x00,0x07,0x40,0x55,0xf5,0x01,0x00,0x25,0x00,0x00,0x13,0x40,0x0a,0x03,0x80,0x4d,0x33,0x2d,0x65,0x4e,0x42,0x33,0x37,0x00,0x14,0x00,0x03,0x01,0x00,0x01}; +uint8_t m3ap_m3setup_message[] = { + 0x00, 0x07, 0x00, 0x23, 0x00, 0x00, 0x03, 0x00, + 0x12, 0x00, 0x07, 0x40, 0x55, 0xf5, 0x01, 0x00, + 0x25, 0x00, 0x00, 0x13, 0x40, 0x0a, 0x03, 0x80, + 0x4d, 0x33, 0x2d, 0x65, 0x4e, 0x42, 0x33, 0x37, + 0x00, 0x14, 0x00, 0x03, 0x01, 0x00, 0x01 +}; + + +//uint8_t m3ap_start_message[] = { +// 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x07, 0x00, +// 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, +// 0x07, 0x00, 0x55, 0xf5, 0x01, 0x00, 0x00, 0x01, +// 0x00, 0x04, 0x00, 0x0d, 0x60, 0x01, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x01, +// 0x7a, 0x00, 0x05, 0x00, 0x03, 0x07, 0x08, 0x00, +// 0x00, 0x06, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, +// 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, +// 0x0e, 0x00, 0xe8, 0x0a, 0x0a, 0x0a, 0x00, 0x0a, +// 0xc8, 0x0a, 0xfe, 0x00, 0x00, 0x00, 0x01 +//}; +// +// SETUP REQUEST +int MCE_send_M3_SETUP_REQUEST(m3ap_MCE_instance_t *instance_p, m3ap_MCE_data_t *m3ap_MCE_data_p) { +// module_id_t enb_mod_idP=0; +// module_id_t du_mod_idP=0; +// + M3AP_M3AP_PDU_t pdu; + M3AP_M3SetupRequest_t *out; + M3AP_M3SetupRequestIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + //int j = 0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M3AP_InitiatingMessage_t *)calloc(1, sizeof(M3AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_m3Setup; + pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_M3SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.M3SetupRequest; + + /* mandatory */ + /* c1. GlobalMCE_ID (integer value) */ + ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_Global_MCE_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_M3SetupRequestIEs__value_PR_Global_MCE_ID; + //ie->value.choice.GlobalMCE_ID.MCE_ID = 1;//M3AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP); + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie->value.choice.Global_MCE_ID.pLMN_Identity); + //ie->value.choice.Global_MCE_ID.MCE_ID.present = M3AP_MCE_ID_PR_macro_MCE_ID; + OCTET_STRING_fromBuf(&ie->value.choice.Global_MCE_ID.mCE_ID,"02",2); + + // MACRO_ENB_ID_TO_BIT_STRING(instance_p->MCE_id, + // &ie->value.choice.Global_MCE_ID.mCE_ID); + //M3AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id, + // ie->value.choice.Global_MCE_ID.mCE_ID.buf[0], + // ie->value.choice.Global_MCE_ID.mCE_ID.buf[1], + // ie->value.choice.Global_MCE_ID.mCE_ID.buf[2]); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// ///* mandatory */ +// ///* c2. GNB_MCE_ID (integrer value) */ +// //ie = (M3AP_M3SetupRequest_Ies_t *)calloc(1, sizeof(M3AP_M3SetupRequest_Ies_t)); +// //ie->id = M3AP_ProtocolIE_ID_id_gNB_MCE_ID; +// //ie->criticality = M3AP_Criticality_reject; +// //ie->value.present = M3AP_M3SetupRequestIEs__value_PR_GNB_MCE_ID; +// //asn_int642INTEGER(&ie->value.choice.GNB_MCE_ID, f1ap_du_data->gNB_MCE_id); +// //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ + /* c3. MCEname */ + //m3ap_MCE_data_p->MCE_name="kk"; + if (m3ap_MCE_data_p->MCE_name != NULL) { + ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCEname; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_M3SetupRequestIEs__value_PR_MCEname; + OCTET_STRING_fromBuf(&ie->value.choice.MCEname, m3ap_MCE_data_p->MCE_name, + strlen(m3ap_MCE_data_p->MCE_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ //but removed from asn definition (optional) since it crashes when decoding ??????????? +// M3SetupRequestIEs M3AP-PROTOCOL-IES ::= { +// { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE mandatory}| +// { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| +// { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE mandatory}, --> optional ?????????? +// ... +// } + + + /* M3AP_MBMSServiceAreaListItem_t */ + ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMSServiceAreaList; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_M3SetupRequestIEs__value_PR_MBMSServiceAreaListItem; + + //M3AP_MBMSServiceAreaListItem_t * m3ap_mbmsservicearealistitem = (M3AP_MBMSServiceAreaListItem_t*)calloc(1,sizeof(M3AP_MBMSServiceAreaListItem_t)); + + M3AP_MBMSServiceArea1_t * m3ap_mbmsservicearea1 = (M3AP_MBMSServiceArea1_t*)calloc(1,sizeof(M3AP_MBMSServiceArea1_t)); + + OCTET_STRING_fromBuf(m3ap_mbmsservicearea1,"02",2); + + //ASN_SEQUENCE_ADD(&m3ap_mbmsservicearealistitem->list,m3ap_mbmsservicearea1); + + //ASN_SEQUENCE_ADD(&ie->value.choice.MBMSServiceAreaListItem,m3ap_mbmsservicearealistitem); + //ASN_SEQUENCE_ADD(&ie->value.choice.MBMSServiceAreaListItem.list,m3ap_mbmsservicearealistitem); + ASN_SEQUENCE_ADD(&ie->value.choice.MBMSServiceAreaListItem.list,m3ap_mbmsservicearea1); + + //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + +// +// /* mandatory */ +// /* c4. serverd cells list */ +// ie = (M3AP_M3SetupRequest_Ies_t *)calloc(1, sizeof(M3AP_M3SetupRequest_Ies_t)); +// ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_Configuration_data_List; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_M3SetupRequest_Ies__value_PR_MCE_MBMS_Configuration_data_List; +// +// int num_mbms_available = 1;//m3ap_du_data->num_mbms_available; +// LOG_D(M3AP, "num_mbms_available = %d \n", num_mbms_available); +// +// for (i=0; +// iid = M3AP_ProtocolIE_ID_id_MCE_MBMS_Configuration_data_Item; +// mbms_configuration_data_list_item_ies->criticality = M3AP_Criticality_reject; +// mbms_configuration_data_list_item_ies->value.present = M3AP_MCE_MBMS_Configuration_data_ItemIEs__value_PR_MCE_MBMS_Configuration_data_Item; +// +// M3AP_MCE_MBMS_Configuration_data_Item_t *mbms_configuration_data_item; +// mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.MCE_MBMS_Configuration_data_Item; +// { +// /* M3AP_ECGI_t eCGI */ +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &mbms_configuration_data_item->eCGI.pLMN_Identity); +// MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0, +// &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier); +// /* M3AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea */ +// mbms_configuration_data_item->mbsfnSynchronisationArea=10000; //? long +// /* M3AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList */ +// M3AP_MBMS_Service_Area_t * mbms_service_area,*mbms_service_area2; +// mbms_service_area = (M3AP_MBMS_Service_Area_t*)calloc(1,sizeof(M3AP_MBMS_Service_Area_t)); +// mbms_service_area2 = (M3AP_MBMS_Service_Area_t*)calloc(1,sizeof(M3AP_MBMS_Service_Area_t)); +// //memset(mbms_service_area,0,sizeof(OCTET_STRING_t)); +// OCTET_STRING_fromBuf(mbms_service_area,"01",2); +// ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area); +// OCTET_STRING_fromBuf(mbms_service_area2,"02",2); +// ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area2); +// +// +// } +// +// +// //M3AP_MCE_MBMS_Configuration_data_Item_t mbms_configuration_data_item; +// //memset((void *)&mbms_configuration_data_item, 0, sizeof(M3AP_MCE_MBMS_Configuration_data_Item_t)); +// +// //M3AP_ECGI_t eCGI; +// //M3AP_PLMN_Identity_t pLMN_Identity; +// //M3AP_EUTRANCellIdentifier_t eUTRANcellIdentifier +// //M3AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea; +// //M3AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList; +// +// +// ASN_SEQUENCE_ADD(&ie->value.choice.MCE_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies); +// +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// LOG_W(M3AP,"m3ap_MCE_data_p->assoc_id %d\n",m3ap_MCE_data_p->assoc_id); +// /* encode */ + +// xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, &pdu); +// xer_fprint(stdout, &asn_DEF_M3AP_M3SetupRequest, &pdu.choice.initiatingMessage.value.choice.M3SetupRequest); +// xer_fprint(stdout, &asn_DEF_M3AP_M3SetupRequest, out); + + if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M3AP, "Failed to encode M3 setup request\n"); + return -1; + } + + /* buffer = &m3ap_start_message[0]; + len=8*9+7; + + buffer = &m3ap_m3setup_message[0]; + len=8*4+7; */ +// +// +// LOG_W(M3AP,"pdu.present %d\n",pdu.present); +// // MSC_LOG_TX_MESSAGE( +// // MSC_M3AP_MCE, +// // MSC_M3AP_MCE, +// // (const char *)buffer, +// // len, +// // MSC_AS_TIME_FMT" M3_SETUP_REQUEST initiatingMessage MCEname %s", +// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +// // m3ap_MCE_data_p->MCEname); +// +// +//// buffer = &bytes[0]; +//// len = 40; +//// +//// for(int i=0; i < len; i++ ) +//// printf("%02X",buffer[i]); +//// printf("\n"); +//// + +// M3AP_M3AP_PDU_t pdu2; +// +// memset(&pdu2, 0, sizeof(pdu2)); +// +// for( i=0; i < len; i++) +// printf("%02X",buffer[i]); +// printf("\n"); +// +// if (m3ap_decode_pdu(&pdu2, buffer, len) < 0) { +// LOG_E(M3AP, "Failed to decode PDU\n"); +// //return -1; +// } +// + + //printf("m3ap_MCE_data_p->assoc_id %d\n",m3ap_MCE_data_p->assoc_id); + m3ap_MCE_itti_send_sctp_data_req(instance_p->instance, m3ap_MCE_data_p->assoc_id, buffer, len, 0); + + return 0; +} + + + +int MCE_handle_M3_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) +{ + + LOG_D(M3AP, "MCE_handle_M3_SETUP_RESPONSE\n"); + + AssertFatal(pdu->present == M3AP_M3AP_PDU_PR_successfulOutcome, + "pdu->present != M3AP_M3AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M3AP_ProcedureCode_id_m3Setup, + "pdu->choice.successfulOutcome.procedureCode != M3AP_ProcedureCode_id_M3Setup\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M3AP_Criticality_reject, + "pdu->choice.successfulOutcome.criticality != M3AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M3AP_SuccessfulOutcome__value_PR_M3SetupResponse, + "pdu->choice.successfulOutcome.value.present != M3AP_SuccessfulOutcome__value_PR_M3SetupResponse\n"); + + //M3AP_M3SetupResponse_t *in = &pdu->choice.successfulOutcome.value.choice.M3SetupResponse; + + + //M3AP_M3SetupResponseIEs_t *ie; + //int GlobalMCE_ID = -1; + //int num_cells_to_activate = 0; + //M3AP_Cells_to_be_Activated_List_Item_t *cell; + + MessageDef *msg_p = itti_alloc_new_message (TASK_M3AP_MCE, M3AP_SETUP_RESP); + + // LOG_D(M3AP, "M3AP: M3Setup-Resp: protocolIEs.list.count %d\n", + // in->protocolIEs.list.count); + // for (int i=0;i < in->protocolIEs.list.count; i++) { + // ie = in->protocolIEs.list.array[i]; + // } + //AssertFatal(GlobalMCE_ID!=-1,"GlobalMCE_ID was not sent\n"); + //AssertFatal(num_cells_to_activate>0,"No cells activated\n"); + //M3AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate; + + //for (int i=0;i 0, "System Information %d is missing",i); + + //MSC_LOG_RX_MESSAGE( + // MSC_M3AP_MCE, + // MSC_M3AP_CU, + // 0, + // 0, + // MSC_AS_TIME_FMT" MCE_handle_M3_SETUP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + //LOG_D(M3AP, "Sending M3AP_SETUP_RESP ITTI message to MCE_APP with assoc_id (%d->%d)\n", + // assoc_id,MCE_MOMCELE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + return 0; +} + +// SETUP FAILURE +int MCE_handle_M3_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) { + LOG_E(M3AP, "MCE_handle_M3_SETUP_FAILURE\n"); + return 0; +} + + + + + diff --git a/openair3/M3AP/m3ap_MCE_interface_management.h b/openair3/M3AP/m3ap_MCE_interface_management.h new file mode 100644 index 0000000000..76e13bb8d8 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_interface_management.h @@ -0,0 +1,119 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE_interface_management.h + * \brief m3ap interface management for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#ifndef M3AP_MCE_INTERFACE_MANAGEMENT_H_ +#define M3AP_MCE_INTERFACE_MANAGEMENT_H_ + +/* + * Session Start + */ + +int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +int MCE_send_MBMS_SESSION_START_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp); +int MCE_send_MBMS_SESSION_START_FAILURE(instance_t instance, m3ap_session_start_failure_t * m3ap_session_start_failure); + +/* + * Session Stop + */ + +int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +/* + * Session Update + */ +int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +int MCE_send_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, m3ap_mbms_session_update_resp_t * m3ap_mbms_session_update_resp); +int MCE_send_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, m3ap_mbms_session_update_failure_t * m3ap_mbms_session_update_failure); + + + + + + + +int MCE_send_MBMS_SESSION_STOP_RESPONSE(instance_t instance, m3ap_session_start_resp_t * m3ap_session_start_resp); + +/* + * Reset + */ +int MCE_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +int MCE_send_RESET_ACKKNOWLEDGE(instance_t instance, M3AP_ResetAcknowledge_t *ResetAcknowledge); +int MCE_send_RESET(instance_t instance, M3AP_Reset_t *Reset); +int MCE_handle_RESET_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +/* + * M3AP Setup + */ +int MCE_send_M3_SETUP_REQUEST( m3ap_MCE_instance_t *instance_p, m3ap_MCE_data_t *m3ap_MCE_data_p); + +int MCE_handle_M3_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +int MCE_handle_M3_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +/* + * Error Indication + */ +int MCE_send_ERROR_INDICATION(instance_t instance, M3AP_M3AP_PDU_t *pdu_p); +int MCE_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + + + + +#endif /* M3AP_MCE_INTERFACE_MANAGEMENT_H_ */ + + + diff --git a/openair3/M3AP/m3ap_MCE_management_procedures.c b/openair3/M3AP/m3ap_MCE_management_procedures.c new file mode 100644 index 0000000000..106d211f10 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_management_procedures.c @@ -0,0 +1,257 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE_management_procedures.c + * \brief m3ap tasks for MCE + * \author Javier Morgade + * \date 2018 + * \version 1.0 + */ + +#include +#include +#include + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "m3ap_common.h" +#include "m3ap_MCE_defs.h" +#include "m3ap_MCE.h" + + +#define M3AP_DEBUG_LIST +#ifdef M3AP_DEBUG_LIST +# define M3AP_MCE_LIST_OUT(x, args...) M3AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args) +#else +# define M3AP_MCE_LIST_OUT(x, args...) +#endif + +static int indent = 0; + + +m3ap_MCE_internal_data_t m3ap_MCE_internal_data; + +RB_GENERATE(m3ap_mce_map, m3ap_MCE_data_s, entry, m3ap_MCE_compare_assoc_id); + +int m3ap_MCE_compare_assoc_id( + struct m3ap_MCE_data_s *p1, struct m3ap_MCE_data_s *p2) +{ + if (p1->assoc_id == -1) { + if (p1->cnx_id < p2->cnx_id) { + return -1; + } + + if (p1->cnx_id > p2->cnx_id) { + return 1; + } + } else { + if (p1->assoc_id < p2->assoc_id) { + return -1; + } + + if (p1->assoc_id > p2->assoc_id) { + return 1; + } + } + + /* Matching reference */ + return 0; +} + +uint16_t m3ap_MCE_fetch_add_global_cnx_id(void) +{ + return ++m3ap_MCE_internal_data.global_cnx_id; +} + +void m3ap_MCE_prepare_internal_data(void) +{ + memset(&m3ap_MCE_internal_data, 0, sizeof(m3ap_MCE_internal_data)); + STAILQ_INIT(&m3ap_MCE_internal_data.m3ap_MCE_instances_head); +} + +void m3ap_MCE_insert_new_instance(m3ap_MCE_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&m3ap_MCE_internal_data.m3ap_MCE_instances_head, + new_instance_p, m3ap_MCE_entries); +} + +void dump_tree_m3(m3ap_MCE_data_t *t) +{ + if (t == NULL) return; + printf("-----------------------\n"); + printf("MCE id %d %s\n", t->MCE_id, t->MCE_name); + printf("state %d\n", t->state); + printf("nextstream %d\n", t->nextstream); + printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams); + printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id); + dump_tree_m3(t->entry.rbe_left); + dump_tree_m3(t->entry.rbe_right); +} + +void dump_trees_m3(void) +{ +m3ap_MCE_instance_t *zz; +STAILQ_FOREACH(zz, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, + m3ap_MCE_entries) { +printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +dump_tree_m3(zz->m3ap_mce_head.rbh_root); +printf("---------------------------------------------\n"); +} +} + +struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id) +{ + struct m3ap_MCE_data_s temp; + struct m3ap_MCE_data_s *found; + +printf("m3ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +dump_trees_m3(); + + memset(&temp, 0, sizeof(struct m3ap_MCE_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, + m3ap_MCE_entries) { + found = RB_FIND(m3ap_mce_map, &instance_p->m3ap_mce_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(m3ap_mce_map, &instance_p->m3ap_mce_head, &temp); + } + + return NULL; +} + + +m3ap_MCE_instance_t *m3ap_MCE_get_instance(instance_t instance) +{ + m3ap_MCE_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, + m3ap_MCE_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} + +/// utility functions + +void m3ap_dump_MCE (m3ap_MCE_data_t * MCE_ref); + +void +m3ap_dump_MCE_list (void) { + m3ap_MCE_instance_t *inst = NULL; + struct m3ap_MCE_data_s *found = NULL; + struct m3ap_MCE_data_s temp; + + memset(&temp, 0, sizeof(struct m3ap_MCE_data_s)); + + STAILQ_FOREACH (inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) { + found = RB_FIND(m3ap_mce_map, &inst->m3ap_mce_head, &temp); + m3ap_dump_MCE (found); + } +} + +void m3ap_dump_MCE (m3ap_MCE_data_t * MCE_ref) { + + if (MCE_ref == NULL) { + return; + } + + M3AP_MCE_LIST_OUT (""); + M3AP_MCE_LIST_OUT ("MCE name: %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name); + M3AP_MCE_LIST_OUT ("MCE STATE: %07x", MCE_ref->state); + M3AP_MCE_LIST_OUT ("MCE ID: %07x", MCE_ref->MCE_id); + indent++; + M3AP_MCE_LIST_OUT ("SCTP cnx id: %d", MCE_ref->cnx_id); + M3AP_MCE_LIST_OUT ("SCTP assoc id: %d", MCE_ref->assoc_id); + M3AP_MCE_LIST_OUT ("SCTP instreams: %d", MCE_ref->in_streams); + M3AP_MCE_LIST_OUT ("SCTP outstreams: %d", MCE_ref->out_streams); + indent--; +} + +m3ap_MCE_data_t * m3ap_is_MCE_pci_in_list (const uint32_t pci) +{ + m3ap_MCE_instance_t *inst; + struct m3ap_MCE_data_s *elm; + + STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) { + RB_FOREACH(elm, m3ap_mce_map, &inst->m3ap_mce_head) { + for (int i = 0; inum_cc; i++) { + if (elm->Nid_cell[i] == pci) { + return elm; + } + } + } + } + return NULL; +} + +m3ap_MCE_data_t * m3ap_is_MCE_id_in_list (const uint32_t MCE_id) +{ + m3ap_MCE_instance_t *inst; + struct m3ap_MCE_data_s *elm; + + STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) { + RB_FOREACH(elm, m3ap_mce_map, &inst->m3ap_mce_head) { + if (elm->MCE_id == MCE_id) + return elm; + } + } + return NULL; +} + +m3ap_MCE_data_t * m3ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id) +{ + m3ap_MCE_instance_t *inst; + struct m3ap_MCE_data_s *found; + struct m3ap_MCE_data_s temp; + + temp.assoc_id = sctp_assoc_id; + temp.cnx_id = -1; + + STAILQ_FOREACH(inst, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) { + found = RB_FIND(m3ap_mce_map, &inst->m3ap_mce_head, &temp); + if (found != NULL){ + if (found->assoc_id == sctp_assoc_id) { + return found; + } + } + } + return NULL; +} diff --git a/openair3/M3AP/m3ap_MCE_management_procedures.h b/openair3/M3AP/m3ap_MCE_management_procedures.h new file mode 100644 index 0000000000..2d18df8c26 --- /dev/null +++ b/openair3/M3AP/m3ap_MCE_management_procedures.h @@ -0,0 +1,53 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE_management_procedures.h + * \brief m3ap tasks for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_MCE_MANAGEMENT_PROCEDURES_H_ +#define M3AP_MCE_MANAGEMENT_PROCEDURES_H + +void m3ap_MCE_prepare_internal_data(void); + +void dump_trees_m3(void); + +void m3ap_MCE_insert_new_instance(m3ap_MCE_instance_t *new_instance_p); + +m3ap_MCE_instance_t *m3ap_MCE_get_instance(uint8_t mod_id); + +uint16_t m3ap_MCE_fetch_add_global_cnx_id(void); + + +m3ap_MCE_data_t* m3ap_is_MCE_id_in_list(uint32_t MCE_id); + +m3ap_MCE_data_t* m3ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id); + +m3ap_MCE_data_t* m3ap_is_MCE_pci_in_list (const uint32_t pci); + +struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id); + +#endif /* M3AP_MCE_MANAGEMENT_PROCEDURES_H_ */ diff --git a/openair3/M3AP/m3ap_MME.c b/openair3/M3AP/m3ap_MME.c new file mode 100644 index 0000000000..fbfe6e1327 --- /dev/null +++ b/openair3/M3AP/m3ap_MME.c @@ -0,0 +1,730 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MME.c + * \brief m3ap tasks for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include +#include +#include + +#include "intertask_interface.h" + +#include "m3ap_MME.h" +#include "m3ap_MME_defs.h" +#include "m3ap_MME_management_procedures.h" +#include "m3ap_MME_handler.h" +//#include "m3ap_MME_generate_messages.h" +#include "m3ap_common.h" +#include "m3ap_MME_interface_management.h" +#include "m3ap_ids.h" +#include "m3ap_timers.h" + +#include "queue.h" +#include "assertions.h" +#include "conversions.h" + +struct m3ap_mme_map; +struct m3ap_MME_data_s; + +m3ap_setup_req_t *m3ap_mme_data_from_mce; + +RB_PROTOTYPE(m3ap_mme_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id); + +static +void m3ap_MME_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); + +static +void m3ap_MME_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +static +void m3ap_MME_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind); + +//static +//void m3ap_MME_handle_register_MME(instance_t instance, +// m3ap_register_mce_req_t *m3ap_register_MME); +static +void m3ap_MME_register_MME(m3ap_MME_instance_t *instance_p, + net_ip_address_t *target_MME_ip_addr, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t mme_port_for_M3C, + int multi_sd); + +//static +//void m3ap_MME_handle_handover_req(instance_t instance, +// m3ap_handover_req_t *m3ap_handover_req); +// +//static +//void m3ap_MME_handle_handover_req_ack(instance_t instance, +// m3ap_handover_req_ack_t *m3ap_handover_req_ack); +// +//static +//void m3ap_MME_ue_context_release(instance_t instance, +// m3ap_ue_context_release_t *m3ap_ue_context_release); +// + +static +void m3ap_MME_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { + int result; + DevAssert(sctp_data_ind != NULL); + m3ap_MME_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + +static +void m3ap_MME_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + + DevAssert(sctp_new_association_resp != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + LOG_W(M3AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + + if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN) + //proto_agent_stop(instance); + //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; // exit -1 for debugging + } + + // go to an init func + m3ap_mme_data_from_mce = (m3ap_setup_req_t *)calloc(1, sizeof(m3ap_setup_req_t)); + // save the assoc id + m3ap_mme_data_from_mce->assoc_id = sctp_new_association_resp->assoc_id; + m3ap_mme_data_from_mce->sctp_in_streams = sctp_new_association_resp->in_streams; + m3ap_mme_data_from_mce->sctp_out_streams = sctp_new_association_resp->out_streams; + + + + // m3ap_MME_instance_t *instance_p; + // m3ap_MME_data_t *m3ap_mme_data_p; + // DevAssert(sctp_new_association_resp != NULL); + // printf("m3ap_MME_handle_sctp_association_resp at 1\n"); + // dump_mme_trees_m3(); + // instance_p = instance;//m3ap_MME_get_instance(instance); + // DevAssert(instance_p != NULL); + + // /* if the assoc_id is already known, it is certainly because an IND was received + // * before. In this case, just update streams and return + // */ + // if (sctp_new_association_resp->assoc_id != -1) { + // m3ap_mme_data_p = m3ap_get_MME(instance_p, sctp_new_association_resp->assoc_id, + // sctp_new_association_resp->ulp_cnx_id); + + // if (m3ap_mme_data_p != NULL) { + // /* some sanity check - to be refined at some point */ + // if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + // M3AP_ERROR("m3ap_mme_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); + // abort(); + // } + + // m3ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; + // m3ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; + // return; + // } + // } + + // m3ap_mme_data_p = m3ap_get_MME(instance_p, -1, + // sctp_new_association_resp->ulp_cnx_id); + // DevAssert(m3ap_mme_data_p != NULL); + // printf("m3ap_MME_handle_sctp_association_resp at 2\n"); + // dump_mme_trees_m3(); + + // if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + // M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + // sctp_new_association_resp->sctp_state, + // instance, + // sctp_new_association_resp->ulp_cnx_id); + // //m3ap_eNB_handle_m3_setup_message(instance_p, m3ap_mme_data_p, + // //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + // return; + // } + + // printf("m3ap_MME_handle_sctp_association_resp at 3\n"); + // dump_mme_trees_m3(); + // /* Update parameters */ + // m3ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; + // m3ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; + // m3ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; + // printf("m3ap_MME_handle_sctp_association_resp at 4\n"); + // dump_mme_trees_m3(); + // /* Prepare new m3 Setup Request */ + // //m3ap_MME_generate_m3_setup_request(instance_p, m3ap_mme_data_p); +} + +static +void m3ap_MME_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { + //m3ap_MME_instance_t *instance_p; + //m3ap_MME_data_t *m3ap_mme_data_p; + //printf("m3ap_MME_handle_sctp_association_ind at 1 (called for instance %d)\n", instance); + ///dump_mme_trees_m3(); + ///DevAssert(sctp_new_association_ind != NULL); + ///instance_p = instance;//m3ap_MME_get_instance(instance); + ///DevAssert(instance_p != NULL); + ///m3ap_mme_data_p = m3ap_get_MME(instance_p, sctp_new_association_ind->assoc_id, -1); + + ///if (m3ap_mme_data_p != NULL) abort(); + + ///// DevAssert(m3ap_enb_data_p != NULL); + ///if (m3ap_mme_data_p == NULL) { + /// /* Create new MME descriptor */ + /// m3ap_mme_data_p = calloc(1, sizeof(*m3ap_mme_data_p)); + /// DevAssert(m3ap_mme_data_p != NULL); + /// m3ap_mme_data_p->cnx_id = m3ap_MME_fetch_add_global_cnx_id(); + /// m3ap_mme_data_p->m3ap_MME_instance = instance_p; + /// /* Insert the new descriptor in list of known MME + /// * but not yet associated. + /// */ + /// RB_INSERT(m3ap_mme_map, &instance_p->m3ap_mme_head, m3ap_mme_data_p); + /// m3ap_mme_data_p->state = M3AP_MME_STATE_CONNECTED; + /// instance_p->m3_target_mme_nb++; + + /// if (instance_p->m3_target_mme_pending_nb > 0) { + /// instance_p->m3_target_mme_pending_nb--; + /// } + ///} else { + /// M3AP_WARN("m3ap_mme_data_p already exists\n"); + ///} + + ///printf("m3ap_MME_handle_sctp_association_ind at 2\n"); + ///dump_mme_trees_m3(); + ////* Update parameters */ + ///m3ap_mme_data_p->assoc_id = sctp_new_association_ind->assoc_id; + ///m3ap_mme_data_p->in_streams = sctp_new_association_ind->in_streams; + ///m3ap_mme_data_p->out_streams = sctp_new_association_ind->out_streams; + ///printf("m3ap_MME_handle_sctp_association_ind at 3\n"); + ///dump_mme_trees_m3(); +} + +int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t mme_port_for_M3C) { + // Create and alloc new message + MessageDef *message; + sctp_init_t *sctp_init = NULL; + DevAssert(instance_p != NULL); + DevAssert(local_ip_addr != NULL); + message = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG_MULTI_REQ); + sctp_init = &message->ittiMsg.sctp_init_multi; + sctp_init->port = mme_port_for_M3C; + sctp_init->ppid = M3AP_SCTP_PPID; + sctp_init->ipv4 = 1; + sctp_init->ipv6 = 0; + sctp_init->nb_ipv4_addr = 1; +#if 0 + memcpy(&sctp_init->ipv4_address, + local_ip_addr, + sizeof(*local_ip_addr)); +#endif + sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + sctp_init->nb_ipv6_addr = 0; + sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1"; + return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message); +} + +static void m3ap_MME_register_MME(m3ap_MME_instance_t *instance_p, + net_ip_address_t *target_MME_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint32_t mme_port_for_M3C, + int multi_sd) { + // MessageDef *message = NULL; + // sctp_new_association_req_multi_t *sctp_new_association_req = NULL; + // m3ap_MME_data_t *m3ap_mme_data = NULL; + // DevAssert(instance_p != NULL); + // DevAssert(target_MME_ip_address != NULL); + // message = itti_alloc_new_message(TASK_M3AP_MME, SCTP_NEW_ASSOCIATION_REQ_MULTI); + // sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; + // sctp_new_association_req->port = mme_port_for_M3C; + // sctp_new_association_req->ppid = M3AP_SCTP_PPID; + // sctp_new_association_req->in_streams = in_streams; + // sctp_new_association_req->out_streams = out_streams; + // sctp_new_association_req->multi_sd = multi_sd; + // memcpy(&sctp_new_association_req->remote_address, + // target_MME_ip_address, + // sizeof(*target_MME_ip_address)); + // memcpy(&sctp_new_association_req->local_address, + // local_ip_addr, + // sizeof(*local_ip_addr)); + // /* Create new MME descriptor */ + // m3ap_mme_data = calloc(1, sizeof(*m3ap_mme_data)); + // DevAssert(m3ap_mme_data != NULL); + // m3ap_mme_data->cnx_id = m3ap_MME_fetch_add_global_cnx_id(); + // sctp_new_association_req->ulp_cnx_id = m3ap_mme_data->cnx_id; + // m3ap_mme_data->assoc_id = -1; + // m3ap_mme_data->m3ap_MME_instance = instance_p; + // /* Insert the new descriptor in list of known MME + // * but not yet associated. + // */ + // RB_INSERT(m3ap_mme_map, &instance_p->m3ap_mme_head, m3ap_mme_data); + // m3ap_mme_data->state = M3AP_MME_STATE_WAITING; + // instance_p->m3_target_mme_nb ++; + // instance_p->m3_target_mme_pending_nb ++; + // itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message); +} + +//static +//void m3ap_MME_handle_register_MME(instance_t instance, +// m3ap_register_mce_req_t *m3ap_register_MME) { +// m3ap_MME_instance_t *new_instance; +// DevAssert(m3ap_register_MME != NULL); +// /* Look if the provided instance already exists */ +// new_instance = m3ap_MME_get_instance(instance); +// +// if (new_instance != NULL) { +// /* Checks if it is a retry on the same MME */ +// DevCheck(new_instance->MME_id == m3ap_register_MME->MME_id, new_instance->MME_id, m3ap_register_MME->MME_id, 0); +// DevCheck(new_instance->cell_type == m3ap_register_MME->cell_type, new_instance->cell_type, m3ap_register_MME->cell_type, 0); +// DevCheck(new_instance->tac == m3ap_register_MME->tac, new_instance->tac, m3ap_register_MME->tac, 0); +// DevCheck(new_instance->mcc == m3ap_register_MME->mcc, new_instance->mcc, m3ap_register_MME->mcc, 0); +// DevCheck(new_instance->mnc == m3ap_register_MME->mnc, new_instance->mnc, m3ap_register_MME->mnc, 0); +// M3AP_WARN("MME[%d] already registered\n", instance); +// } else { +// new_instance = calloc(1, sizeof(m3ap_MME_instance_t)); +// DevAssert(new_instance != NULL); +// RB_INIT(&new_instance->m3ap_mme_head); +// /* Copy usefull parameters */ +// new_instance->instance = instance; +// new_instance->MME_name = m3ap_register_MME->MME_name; +// new_instance->MME_id = m3ap_register_MME->MME_id; +// new_instance->cell_type = m3ap_register_MME->cell_type; +// new_instance->tac = m3ap_register_MME->tac; +// new_instance->mcc = m3ap_register_MME->mcc; +// new_instance->mnc = m3ap_register_MME->mnc; +// new_instance->mnc_digit_length = m3ap_register_MME->mnc_digit_length; +// new_instance->num_cc = m3ap_register_MME->num_cc; +// +// m3ap_id_manager_init(&new_instance->id_manager); +// m3ap_timers_init(&new_instance->timers, +// m3ap_register_MME->t_reloc_prep, +// m3ap_register_MME->tm3_reloc_overall); +// +// for (int i = 0; i< m3ap_register_MME->num_cc; i++) { +// new_instance->eutra_band[i] = m3ap_register_MME->eutra_band[i]; +// new_instance->downlink_frequency[i] = m3ap_register_MME->downlink_frequency[i]; +// new_instance->uplink_frequency_offset[i] = m3ap_register_MME->uplink_frequency_offset[i]; +// new_instance->Nid_cell[i] = m3ap_register_MME->Nid_cell[i]; +// new_instance->N_RB_DL[i] = m3ap_register_MME->N_RB_DL[i]; +// new_instance->frame_type[i] = m3ap_register_MME->frame_type[i]; +// new_instance->fdd_earfcn_DL[i] = m3ap_register_MME->fdd_earfcn_DL[i]; +// new_instance->fdd_earfcn_UL[i] = m3ap_register_MME->fdd_earfcn_UL[i]; +// } +// +// DevCheck(m3ap_register_MME->nb_m3 <= M3AP_MAX_NB_MME_IP_ADDRESS, +// M3AP_MAX_NB_MME_IP_ADDRESS, m3ap_register_MME->nb_m3, 0); +// memcpy(new_instance->target_mme_m3_ip_address, +// m3ap_register_MME->target_mme_m3_ip_address, +// m3ap_register_MME->nb_m3 * sizeof(net_ip_address_t)); +// new_instance->nb_m3 = m3ap_register_MME->nb_m3; +// new_instance->mme_m3_ip_address = m3ap_register_MME->mme_m3_ip_address; +// new_instance->sctp_in_streams = m3ap_register_MME->sctp_in_streams; +// new_instance->sctp_out_streams = m3ap_register_MME->sctp_out_streams; +// new_instance->mme_port_for_M3C = m3ap_register_MME->mme_port_for_M3C; +// /* Add the new instance to the list of MME (meaningfull in virtual mode) */ +// m3ap_MME_insert_new_instance(new_instance); +// M3AP_INFO("Registered new MME[%d] and %s MME id %u\n", +// instance, +// m3ap_register_MME->cell_type == CELL_MACRO_ENB ? "macro" : "home", +// m3ap_register_MME->MME_id); +// +// /* initiate the SCTP listener */ +// if (m3ap_MME_init_sctp(new_instance,&m3ap_register_MME->mme_m3_ip_address,m3ap_register_MME->mme_port_for_M3C) < 0 ) { +// M3AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n"); +// return; +// } +// +// M3AP_INFO("MME[%d] MME id %u acting as a listner (server)\n", +// instance, m3ap_register_MME->MME_id); +// } +//} + +static +void m3ap_MME_handle_sctp_init_msg_multi_cnf( + instance_t instance_id, + sctp_init_msg_multi_cnf_t *m) { + m3ap_MME_instance_t *instance; + int index; + DevAssert(m != NULL); + instance = m3ap_MME_get_instance(instance_id); + DevAssert(instance != NULL); + instance->multi_sd = m->multi_sd; + + /* Exit if CNF message reports failure. + * Failure means multi_sd < 0. + */ + if (instance->multi_sd < 0) { + M3AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n"); + DevAssert(instance->multi_sd >= 0); + } + + /* Trying to connect to the provided list of MME ip address */ + + for (index = 0; index < instance->nb_m3; index++) { + M3AP_INFO("MME[%d] MME id %u acting as an initiator (client)\n", + instance_id, instance->MME_id); + m3ap_MME_register_MME(instance, + &instance->target_mme_m3_ip_address[index], + &instance->mme_m3_ip_address, + instance->sctp_in_streams, + instance->sctp_out_streams, + instance->mme_port_for_M3C, + instance->multi_sd); + } +} + +//static +//void m3ap_MME_handle_handover_req(instance_t instance, +// m3ap_handover_req_t *m3ap_handover_req) +//{ +// m3ap_MME_instance_t *instance_p; +// m3ap_MME_data_t *target; +// m3ap_id_manager *id_manager; +// int ue_id; +// +// int target_pci = m3ap_handover_req->target_physCellId; +// +// instance_p = m3ap_MME_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m3ap_is_MME_pci_in_list(target_pci); +// DevAssert(target != NULL); +// +// /* allocate m3ap ID */ +// id_manager = &instance_p->id_manager; +// ue_id = m3ap_allocate_new_id(id_manager); +// if (ue_id == -1) { +// M3AP_ERROR("could not allocate a new M3AP UE ID\n"); +// /* TODO: cancel handover: send (to be defined) message to RRC */ +// exit(1); +// } +// /* id_source is ue_id, id_target is unknown yet */ +// m3ap_set_ids(id_manager, ue_id, m3ap_handover_req->rnti, ue_id, -1); +// m3ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE); +// m3ap_set_reloc_prep_timer(id_manager, ue_id, +// m3ap_timer_get_tti(&instance_p->timers)); +// m3ap_id_set_target(id_manager, ue_id, target); +// +// m3ap_MME_generate_m3_handover_request(instance_p, target, m3ap_handover_req, ue_id); +//} + +//static +//void m3ap_MME_handle_handover_req_ack(instance_t instance, +// m3ap_handover_req_ack_t *m3ap_handover_req_ack) +//{ +// /* TODO: remove this hack (the goal is to find the correct +// * eNodeB structure for the other end) - we need a proper way for RRC +// * and M3AP to identify eNodeBs +// * RRC knows about mod_id and M3AP knows about MME_id (MME_ID in +// * the configuration file) +// * as far as I understand.. CROUX +// */ +// m3ap_MME_instance_t *instance_p; +// m3ap_MME_data_t *target; +// int source_assoc_id = m3ap_handover_req_ack->source_assoc_id; +// int ue_id; +// int id_source; +// int id_target; +// +// instance_p = m3ap_MME_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m3ap_get_MME(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// /* rnti is a new information, save it */ +// ue_id = m3ap_handover_req_ack->m3_id_target; +// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// m3ap_set_ids(&instance_p->id_manager, ue_id, m3ap_handover_req_ack->rnti, id_source, id_target); +// +// m3ap_MME_generate_m3_handover_request_ack(instance_p, target, m3ap_handover_req_ack); +//} +// +//static +//void m3ap_MME_ue_context_release(instance_t instance, +// m3ap_ue_context_release_t *m3ap_ue_context_release) +//{ +// m3ap_MME_instance_t *instance_p; +// m3ap_MME_data_t *target; +// int source_assoc_id = m3ap_ue_context_release->source_assoc_id; +// int ue_id; +// instance_p = m3ap_MME_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// target = m3ap_get_MME(NULL, source_assoc_id, 0); +// DevAssert(target != NULL); +// +// m3ap_MME_generate_m3_ue_context_release(instance_p, target, m3ap_ue_context_release); +// +// /* free the M3AP UE ID */ +// ue_id = m3ap_find_id_from_rnti(&instance_p->id_manager, m3ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M3AP_ERROR("could not find UE %x\n", m3ap_ue_context_release->rnti); +// exit(1); +// } +// m3ap_release_id(&instance_p->id_manager, ue_id); +//} + +void MME_task_send_sctp_init_req(instance_t enb_id, m3ap_mme_sctp_req_t * m3ap_mme_sctp_req) { + // 1. get the itti msg, and retrive the enb_id from the message + // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port + // 3. creat an itti message to init + + MessageDef *message_p = NULL; + + message_p = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG); +if(m3ap_mme_sctp_req==NULL) { + LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n"); + message_p->ittiMsg.sctp_init.port = M3AP_PORT_NUMBER; + message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID; + message_p->ittiMsg.sctp_init.ipv4 = 1; + message_p->ittiMsg.sctp_init.ipv6 = 0; + message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); + message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.8"); + +}else{ + + LOG_I(M3AP, "M3AP_SCTP_REQ(create socket) %s\n",m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address); + message_p->ittiMsg.sctp_init.port = m3ap_mme_sctp_req->mme_port_for_M3C; + message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID; + message_p->ittiMsg.sctp_init.ipv4 = 1; + message_p->ittiMsg.sctp_init.ipv6 = 0; + message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); + message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address); + } + + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; + message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + + itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); +} + +void *m3ap_MME_task(void *arg) { + MessageDef *received_msg = NULL; + int result; + M3AP_DEBUG("Starting M3AP layer\n"); + m3ap_MME_prepare_internal_data(); + itti_mark_task_ready(TASK_M3AP_MME); + + //MME_task_send_sctp_init_req(0,NULL); + + + while (1) { + itti_receive_msg(TASK_M3AP_MME, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case MESSAGE_TEST: + LOG_W(M3AP,"MME Received MESSAGE_TEST Message\n"); + //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP_MME, MESSAGE_TEST); + //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p); + break; + case TERMINATE_MESSAGE: + M3AP_WARN(" *** Exiting M3AP thread\n"); + itti_exit_task(); + break; + +// case M3AP_SUBFRAME_PROCESS: +// m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); +// break; +// +// case M3AP_REGISTER_MME_REQ: +// LOG_W(M3AP,"MME Received M3AP_REGISTER_MME_REQ Message\n"); +// m3ap_MME_handle_register_MME(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_REGISTER_MME_REQ(received_msg)); +// break; +// + + case M3AP_MME_SCTP_REQ: + MME_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_MME_SCTP_REQ(received_msg)); + break; + + case M3AP_SETUP_RESP: + LOG_I(M3AP,"MME Received M3AP_SETUP_RESP Message\n"); + MME_send_M3_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_SETUP_RESP(received_msg)); + break; +// break; +// +// case M3AP_SETUP_FAILURE: +// LOG_W(M3AP,"MME Received M3AP_SETUP_FAILURE Message\n"); +// MME_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_SETUP_FAILURE(received_msg)); +// break; +// +// case M3AP_MBMS_SCHEDULING_INFORMATION: +// LOG_W(M3AP,"MME Received M3AP_MBMS_SCHEDULING_INFORMATION Message\n"); +// MME_send_MBMS_SCHEDULING_INFORMATION(0, +// &M3AP_MBMS_SCHEDULING_INFORMATION(received_msg)); +// + case M3AP_MBMS_SESSION_START_REQ: + LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_START_REQ Message\n"); + MME_send_MBMS_SESSION_START_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_MBMS_SESSION_START_REQ(received_msg)); + break; +// + case M3AP_MBMS_SESSION_STOP_REQ: + LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_STOP_REQ Message\n"); + MME_send_MBMS_SESSION_STOP_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &M3AP_MBMS_SESSION_STOP_REQ(received_msg)); + break; +// + case M3AP_MBMS_SESSION_UPDATE_REQ: + LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_UPDATE_REQ Message\n"); + // MME_send_MBMS_SESSION_UPDATE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + // &M3AP_MBMS_SESSION_UPDATE_REQ(received_msg)); + break; +// +// case M3AP_RESET: +// LOG_W(M3AP,"MME Received M3AP_RESET Message\n"); +// MME_send_RESET(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_RESET(received_msg)); +// break; +// +// case M3AP_ENB_CONFIGURATION_UPDATE_ACK: +// LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_ACK Message\n"); +// MME_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg)); +// break; +// +// case M3AP_ENB_CONFIGURATION_UPDATE_FAILURE: +// LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n"); +// MME_send_ENB_CONFIGURATION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg))// break; +// +// +// case M3AP_MME_CONFIGURATION_UPDATE: +// LOG_W(M3AP,"MME Received M3AP_MME_CONFIGURATION_UPDATE Message\n"); +// MME_send_MME_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_MME_CONFIGURATION_UPDATE(received_msg)); +// break; +// + +// case M3AP_HANDOVER_REQ: +// m3ap_MME_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_HANDOVER_REQ(received_msg)); +// break; +// +// case M3AP_HANDOVER_REQ_ACK: +// m3ap_MME_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_HANDOVER_REQ_ACK(received_msg)); +// break; +// +// case M3AP_UE_CONTEXT_RELEASE: +// m3ap_MME_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// &M3AP_UE_CONTEXT_RELEASE(received_msg)); +// break; +// + case SCTP_INIT_MSG_MULTI_CNF: + LOG_E(M3AP,"MME Received SCTP_INIT_MSG_MULTI_CNF Message ... shoudn't be happening ... it doesn't at leaast with M2AP_MCEC\n"); + m3ap_MME_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_init_msg_multi_cnf); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION_RESP Message\n"); + m3ap_MME_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_NEW_ASSOCIATION_IND: + LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION Message\n"); + m3ap_MME_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_DATA_IND: + LOG_D(M3AP,"MME Received SCTP_DATA_IND Message\n"); + m3ap_MME_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + default: + M3AP_ERROR("MME Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; + } + + return NULL; +} + +#include "common/config/config_userapi.h" + +int is_m3ap_MME_enabled(void) +{ + static volatile int config_loaded = 0; + static volatile int enabled = 0; + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if (pthread_mutex_lock(&mutex)) goto mutex_error; + + if (config_loaded) { + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + return enabled; + } + + char *enable_m3 = NULL; + paramdef_t p[] = { + { "enable_mme_m3", "yes/no", 0, strptr:&enable_m3, defstrval:"", TYPE_STRING, 0 } + }; + + /* TODO: do it per module - we check only first MME */ + config_get(p, sizeof(p)/sizeof(paramdef_t), "MMEs.[0]"); + if (enable_m3 != NULL && strcmp(enable_m3, "yes") == 0) + enabled = 1; + + config_loaded = 1; + + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + + return enabled; + +mutex_error: + LOG_E(M3AP, "mutex error\n"); + exit(1); +} diff --git a/openair3/M3AP/m3ap_MME.h b/openair3/M3AP/m3ap_MME.h new file mode 100644 index 0000000000..f5d1b158e4 --- /dev/null +++ b/openair3/M3AP/m3ap_MME.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MME.h + * \brief m3ap tasks for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include + +/** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + +#ifndef M3AP_MME_H_ +#define M3AP_MME_H_ + +#include "m3ap_MME_defs.h" + + +int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t enb_port_for_M3C); + +void *m3ap_MME_task(void *arg); + +int is_m3ap_MME_enabled(void); + +#endif /* M3AP_MCE_H_ */ + +/** + * @} + */ diff --git a/openair3/M3AP/m3ap_MME_defs.h b/openair3/M3AP/m3ap_MME_defs.h new file mode 100644 index 0000000000..3b5725655d --- /dev/null +++ b/openair3/M3AP/m3ap_MME_defs.h @@ -0,0 +1,210 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MME_defs.h + * \brief m2ap struct definitions for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#include "m3ap_ids.h" //looks X2AP specific for HO +#include "m3ap_timers.h" + +#ifndef M3AP_MME_DEFS_H_ +#define M3AP_MME_DEFS_H_ + +#define M3AP_MME_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + M3AP_MME_STATE_DISCONNECTED = 0x0, + + /* State waiting for m2 Setup response message if the target MME accepts or + * M2 Setup failure if rejects the MME. + */ + M3AP_MME_STATE_WAITING = 0x1, + + /* The MME is successfully connected to another MME. */ + M3AP_MME_STATE_CONNECTED = 0x2, + + /* M3AP is ready, and the MME is successfully connected to another MME. */ + M3AP_MME_STATE_READY = 0x3, + + M3AP_MME_STATE_OVERLOAD = 0x4, + + M3AP_MME_STATE_RESETTING = 0x5, + + /* Max number of states available */ + M3AP_MME_STATE_MAX, +} m3ap_MME_state_t; + +/* Served PLMN identity element */ +/*struct plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + STAILQ_ENTRY(plmn_identity_s) next; +};*/ + +/* Served group id element */ +/*struct served_group_id_s { + uint16_t mce_group_id; + STAILQ_ENTRY(served_group_id_s) next; +};*/ + +/* Served enn code for a particular MME */ +/*struct mce_code_s { + uint8_t mce_code; + STAILQ_ENTRY(mce_code_s) next; +};*/ + +struct m3ap_MME_instance_s; + +/* This structure describes association of a MME to another MME */ +typedef struct m3ap_MME_data_s { + /* MME descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(m3ap_MME_data_s) entry; + + /* This is the optional name provided by the MME */ + char *MME_name; + + /* target MME ID */ + uint32_t MME_id; + + /* Current MME load information (if any). */ + //m3ap_load_state_t overload_state; + + /* Current MME->MME M3AP association state */ + m3ap_MME_state_t state; + + /* Next usable stream for UE signalling */ + int32_t nextstream; + + /* Number of input/ouput streams */ + uint16_t in_streams; + uint16_t out_streams; + + /* Connexion id used between SCTP/M3AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Nid cells */ + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + + /* Only meaningfull in virtual mode */ + struct m3ap_MME_instance_s *m3ap_MME_instance; +} m3ap_MME_data_t; + +typedef struct m3ap_MME_instance_s { + /* used in simulation to store multiple MME instances*/ + STAILQ_ENTRY(m3ap_MME_instance_s) m3ap_MME_entries; + + /* Number of target MMEs requested by MME (tree size) */ + uint32_t m2_target_mce_nb; + /* Number of target MMEs for which association is pending */ + uint32_t m2_target_mce_pending_nb; + /* Number of target MME successfully associated to MME */ + uint32_t m2_target_mce_associated_nb; + /* Tree of M3AP MME associations ordered by association ID */ + RB_HEAD(m3ap_mme_map, m3ap_MME_data_s) m3ap_mme_head; + + /* Tree of UE ordered by MME_ue_m3ap_id's */ + // RB_HEAD(m3ap_ue_map, m3ap_MME_ue_context_s) m3ap_ue_head; + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + /* Displayable name of MME */ + char *MME_name; + + /* Unique MME_id to identify the MME within EPC. + * In our case the MME is a macro MME so the id will be 20 bits long. + * For Home MME id, this field should be 28 bits long. + */ + uint32_t MME_id; + /* The type of the cell */ + cell_type_t cell_type; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* CC params */ + int16_t eutra_band[MAX_NUM_CCs]; + uint32_t downlink_frequency[MAX_NUM_CCs]; + int32_t uplink_frequency_offset[MAX_NUM_CCs]; + uint32_t Nid_cell[MAX_NUM_CCs]; + int16_t N_RB_DL[MAX_NUM_CCs]; + lte_frame_type_t frame_type[MAX_NUM_CCs]; + uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; + uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + int num_cc; + + net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MME_IP_ADDRESS]; + uint8_t nb_m3; + net_ip_address_t mme_m3_ip_address; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + uint32_t mme_port_for_M3C; + int multi_sd; + + m3ap_id_manager id_manager; + m3ap_timers_t timers; +} m3ap_MME_instance_t; + +typedef struct { + /* List of served MMEs + * Only used for virtual mode + */ + STAILQ_HEAD(m3ap_MME_instances_head_s, m3ap_MME_instance_s) m3ap_MME_instances_head; + /* Nb of registered MMEs */ + uint8_t nb_registered_MMEs; + + /* Generate a unique connexion id used between M3AP and SCTP */ + uint16_t global_cnx_id; +} m3ap_MME_internal_data_t; + +int m3ap_MME_compare_assoc_id(struct m3ap_MME_data_s *p1, struct m3ap_MME_data_s *p2); + +/* Generate the tree management functions */ +struct m3ap_MME_map; +struct m3ap_MME_data_s; +RB_PROTOTYPE(m3ap_MME_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id); + + +#endif /* M3AP_MME_DEFS_H_ */ diff --git a/openair3/M3AP/m3ap_MME_generate_messages.c b/openair3/M3AP/m3ap_MME_generate_messages.c new file mode 100644 index 0000000000..a28097cf1a --- /dev/null +++ b/openair3/M3AP/m3ap_MME_generate_messages.c @@ -0,0 +1,804 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_generate_messages.c + * \brief m2ap procedures for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +//#include "M2AP_LastVisitedCell-Item.h" + +#include "m2ap_common.h" +#include "m2ap_MCE.h" +#include "m2ap_MCE_generate_messages.h" +#include "m2ap_encoder.h" +#include "m2ap_decoder.h" +#include "m2ap_ids.h" + +#include "m2ap_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +int m2ap_MCE_generate_m2_setup_request( + m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p) +{ + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupRequest_t *out; + M2AP_M2SetupRequest_Ies_t *ie; + //M2AP_PLMN_Identity_t *plmn; + //ServedCells__Member *servedCellMember; + //M2AP_GU_Group_ID_t *gu; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(m2ap_MCE_data_p != NULL); + + m2ap_MCE_data_p->state = M2AP_MCE_STATE_WAITING; + + /* Prepare the M2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest; + + /* mandatory */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GlobalMCE_ID; + //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &ie->value.choice.GlobalMCE_ID.pLMN_Identity); + //ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID; + //MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id, + // &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID); + //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id, + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_ServedCells; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_ServedCells; + //{ + // for (int i = 0; inum_cc; i++){ + // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); + // { + // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; + + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); + // MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0, + // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); + + // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); + // } + + // if (instance_p->frame_type[i] == FDD) { + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + // switch (instance_p->N_RB_DL[i]) { + // case 6: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // break; + // case 15: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // break; + // case 25: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // break; + // case 50: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // break; + // case 75: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // break; + // case 100: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // break; + // default: + // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + // break; + // } + // } + // else { + // AssertFatal(0,"M2Setuprequest not supported for TDD!"); + // } + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + // } + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GUGroupIDList; + //{ + // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &gu->pLMN_Identity); + // //@TODO: consider to update this value + // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + M2AP_ERROR("Failed to encode M2 setup request\n"); + return -1; + } + + //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); + + m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p) +{ + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupResponse_t *out; + M2AP_M2SetupResponse_Ies_t *ie; + //M2AP_PLMN_Identity_t *plmn; + //ServedCells__Member *servedCellMember; + //M2AP_GU_Group_ID_t *gu; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(m2ap_MCE_data_p != NULL); + + /* Prepare the M2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse; + + /* mandatory */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalMCE_ID; + //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &ie->value.choice.GlobalMCE_ID.pLMN_Identity); + //ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID; + //MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id, + // &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID); + //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id, + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1], + // ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_ServedCells; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells; + //{ + // for (int i = 0; inum_cc; i++){ + // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); + // { + // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; + + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); + // MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0, + // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); + + // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); + // } + + // if (instance_p->frame_type[i] == FDD) { + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + // switch (instance_p->N_RB_DL[i]) { + // case 6: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6; + // break; + // case 15: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15; + // break; + // case 25: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25; + // break; + // case 50: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50; + // break; + // case 75: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75; + // break; + // case 100: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100; + // break; + // default: + // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + // break; + // } + // } + // else { + // AssertFatal(0,"M2Setupresponse not supported for TDD!"); + // } + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + // } + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList; + //ie->criticality = M2AP_Criticality_reject; + //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList; + //{ + // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &gu->pLMN_Identity); + // //@TODO: consider to update this value + // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + M2AP_ERROR("Failed to encode M2 setup response\n"); + return -1; + } + + m2ap_MCE_data_p->state = M2AP_MCE_STATE_READY; + + //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id); + + m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int m2ap_MCE_generate_m2_setup_failure(instance_t instance, + uint32_t assoc_id, + M2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait) +{ + M2AP_M2AP_PDU_t pdu; + M2AP_M2SetupFailure_t *out; + M2AP_M2SetupFailure_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + /* Prepare the M2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup; + pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure; + + /* mandatory */ + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_Cause; + //ie->criticality = M2AP_Criticality_ignore; + //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause; + + //m2ap_MCE_set_cause (&ie->value.choice.Cause, cause_type, cause_value); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional: consider to handle this later */ + ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t)); + //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait; + //ie->criticality = M2AP_Criticality_ignore; + //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait; + + //if (time_to_wait > -1) { + // ie->value.choice.TimeToWait = time_to_wait; + //} + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + M2AP_ERROR("Failed to encode M2 setup failure\n"); + return -1; + } + + //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, + // MSC_M2AP_TARGET_MCE, NULL, 0, + // "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", + // assoc_id, cause_type, cause_value); + + m2ap_MCE_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); + + return ret; +} + +int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value) +{ + + DevAssert (cause_p != NULL); + cause_p->present = cause_type; + + switch (cause_type) { + case M2AP_Cause_PR_radioNetwork: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_transport: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_protocol: + cause_p->choice.misc = cause_value; + break; + + case M2AP_Cause_PR_misc: + cause_p->choice.misc = cause_value; + break; + + default: + return -1; + } + + return 0; +} + +//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequest_t *out; +// M2AP_HandoverRequest_IEs_t *ie; +// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; +// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; +// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause; +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.ECGI.pLMN_Identity); +// MACRO_MCE_ID_TO_CELL_IDENTITY(m2ap_MCE_data_p->MCE_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); +// //@TODO: consider to update these values +// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); +// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; +// //@TODO: consider to update this value +// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id; +// +// KMCE_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); +// +// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc; +// } +// else { +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; +// } +// +// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); +// +// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); +// +// //@TODO: update with proper UEAMPR +// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); +// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t)); +// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; +// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; +// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; +// { +// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length/8); +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length%8; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = +// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, +// m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.buffer, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); +// } +// } +// +// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; +// //@TODO: consider to update this value +// { +// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t)); +// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); +// MACRO_MCE_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); +// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small; +// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover request\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverRequestAcknowledge_t *out; +// M2AP_HandoverRequestAcknowledge_IEs_t *ie; +// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; +// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// ue_id = m2ap_handover_req_ack->m2_id_target; +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; +// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; +// +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t)); +// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; +// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore; +// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; +// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; +// { +// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); +// } +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_TargetMCEtoSource_MCETransparentContainer; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargetMCEtoSource_MCETransparentContainer; +// +// OCTET_STRING_fromBuf(&ie->value.choice.TargetMCEtoSource_MCETransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 handover response\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release) +//{ +// +// M2AP_M2AP_PDU_t pdu; +// M2AP_UEContextRelease_t *out; +// M2AP_UEContextRelease_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti); +// exit(1); +// } +// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M2AP ue context relase message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease; +// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 UE Context Release\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause) +//{ +// M2AP_M2AP_PDU_t pdu; +// M2AP_HandoverCancel_t *out; +// M2AP_HandoverCancel_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m2ap_MCE_data_p != NULL); +// +// ue_id = m2_ue_id; +// id_source = ue_id; +// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id); +// +// /* Prepare the M2AP handover cancel message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel; +// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_reject; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID; +// ie->value.choice.UE_M2AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// if (id_target != -1) { +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1; +// ie->value.choice.UE_M2AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* mandatory */ +// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t)); +// ie->id = M2AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M2AP_Criticality_ignore; +// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause; +// switch (cause) { +// case M2AP_T_RELOC_PREP_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_trelocprep_expiry; +// break; +// case M2AP_TX2_RELOC_OVERALL_TIMEOUT: +// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M2AP_CauseRadioNetwork_tx2relocoverall_expiry; +// break; +// default: +// /* we can't come here */ +// M2AP_ERROR("unhandled cancel cause\n"); +// exit(1); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) { +// M2AP_ERROR("Failed to encode X2 Handover Cancel\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id); +// +// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} diff --git a/openair3/M3AP/m3ap_MME_generate_messages.h b/openair3/M3AP/m3ap_MME_generate_messages.h new file mode 100644 index 0000000000..1632dc807a --- /dev/null +++ b/openair3/M3AP/m3ap_MME_generate_messages.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_MCE_generate_messages.h + * \brief m2ap procedures for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_MCE_GENERATE_MESSAGES_H_ +#define M2AP_MCE_GENERATE_MESSAGES_H_ + +#include "m2ap_MCE_defs.h" +#include "m2ap_common.h" + +int m2ap_MCE_generate_m2_setup_request(m2ap_MCE_instance_t *instance_p, + m2ap_MCE_data_t *m2ap_MCE_data_p); + +int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p); + +int m2ap_MCE_generate_m2_setup_failure(instance_t instance, + uint32_t assoc_id, + M2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait); + +int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p, + M2AP_Cause_PR cause_type, + long cause_value); + +//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_t *m2ap_handover_req, int ue_id); +// +//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_handover_req_ack_t *m2ap_handover_req_ack); +// +//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// m2ap_ue_context_release_t *m2ap_ue_context_release); +// +//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, +// int m2_ue_id, +// m2ap_handover_cancel_cause_t cause); + +#endif /* M2AP_MCE_GENERATE_MESSAGES_H_ */ diff --git a/openair3/M3AP/m3ap_MME_handler.c b/openair3/M3AP/m3ap_MME_handler.c new file mode 100644 index 0000000000..9af8cbe14f --- /dev/null +++ b/openair3/M3AP/m3ap_MME_handler.c @@ -0,0 +1,118 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_handler.c + * \brief m3ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m3ap_common.h" +#include "m3ap_MME_defs.h" +#include "m3ap_handler.h" +#include "m3ap_decoder.h" +#include "m3ap_ids.h" + +#include "m3ap_MME_management_procedures.h" +//#include "m3ap_MCE_generate_messages.h" + +#include "m3ap_MME_interface_management.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +/* Handlers matrix. Only eNB related procedure present here */ +m3ap_MCE_message_decoded_callback m3ap_MME_messages_callback[][3] = { + { 0, MME_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */ + { 0, MME_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */ + { 0, 0, 0 }, /* Error Indication */ + { 0, 0, 0 }, /* Reset */ + { 0, 0, 0 }, /* ??? */ + { 0, MME_handle_MBMS_SESSION_UPDATE_RESPONSE, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { MME_handle_M3_SETUP_REQUEST, 0, 0 } /* M3 Setup */ +}; + +static char *m3ap_direction2String(int m3ap_dir) { +static char *m3ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m3ap_direction_String[m3ap_dir]); +} + + +int m3ap_MME_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + M3AP_M3AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + + if (m3ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(M3AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_MME_messages_callback) / (3 * sizeof( + m3ap_message_decoded_callback)) + || (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m3ap_MME_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m3ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(M3AP, "Calling handler with instance %d\n",instance); + ret = (*m3ap_MME_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return ret; +} + + diff --git a/openair3/M3AP/m3ap_MME_handler.h b/openair3/M3AP/m3ap_MME_handler.h new file mode 100644 index 0000000000..feabfe256c --- /dev/null +++ b/openair3/M3AP/m3ap_MME_handler.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_handler.h + * \brief m3ap handler procedures for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_MME_HANDLERS_H_ +#define M3AP_MME_HANDLERS_H_ + +#include "m3ap_MME_defs.h" + +//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + //const uint8_t * const data, const uint32_t data_length); + +int m3ap_MME_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + + +#endif /* M3AP_MME_HANDLERS_H_ */ diff --git a/openair3/M3AP/m3ap_MME_interface_management.c b/openair3/M3AP/m3ap_MME_interface_management.c new file mode 100644 index 0000000000..e5cb03cf26 --- /dev/null +++ b/openair3/M3AP/m3ap_MME_interface_management.c @@ -0,0 +1,1162 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MME_interface_management.c + * \brief m3ap interface management for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "m3ap_common.h" +#include "m3ap_encoder.h" +#include "m3ap_decoder.h" +#include "m3ap_itti_messaging.h" +#include "m3ap_MME_interface_management.h" + +#include "conversions.h" + +#include "M3AP_ECGI.h" + +extern m3ap_setup_req_t *m3ap_mme_data_from_mce; + + + +uint8_t m3ap_start_message[] = { + 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x07, 0x00, 0x55, 0xf5, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x04, 0x00, 0x0d, 0x60, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x01, + 0x7a, 0x00, 0x05, 0x00, 0x03, 0x07, 0x08, 0x00, + 0x00, 0x06, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, + 0x0e, 0x00, 0xe8, 0x0a, 0x0a, 0x0a, 0x00, 0x0a, + 0xc8, 0x0a, 0xfe, 0x00, 0x00, 0x00, 0x01 +}; + + +/* + * MBMS Session start + */ +int MME_send_MBMS_SESSION_START_REQUEST(instance_t instance/*, uint32_t assoc_id*/,m3ap_session_start_req_t* m3ap_session_start_req){ + + //AssertFatal(1==0,"Not implemented yet\n"); + + //module_id_t enb_mod_idP=0; + //module_id_t du_mod_idP=0; + + M3AP_M3AP_PDU_t pdu; + M3AP_MBMSSessionStartRequest_t *out; + M3AP_MBMSSessionStartRequest_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i=0; + //int j=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M3AP_InitiatingMessage_t *)calloc(1, sizeof(M3AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_mBMSsessionStart; + pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_MBMSSessionStartRequest; + out = &pdu.choice.initiatingMessage.value.choice.MBMSSessionStartRequest; + + /* mandatory */ + /* c1. MME_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MME_MBMS_M3AP_ID; + //ie->value.choice.MME_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. TMGI */ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_TMGI; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_TMGI; + M3AP_TMGI_t *tmgi = &ie->value.choice.TMGI; + { + MCC_MNC_TO_PLMNID(0,0,3,&tmgi->pLMNidentity); + uint8_t TMGI[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(&tmgi->serviceID,(const char*)&TMGI[2],3); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + /* c2. MBMS_Session_ID */ + if(0){ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Session_ID; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MBMS_Session_ID; + //M3AP_MBMS_Session_ID_t * mbms_session_id = &ie->value.choice.MBMS_Session_ID; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* mandatory */ + /* c2. MBMS_E_RAB_QoS_Parameters */ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_E_RAB_QoS_Parameters; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MBMS_E_RAB_QoS_Parameters; + M3AP_MBMS_E_RAB_QoS_Parameters_t * mbms_e_rab_qos_parameters = &ie->value.choice.MBMS_E_RAB_QoS_Parameters; + { + //M3AP_QCI_t * qci = &mbms_e_rab_qos_parameters->qCI; //long + mbms_e_rab_qos_parameters->qCI = 1; + //struct M3AP_GBR_QosInformation *gbrQosInformation; /* OPTIONAL */ + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + /* c2. MBMS_Session_Duration */ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Session_Duration; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MBMS_Session_Duration; + M3AP_MBMS_Session_Duration_t * mbms_session_duration = &ie->value.choice.MBMS_Session_Duration; + { + uint8_t duration[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(mbms_session_duration,(const char*)&duration[2],3); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + /* c2 MBMS_Service_Area */ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Service_Area; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MBMS_Service_Area; + M3AP_MBMS_Service_Area_t * mbms_service_area = &ie->value.choice.MBMS_Service_Area; + { + uint8_t duration[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(mbms_service_area,(const char*)&duration[2],1); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + /* c2 MinimumTimeToMBMSDataTransfer */ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MinimumTimeToMBMSDataTransfer; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MinimumTimeToMBMSDataTransfer; + M3AP_MinimumTimeToMBMSDataTransfer_t * minimumtimetombmsdatatransfer = &ie->value.choice.MinimumTimeToMBMSDataTransfer; + { + uint8_t duration[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(minimumtimetombmsdatatransfer,(const char*)&duration[2],1); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + /* c2 TNL_Information */ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_TNL_Information; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_TNL_Information; + M3AP_TNL_Information_t * tnl_information = &ie->value.choice.TNL_Information; + { + //OCTET_STRING_fromBuf(&tnl_information->iPMCAddress,"1204",strlen("1234")); + //OCTET_STRING_fromBuf(&tnl_information->iPSourceAddress,"1204",strlen("1234")); + //OCTET_STRING_fromBuf(&tnl_information->gTP_DLTEID,"1204",strlen("1234")); + uint32_t gtp_dlteid = 1; + GTP_TEID_TO_ASN1(gtp_dlteid,&tnl_information->gTP_DLTEID); + //tnl_information->iPMCAddress.buf = calloc(4,sizeof(uint8_t)); + //tnl_information->iPMCAddress.buf[0] + //tnl_information->iPMCAddress.buf[1] + //tnl_information->iPMCAddress.buf[2] + //tnl_information->iPMCAddress.buf[3] + //tnl_information->iPMCAddress.buf.size = 4; + uint32_t ip= (224<<24) | (0) << 16 | (0) << 8 | (2); + INT32_TO_OCTET_STRING(ip,&tnl_information->iPMCAddress); + ip= (224<<24) | (0) << 16 | (0) << 8 | (2); + INT32_TO_OCTET_STRING(ip,&tnl_information->iPSourceAddress); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + /* c2 Time_ofMBMS_DataTransfer */ + if(0){ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_Time_ofMBMS_DataTransfer; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_Absolute_Time_ofMBMS_Data; + //M3AP_Absolute_Time_ofMBMS_Data_t * absolute_time_ofmbms_data = &ie->value.choice.Absolute_Time_ofMBMS_Data; + //{ + //char duration[5] = {4,3,2,1,0}; + //OCTET_STRING_fromBuf(absolute_time_ofmbms_data,(const char*)&duration[2],3); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* optional */ + /* c2 MBMS_Cell_List */ + if(0){ + ie = (M3AP_MBMSSessionStartRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStartRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Cell_List; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionStartRequest_IEs__value_PR_MBMS_Cell_List; + M3AP_MBMS_Cell_List_t * mbms_cell_list = &ie->value.choice.MBMS_Cell_List; + M3AP_ECGI_t * ecgi = (M3AP_ECGI_t*)calloc(1,sizeof(M3AP_ECGI_t)); + { + //MCC_MNC_TO_PLMNID(0,0,3,ecgi->pLMN_Identity); + //MACRO_ENB_ID_TO_CELL_IDENTITY(1,0,ecgi->eUTRANcellIdentifier); + ASN_SEQUENCE_ADD(&mbms_cell_list->list,ecgi); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (m3ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + } + + +// buffer = &m3ap_start_message[0]; +// len=8*9+7; +// + m3ap_MME_itti_send_sctp_data_req(instance, m3ap_mme_data_from_mce->assoc_id, buffer, len, 0); + + return 0; + +} + +int MME_handle_MBMS_SESSION_START_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ +// AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M3AP, "MME_handle_MBMS_SESSION_START_RESPONSE\n"); + + AssertFatal(pdu->present == M3AP_M3AP_PDU_PR_successfulOutcome, + "pdu->present != M3AP_M3AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M3AP_ProcedureCode_id_mBMSsessionStart, + "pdu->choice.successfulOutcome->procedureCode != M3AP_ProcedureCode_id_sessionStart\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M3AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M3AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M3AP_SuccessfulOutcome__value_PR_MBMSSessionStartResponse, + "pdu->choice.successfulOutcome.value.present != M3AP_SuccessfulOutcome__value_PR_MBMSSessionStartResponse\n"); + + + M3AP_MBMSSessionStartResponse_t *in = &pdu->choice.successfulOutcome.value.choice.MBMSSessionStartResponse; + M3AP_MBMSSessionStartResponse_IEs_t *ie; + int MME_MBMS_M3AP_ID=-1; + int MCE_MBMS_M3AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_START_RESP); //TODO + + LOG_D(M3AP, "M3AP: SessionStart-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID: + AssertFatal(ie->criticality == M3AP_Criticality_reject, + "ie->criticality != M3AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M3AP_MBMSSessionStartResponse_IEs__value_PR_MME_MBMS_M3AP_ID, + "ie->value.present != M3AP_sessionStartResponse_IEs__value_PR_MME_MBMS_M3AP_ID\n"); + MME_MBMS_M3AP_ID=ie->value.choice.MME_MBMS_M3AP_ID; + LOG_D(M3AP, "M3AP: SessionStart-Resp: MME_MBMS_M3AP_ID %d\n", + MME_MBMS_M3AP_ID); + break; + case M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID: + AssertFatal(ie->criticality == M3AP_Criticality_reject, + "ie->criticality != M3AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M3AP_MBMSSessionStartResponse_IEs__value_PR_MCE_MBMS_M3AP_ID, + "ie->value.present != M3AP_sessionStartResponse_IEs__value_PR_MCE_MBMS_M3AP_ID\n"); + MCE_MBMS_M3AP_ID=ie->value.choice.MCE_MBMS_M3AP_ID; + LOG_D(M3AP, "M3AP: SessionStart-Resp: MCE_MBMS_M3AP_ID %d\n", + MCE_MBMS_M3AP_ID); + break; + } + } + + //AssertFatal(MME_MBMS_M3AP_ID!=-1,"MME_MBMS_M3AP_ID was not sent\n"); + //AssertFatal(MCE_MBMS_M3AP_ID!=-1,"MCE_MBMS_M3AP_ID was not sent\n"); + ////M3AP_SESSION_START_RESP(msg_p). +//// MSC_LOG_RX_MESSAGE( +//// MSC_M3AP_MME, +//// MSC_M3AP_MCE, + // //return 0; +//// 0, +//// 0, +//// MSC_AS_TIME_FMT" MME_handle_M2_SESSION_START_RESPONSE successfulOutcome assoc_id %d", +//// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +//// assoc_id); +//// + // LOG_W(M3AP, "Sending M3AP_SESSION_START_RESP ITTI message to MCE_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g); + return 0; + +} +int MME_handle_MBMS_SESSION_START_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + +/* + * MBMS Session stop + */ +int MME_send_MBMS_SESSION_STOP_REQUEST(instance_t instance, m3ap_session_stop_req_t* m3ap_session_stop_req){ + + + // module_id_t enb_mod_idP=0; + // module_id_t du_mod_idP=0; + + M3AP_M3AP_PDU_t pdu; + M3AP_MBMSSessionStopRequest_t *out; + M3AP_MBMSSessionStopRequest_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i=0; + //int j=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M3AP_InitiatingMessage_t *)calloc(1, sizeof(M3AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_mBMSsessionStop; + pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_MBMSSessionStopRequest; + out = &pdu.choice.initiatingMessage.value.choice.MBMSSessionStopRequest; + + /* mandatory */ + /* c1. MME_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStopRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStopRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStopRequest_IEs__value_PR_MME_MBMS_M3AP_ID; + //ie->value.choice.MME_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionStopRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionStopRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionStopRequest_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* encode */ + if (m3ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + } + + //MME_m3ap_itti_send_sctp_data_req(instance, m3ap_mce_data_from_mce->assoid,buffer,len,0); + m3ap_MME_itti_send_sctp_data_req(instance, m3ap_mme_data_from_mce->assoc_id,buffer,len,0); + return 0; + + + +} + +int MME_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M3AP, "eNB_handle_MBMS_SESSION_STOP_RESPONSE\n"); + + AssertFatal(pdu->present == M3AP_M3AP_PDU_PR_successfulOutcome, + "pdu->present != M3AP_M3AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M3AP_ProcedureCode_id_mBMSsessionStop, + "pdu->choice.successfulOutcome->procedureCode != M3AP_ProcedureCode_id_sessionStop\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M3AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M3AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M3AP_SuccessfulOutcome__value_PR_MBMSSessionStopResponse, + "pdu->choice.successfulOutcome->value.present != M3AP_SuccessfulOutcome__value_PR_MBMSSessionStopResponse\n"); + + + M3AP_MBMSSessionStopResponse_t *in = &pdu->choice.successfulOutcome.value.choice.MBMSSessionStopResponse; + M3AP_MBMSSessionStopResponse_IEs_t *ie; + int MME_MBMS_M3AP_ID=-1; + int MCE_MBMS_M3AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_STOP_RESP); //TODO + + LOG_D(M3AP, "M3AP: MBMSSessionStop-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID: + AssertFatal(ie->criticality == M3AP_Criticality_reject, + "ie->criticality != M3AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M3AP_MBMSSessionStopResponse_IEs__value_PR_MME_MBMS_M3AP_ID, + "ie->value.present != M3AP_MBMSStopResponse_IEs__value_PR_MME_MBMS_M3AP_ID\n"); + MME_MBMS_M3AP_ID=ie->value.choice.MME_MBMS_M3AP_ID; + LOG_D(M3AP, "M3AP: MBMSSessionStop-Resp: MME_MBMS_M3AP_ID %d\n", + MME_MBMS_M3AP_ID); + break; + case M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID: + AssertFatal(ie->criticality == M3AP_Criticality_reject, + "ie->criticality != M3AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M3AP_MBMSSessionStopResponse_IEs__value_PR_MCE_MBMS_M3AP_ID, + "ie->value.present != M3AP_MBMSStopResponse_IEs__value_PR_MCE_MBMS_M3AP_ID\n"); + MCE_MBMS_M3AP_ID=ie->value.choice.MCE_MBMS_M3AP_ID; + LOG_D(M3AP, "M3AP: MBMSSessionStop-Resp: MCE_MBMS_M3AP_ID %d\n", + MCE_MBMS_M3AP_ID); + break; + } + } + + //AssertFatal(MME_MBMS_M3AP_ID!=-1,"MME_MBMS_M3AP_ID was not sent\n"); + //AssertFatal(MCE_MBMS_M3AP_ID!=-1,"MCE_MBMS_M3AP_ID was not sent\n"); + // M3AP_SESSION_STOP_RESP(msg_p). + // MSC_LOG_RX_MESSAGE( + // MSC_M3AP_MME, + // MSC_M3AP_MCE, + // 0, + // 0, + // MSC_AS_TIME_FMT" MME_handle_M2_SESSION_STOP_RESPONSE successfulOutcome assoc_id %d", + // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + // assoc_id); + + // LOG_D(M3AP, "Sending M3AP_SESSION_START_RESP ITTI message to MCE_APP with assoc_id (%d->%d)\n", + // assoc_id,MCE_MODULE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g); +// // + return 0; +} + + + +int MME_handle_MBMS_SESSION_STOP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + + + + +/* + * Reset + */ + +int MME_send_RESET(instance_t instance, m3ap_reset_t * m3ap_reset) { + AssertFatal(1==0,"Not implemented yet\n"); + //M3AP_Reset_t Reset; + +} + + +int MME_handle_RESET_ACKKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); + +} + +int MME_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int MME_send_RESET_ACKNOWLEDGE(instance_t instance, M3AP_ResetAcknowledge_t *ResetAcknowledge) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +/* + * M3 Setup + */ +int MME_handle_M3_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) +{ + LOG_D(M2AP, "MCE_handle_M3_SETUP_REQUEST assoc_id %d\n",assoc_id); + + //AssertFatal(1==0,"Not implemented yet\n"); +// LOG_W(M3AP, "MME_handle_M3_SETUP_REQUEST assoc_id %d\n",assoc_id); +// + MessageDef *message_p; +// M3AP_M3SetupRequest_t *container; +// M3AP_M3SetupRequestIEs_t *ie; +// int i = 0,j=0; +// +// DevAssert(pdu != NULL); +// +// container = &pdu->choice.initiatingMessage.value.choice.M3SetupRequest; +// +// /* M3 Setup Request == Non UE-related procedure -> stream 0 */ +// if (stream != 0) { +// LOG_W(M3AP, "[SCTP %d] Received m3 setup request on stream != 0 (%d)\n", +// assoc_id, stream); +// } +// + message_p = itti_alloc_new_message(TASK_M3AP_MME, M3AP_SETUP_REQ); + //printf("M3AP_SETUP_REQ(message_p).assoc_id %d\n",M3AP_SETUP_REQ(message_p).assoc_id); +// +// /* assoc_id */ + M3AP_SETUP_REQ(message_p).assoc_id = assoc_id; +// +// /* GlobalMCE_id */ +// // this function exits if the ie is mandatory +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequestIEs_t, ie, container, +// M3AP_ProtocolIE_ID_id_Global_MCE_ID, true); +// asn_INTEGER2ulong(&ie->value.choice.GlobalMCE_ID, &M3AP_SETUP_REQ(message_p).GlobalMCE_ID); +// LOG_W(M3AP, "M3AP_SETUP_REQ(message_p).GlobalMCE_ID %lu \n", M3AP_SETUP_REQ(message_p).GlobalMCE_ID); +// +// /* MCE_name */ +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequestIEs_t, ie, container, +// M3AP_ProtocolIE_ID_id_MCEname, true); +// M3AP_SETUP_REQ(message_p).MCEname = calloc(ie->value.choice.MCEname.size + 1, sizeof(char)); +// memcpy(M3AP_SETUP_REQ(message_p).MCEname, ie->value.choice.MCEname.buf, +// ie->value.choice.MCEname.size); +// +// /* Convert the mme name to a printable string */ +// M3AP_SETUP_REQ(message_p).MCEname[ie->value.choice.MCEname.size] = '\0'; +// LOG_W(M3AP, "M3AP_SETUP_REQ(message_p).gNB_DU_name %s \n", M3AP_SETUP_REQ(message_p).MCEname); +// /* MCE_MBMS_Configuration_data_List */ +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequestIEs_t, ie, container, +// M3AP_ProtocolIE_ID_id_MCE_MBMS_Configuration_data_List, true); +// M3AP_SETUP_REQ(message_p).num_mbms_available = ie->value.choice.MCE_MBMS_Configuration_data_List.list.count; +// LOG_W(M3AP, "M3AP_SETUP_REQ(message_p).num_mbms_available %d \n", +// M3AP_SETUP_REQ(message_p).num_mbms_available); +// int num_mbms_available = M3AP_SETUP_REQ(message_p).num_mbms_available; +// for (i=0; ivalue.choice.MCE_MBMS_Configuration_data_List.list.array[i])->value.choice.MCE_MBMS_Configuration_data_Item); +// /* eCGI */ +// //mbms_configuration_item_p->eCGI ... (M3AP_ECGI_t) +// +// OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.pLMN_Identity),M3AP_SETUP_REQ(message_p).plmn_identity[i]); +// //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.eUTRANcellIdentifier),M3AP_SETUP_REQ(message_p).eutran_cell_identifier[i]); +// /* mbsfnSynchronisationArea */ +// //mbms_configuration_item_p->mbsfnSynchronisationArea ... (M3AP_MBSFN_SynchronisationArea_ID_t) +// +// M3AP_SETUP_REQ(message_p).mbsfn_synchronization_area[i]=mbms_configuration_item_p->mbsfnSynchronisationArea; +// /* mbmsServiceAreaList */ +// //mbms_configuration_item_p->mbmsServiceAreaList ... (M3AP_MBMS_Service_Area_ID_List_t) +// for(j=0;j<1;j++){ +// //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->mbmsServiceAreaList.list.array[j]), M3AP_SETUP_REQ(message_p).service_area_id[i][j]); +// } +// +// } +// +//// /* tac */ +//// OCTET_STRING_TO_INT16(&(served_celles_item_p->served_Cell_Information.fiveGS_TAC), M3AP_SETUP_REQ(message_p).tac[i]); +//// LOG_D(M3AP, "M3AP_SETUP_REQ(message_p).tac[%d] %d \n", +//// i, M3AP_SETUP_REQ(message_p).tac[i]); +//// +//// /* - nRCGI */ +//// TBCD_TO_MCC_MNC(&(served_celles_item_p->served_Cell_Information.nRCGI.pLMN_Identity), M3AP_SETUP_REQ(message_p).mcc[i], +//// M3AP_SETUP_REQ(message_p).mnc[i], +//// M3AP_SETUP_REQ(message_p).mnc_digit_length[i]); +//// +//// +//// // NR cellID +//// BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity, +//// M3AP_SETUP_REQ(message_p).nr_cellid[i]); +//// LOG_D(M3AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id, +//// M3AP_SETUP_REQ(message_p).mcc[i], +//// M3AP_SETUP_REQ(message_p).mnc[i], +//// (long long unsigned int)M3AP_SETUP_REQ(message_p).nr_cellid[i]); +//// LOG_D(M3AP, "nr_cellId : %x %x %x %x %x\n", +//// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0], +//// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1], +//// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2], +//// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3], +//// served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]); +//// /* - nRPCI */ +//// M3AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI; +//// LOG_D(M3AP, "M3AP_SETUP_REQ(message_p).nr_pci[%d] %d \n", +//// i, M3AP_SETUP_REQ(message_p).nr_pci[i]); +//// +//// // System Information +//// /* mib */ +//// M3AP_SETUP_REQ(message_p).mib[i] = calloc(served_celles_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char)); +//// memcpy(M3AP_SETUP_REQ(message_p).mib[i], served_celles_item_p->gNB_DU_System_Information->mIB_message.buf, +//// served_celles_item_p->gNB_DU_System_Information->mIB_message.size); +//// /* Convert the mme name to a printable string */ +//// M3AP_SETUP_REQ(message_p).mib[i][served_celles_item_p->gNB_DU_System_Information->mIB_message.size] = '\0'; +//// M3AP_SETUP_REQ(message_p).mib_length[i] = served_celles_item_p->gNB_DU_System_Information->mIB_message.size; +//// LOG_D(M3AP, "M3AP_SETUP_REQ(message_p).mib[%d] %s , len = %d \n", +//// i, M3AP_SETUP_REQ(message_p).mib[i], M3AP_SETUP_REQ(message_p).mib_length[i]); +//// +//// /* sib1 */ +//// M3AP_SETUP_REQ(message_p).sib1[i] = calloc(served_celles_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char)); +//// memcpy(M3AP_SETUP_REQ(message_p).sib1[i], served_celles_item_p->gNB_DU_System_Information->sIB1_message.buf, +//// served_celles_item_p->gNB_DU_System_Information->sIB1_message.size); +//// /* Convert the mme name to a printable string */ +//// M3AP_SETUP_REQ(message_p).sib1[i][served_celles_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0'; +//// M3AP_SETUP_REQ(message_p).sib1_length[i] = served_celles_item_p->gNB_DU_System_Information->sIB1_message.size; +//// LOG_D(M3AP, "M3AP_SETUP_REQ(message_p).sib1[%d] %s , len = %d \n", +//// i, M3AP_SETUP_REQ(message_p).sib1[i], M3AP_SETUP_REQ(message_p).sib1_length[i]); +//// } +// +// + //printf("m3ap_mme_data_from_mce->assoc_id %d %d\n",m3ap_mme_data_from_mce->assoc_id,assoc_id); + *m3ap_mme_data_from_mce = M3AP_SETUP_REQ(message_p); + //printf("m3ap_mme_data_from_mce->assoc_id %d %d\n",m3ap_mme_data_from_mce->assoc_id,assoc_id); +// +//// MSC_LOG_TX_MESSAGE( +//// MSC_M3AP_MME, +//// MSC_RRC_MCE, +//// 0, +//// 0, +//// MSC_AS_TIME_FMT" MME_handle_M3_SETUP_REQUEST", +//// 0,0//MSC_AS_TIME_ARGS(ctxt_pP), +//// ); +//// + itti_send_msg_to_task(TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); +// if (num_mbms_available > 0) { +// itti_send_msg_to_task(TASK_MME_APP, MCE_MODULE_ID_TO_INSTANCE(instance), message_p); +// } else { +// //MME_send_M3_SETUP_FAILURE(instance); +// return -1; +// } +//// return 0; +// //TEST POINT MME -> eNB +// if(1){ +// printf("instance %d\n",instance); +// //MME_send_M3_SETUP_RESPONSE(instance,assoc_id,m3ap_mce_data_from_enb->assoc_id); +// //MME_send_MBMS_SESSION_START_REQUEST(instance,assoc_id); +// //MME_send_MBMS_SESSION_STOP_REQUEST(instance,assoc_id); +// //MME_send_MBMS_SCHEDULING_INFORMATION(instance,assoc_id,NULL); //TODO +// } +// else +// MME_send_M3_SETUP_FAILURE(instance,assoc_id); +// + return 0; +} + +int MME_send_M3_SETUP_RESPONSE(instance_t instance, /*uint32_t assoc_id,*/ + m3ap_setup_resp_t *m3ap_setup_resp) { + M3AP_M3AP_PDU_t pdu; + M3AP_M3SetupResponse_t *out; + M3AP_M3SetupResponseIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M3AP_SuccessfulOutcome_t *)calloc(1, sizeof(M3AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_m3Setup; + pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_M3SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.M3SetupResponse; + + /* mandatory */ + /* c4. CriticalityDiagnostics*/ + if (0) { + ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_M3SetupFailureIEs__value_PR_CriticalityDiagnostics; + ie->value.choice.CriticalityDiagnostics.procedureCode = (M3AP_ProcedureCode_t *)calloc(1, sizeof(M3AP_ProcedureCode_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCode = M3AP_ProcedureCode_id_m3Setup; + ie->value.choice.CriticalityDiagnostics.triggeringMessage = (M3AP_TriggeringMessage_t *)calloc(1, sizeof(M3AP_TriggeringMessage_t)); + *ie->value.choice.CriticalityDiagnostics.triggeringMessage = M3AP_TriggeringMessage_initiating_message; + ie->value.choice.CriticalityDiagnostics.procedureCriticality = (M3AP_Criticality_t *)calloc(1, sizeof(M3AP_Criticality_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCriticality = M3AP_Criticality_reject; + //ie->value.choice.CriticalityDiagnostics.transactionID = (M2AP_TransactionID_t *)calloc(1, sizeof(M3AP_TransactionID_t)); + //*ie->value.choice.CriticalityDiagnostics.transactionID = 0; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M3AP, "Failed to encode M3 response\n"); + return -1; + } + + //printf(",m3ap_mme_data_from_mce->assoc_id %d\n",m3ap_mme_data_from_mce->assoc_id); + + m3ap_MME_itti_send_sctp_data_req(instance,m3ap_mme_data_from_mce->assoc_id,buffer,len,0); + + return 0; +} + +int MME_send_M3_SETUP_FAILURE(instance_t instance,m3ap_setup_failure_t* m3ap_setup_failure) { + AssertFatal(1==0,"Not implemented yet\n"); + +// module_id_t enb_mod_idP; +// module_id_t mce_mod_idP; +// +// // This should be fixed +// enb_mod_idP = (module_id_t)0; +// mce_mod_idP = (module_id_t)0; +// +// M3AP_M3AP_PDU_t pdu; +// M3AP_M3SetupFailure_t *out; +// M3AP_M3SetupFailureIEs_t *ie; +// +// uint8_t *buffer; +// uint32_t len; +// +// /* Create */ +// /* 0. Message Type */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome; +// //pdu.choice.unsuccessfulOutcome = (M3AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(M3AP_UnsuccessfulOutcome_t)); +// pdu.choice.unsuccessfulOutcome.procedureCode = M3AP_ProcedureCode_id_m3Setup; +// pdu.choice.unsuccessfulOutcome.criticality = M3AP_Criticality_reject; +// pdu.choice.unsuccessfulOutcome.value.present = M3AP_UnsuccessfulOutcome__value_PR_M2SetupFailure; +// out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure; +// +// /* mandatory */ +// /* c1. Transaction ID (integer value)*/ +// // ie = (M3AP_M3SetupFailure_Ies_t *)calloc(1, sizeof(M3AP_M3SetupFailure_Ies_t)); +// // ie->id = M3AP_ProtocolIE_ID_id_GlobalMCE_ID; +// // ie->criticality = M3AP_Criticality_reject; +// // ie->value.present = M3AP_M3SetupFailure_Ies__value_PR_GlobalMCE_ID; +// // ie->value.choice.GlobalMCE_ID = M3AP_get_next_transaction_identifier(enb_mod_idP, mce_mod_idP); +// // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// /* c2. Cause */ +// ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_M3SetupFailure_Ies__value_PR_Cause; +// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M3AP_CauseRadioNetwork_unspecified; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// /* c3. TimeToWait */ +// if (0) { +// ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_TimeToWait; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_M3SetupFailure_Ies__value_PR_TimeToWait; +// ie->value.choice.TimeToWait = M3AP_TimeToWait_v10s; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* optional */ +// /* c4. CriticalityDiagnostics*/ +// if (0) { +// ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_CriticalityDiagnostics; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_M3SetupFailure_Ies__value_PR_CriticalityDiagnostics; +// ie->value.choice.CriticalityDiagnostics.procedureCode = (M3AP_ProcedureCode_t *)calloc(1, sizeof(M3AP_ProcedureCode_t)); +// *ie->value.choice.CriticalityDiagnostics.procedureCode = M3AP_ProcedureCode_id_m3Setup; +// ie->value.choice.CriticalityDiagnostics.triggeringMessage = (M3AP_TriggeringMessage_t *)calloc(1, sizeof(M3AP_TriggeringMessage_t)); +// *ie->value.choice.CriticalityDiagnostics.triggeringMessage = M3AP_TriggeringMessage_initiating_message; +// ie->value.choice.CriticalityDiagnostics.procedureCriticality = (M3AP_Criticality_t *)calloc(1, sizeof(M3AP_Criticality_t)); +// *ie->value.choice.CriticalityDiagnostics.procedureCriticality = M3AP_Criticality_reject; +// //ie->value.choice.CriticalityDiagnostics.transactionID = (M3AP_TransactionID_t *)calloc(1, sizeof(M3AP_TransactionID_t)); +// //*ie->value.choice.CriticalityDiagnostics.transactionID = 0; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* encode */ +// if (m3ap_encode_pdu(&pdu, &buffer, &len) < 0) { +// LOG_E(M3AP, "Failed to encode M2 setup request\n"); +// return -1; +// } +// +// //mce_m3ap_itti_send_sctp_data_req(instance, m3ap_mce_data_from_enb->assoc_id, buffer, len, 0); +// m3ap_MME_itti_send_sctp_data_req(instance,m3ap_mme_data_from_mce->assoc_id,buffer,len,0); + + return 0; +} + +/* + * MME Configuration Update + */ + + +int MME_handle_MME_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + + +int MME_handle_MME_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + + +/* + * MCE Configuration Update + */ + + +int MME_handle_MCE_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + + + + + + +/* + * Error Indication + */ + +int MME_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); + + +} + +int MME_send_ERROR_INDICATION(instance_t instance, M3AP_ErrorIndication_t *ErrorIndication) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + + + +/* + * Session Update Request + */ +int MME_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m3ap_mbms_session_update_req_t * m3ap_mbms_session_update_req){ + M3AP_M3AP_PDU_t pdu; + M3AP_MBMSSessionUpdateRequest_t *out; + M3AP_MBMSSessionUpdateRequest_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i=0; + //int j=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M3AP_InitiatingMessage_t *)calloc(1, sizeof(M3AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_mBMSsessionUpdate; + pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_MBMSSessionUpdateRequest; + out = &pdu.choice.initiatingMessage.value.choice.MBMSSessionUpdateRequest; + + /* mandatory */ + /* c1. MME_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MME_MBMS_M3AP_ID; + //ie->value.choice.MME_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. MCE_MBMS_M3AP_ID (integer value) */ //long + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MCE_MBMS_M3AP_ID; + //ie->value.choice.MCE_MBMS_M3AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. TMGI */ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_TMGI; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_TMGI; + M3AP_TMGI_t *tmgi = &ie->value.choice.TMGI; + { + MCC_MNC_TO_PLMNID(0,0,3,&tmgi->pLMNidentity); + uint8_t TMGI[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(&tmgi->serviceID,(const char*)&TMGI[2],3); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + /* c2. MBMS_Session_ID */ + if(0){ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Session_ID; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MBMS_Session_ID; + //M3AP_MBMS_Session_ID_t * mbms_session_id = &ie->value.choice.MBMS_Session_ID; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* mandatory */ + /* c2. MBMS_E_RAB_QoS_Parameters */ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_E_RAB_QoS_Parameters; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MBMS_E_RAB_QoS_Parameters; + M3AP_MBMS_E_RAB_QoS_Parameters_t * mbms_e_rab_qos_parameters = &ie->value.choice.MBMS_E_RAB_QoS_Parameters; + { + //M3AP_QCI_t * qci = &mbms_e_rab_qos_parameters->qCI; //long + mbms_e_rab_qos_parameters->qCI=1; + //struct M3AP_GBR_QosInformation *gbrQosInformation; /* OPTIONAL */ + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + /* c2. MBMS_Session_Duration */ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Session_Duration; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MBMS_Session_Duration; + M3AP_MBMS_Session_Duration_t * mbms_session_duration = &ie->value.choice.MBMS_Session_Duration; + { + uint8_t duration[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(mbms_session_duration,(const char*)&duration[2],3); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + /* c2 MBMS_Service_Area */ + if(0){ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Service_Area; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MBMS_Service_Area; + //M3AP_MBMS_Service_Area_t * mbms_service_area = &ie->value.choice.MBMS_Service_Area; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* mandatory */ + /* c2 MinimumTimeToMBMSDataTransfer */ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MinimumTimeToMBMSDataTransfer; + ie->criticality = M3AP_Criticality_reject; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MinimumTimeToMBMSDataTransfer; + M3AP_MinimumTimeToMBMSDataTransfer_t * minimumtimetombmsdatatransfer = &ie->value.choice.MinimumTimeToMBMSDataTransfer; + { + uint8_t duration[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(minimumtimetombmsdatatransfer,(const char*)&duration[2],1); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + /* c2 TNL_Information */ + if(0){ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_TNL_Information; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_TNL_Information; + M3AP_TNL_Information_t * tnl_information = &ie->value.choice.TNL_Information; + { + OCTET_STRING_fromBuf(&tnl_information->iPMCAddress,"1204",strlen("1234")); + OCTET_STRING_fromBuf(&tnl_information->iPSourceAddress,"1204",strlen("1234")); + OCTET_STRING_fromBuf(&tnl_information->gTP_DLTEID,"1204",strlen("1234")); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* optional */ + /* c2 Time_ofMBMS_DataTransfer */ + if(0){ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_Time_ofMBMS_DataTransfer; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_Absolute_Time_ofMBMS_Data; + //M3AP_Absolute_Time_ofMBMS_Data_t * absolute_time_ofmbms_data = &ie->value.choice.Absolute_Time_ofMBMS_Data; + //{ + //char duration[5] = {4,3,2,1,0}; + //OCTET_STRING_fromBuf(absolute_time_ofmbms_data,(const char*)&duration[2],3); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* optional */ + /* c2 MBMS_Cell_List */ + if(0){ + ie = (M3AP_MBMSSessionUpdateRequest_IEs_t *)calloc(1, sizeof(M3AP_MBMSSessionUpdateRequest_IEs_t)); + ie->id = M3AP_ProtocolIE_ID_id_MBMS_Cell_List; + ie->criticality = M3AP_Criticality_ignore; + ie->value.present = M3AP_MBMSSessionUpdateRequest_IEs__value_PR_MBMS_Cell_List; + M3AP_MBMS_Cell_List_t * mbms_cell_list = &ie->value.choice.MBMS_Cell_List; + M3AP_ECGI_t * ecgi = (M3AP_ECGI_t*)calloc(1,sizeof(M3AP_ECGI_t)); + { + //MCC_MNC_TO_PLMNID(0,0,3,ecgi->pLMN_Identity); + //MACRO_ENB_ID_TO_CELL_IDENTITY(1,0,ecgi->eUTRANcellIdentifier); + ASN_SEQUENCE_ADD(&mbms_cell_list->list,ecgi); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (m3ap_encode_pdu(&pdu,&buffer,&len) < 0){ + return -1; + } + + //MME_m3ap_itti_send_sctp_data_req(instance, m3ap_mce_data_from_mce->assoid,buffer,len,0); + m3ap_MME_itti_send_sctp_data_req(instance, m3ap_mme_data_from_mce->assoc_id,buffer,len,0); + return 0; + + + +} + + + +int MME_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M3AP, "MME_handle_MBMS_SESSION_UPDATE_RESPONSE\n"); + + AssertFatal(pdu->present == M3AP_M3AP_PDU_PR_successfulOutcome, + "pdu->present != M3AP_M3AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M3AP_ProcedureCode_id_mBMSsessionUpdate, + "pdu->choice.successfulOutcome->procedureCode != M3AP_ProcedureCode_id_sessionUpdate\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M3AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M3AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M3AP_SuccessfulOutcome__value_PR_MBMSSessionUpdateResponse, + "pdu->choice.successfulOutcome.value.present != M3AP_SuccessfulOutcome__value_PR_MBMSSessionUpdateResponse\n"); + + + M3AP_MBMSSessionUpdateResponse_t *in = &pdu->choice.successfulOutcome.value.choice.MBMSSessionUpdateResponse; + M3AP_MBMSSessionUpdateResponse_IEs_t *ie; + int MME_MBMS_M3AP_ID=-1; + int MCE_MBMS_M3AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_UPDATE_RESP); //TODO + + LOG_D(M3AP, "M3AP: SessionUpdate-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case M3AP_ProtocolIE_ID_id_MME_MBMS_M3AP_ID: + AssertFatal(ie->criticality == M3AP_Criticality_reject, + "ie->criticality != M3AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M3AP_MBMSSessionUpdateResponse_IEs__value_PR_MME_MBMS_M3AP_ID, + "ie->value.present != M3AP_sessionUpdateResponse_IEs__value_PR_MME_MBMS_M3AP_ID\n"); + MME_MBMS_M3AP_ID=ie->value.choice.MME_MBMS_M3AP_ID; + LOG_D(M3AP, "M3AP: SessionUpdate-Resp: MME_MBMS_M3AP_ID %d\n", + MME_MBMS_M3AP_ID); + break; + case M3AP_ProtocolIE_ID_id_MCE_MBMS_M3AP_ID: + AssertFatal(ie->criticality == M3AP_Criticality_reject, + "ie->criticality != M3AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M3AP_MBMSSessionUpdateResponse_IEs__value_PR_MCE_MBMS_M3AP_ID, + "ie->value.present != M3AP_sessionUpdateResponse_IEs__value_PR_MCE_MBMS_M3AP_ID\n"); + MCE_MBMS_M3AP_ID=ie->value.choice.MCE_MBMS_M3AP_ID; + LOG_D(M3AP, "M3AP: SessionUpdate-Resp: MCE_MBMS_M3AP_ID %d\n", + MCE_MBMS_M3AP_ID); + break; + } + } + + //AssertFatal(MME_MBMS_M3AP_ID!=-1,"MME_MBMS_M3AP_ID was not sent\n"); + //AssertFatal(MCE_MBMS_M3AP_ID!=-1,"MCE_MBMS_M3AP_ID was not sent\n"); + ////M3AP_SESSION_START_RESP(msg_p). +//// MSC_LOG_RX_MESSAGE( +//// MSC_M3AP_MME, +//// MSC_M3AP_MCE, + // //return 0; +//// 0, +//// 0, +//// MSC_AS_TIME_FMT" MME_handle_M2_SESSION_START_RESPONSE successfulOutcome assoc_id %d", +//// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +//// assoc_id); +//// + // LOG_W(M3AP, "Sending M3AP_SESSION_START_RESP ITTI message to MCE_APP with assoc_id (%d->%d)\n", + // assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g); + + return 0; + +} + + + +int MME_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + + + +int MME_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); +} + + + +int MME_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + +/* + * Service Counting Results Report + */ + +int MME_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + +/* + * Overload Notification + */ +int MME_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu){ + AssertFatal(1==0,"Not implemented yet\n"); + +} + + + + diff --git a/openair3/M3AP/m3ap_MME_interface_management.h b/openair3/M3AP/m3ap_MME_interface_management.h new file mode 100644 index 0000000000..d3765182ce --- /dev/null +++ b/openair3/M3AP/m3ap_MME_interface_management.h @@ -0,0 +1,111 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MME_interface_management.h + * \brief m3ap interface management for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#ifndef M3AP_MME_INTERFACE_MANAGEMENT_H_ +#define M3AP_MME_INTERFACE_MANAGEMENT_H_ +/* + * MBMS Session start + */ +int MME_send_MBMS_SESSION_START_REQUEST(instance_t instance/*, + uint32_t assoc_id*/,m3ap_session_start_req_t* m3ap_session_start_req); +int MME_handle_MBMS_SESSION_START_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +int MME_handle_MBMS_SESSION_START_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +/* + * MBMS Session stop + */ +int MME_send_MBMS_SESSION_STOP_REQUEST(instance_t instance, + m3ap_session_stop_req_t* m3ap_session_stop_req); + +int MME_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +/* + * Update + */ +int MME_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +int MME_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + + + +/* + * Reset + */ +int MME_send_RESET(instance_t instance, m3ap_reset_t * m3ap_reset); + +int MME_handle_RESET_ACKKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +int MME_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +int MME_send_RESET_ACKNOWLEDGE(instance_t instance, M3AP_ResetAcknowledge_t *ResetAcknowledge); + +/* + * M3AP Setup + */ +int MME_handle_M3_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); + +int MME_send_M3_SETUP_RESPONSE(instance_t instance,/*uint32_t assoc_id,*/ m3ap_setup_resp_t *m3ap_setup_resp); + +int MME_send_M3_SETUP_FAILURE(instance_t instance, /*uint32_t assoc_id*/ m3ap_setup_failure_t * m3ap_setup_failure); + + + + + + +#endif /* M3AP_MME_INTERFACE_MANAGEMENT_H_ */ + + + diff --git a/openair3/M3AP/m3ap_MME_management_procedures.c b/openair3/M3AP/m3ap_MME_management_procedures.c new file mode 100644 index 0000000000..11d2924249 --- /dev/null +++ b/openair3/M3AP/m3ap_MME_management_procedures.c @@ -0,0 +1,257 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MME_management_procedures.c + * \brief m3ap tasks for MME + * \author Javier Morgade + * \date 2018 + * \version 1.0 + */ + +#include +#include +#include + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "m3ap_common.h" +#include "m3ap_MME_defs.h" +#include "m3ap_MME.h" + + +#define M3AP_DEBUG_LIST +#ifdef M3AP_DEBUG_LIST +# define M3AP_MME_LIST_OUT(x, args...) M3AP_DEBUG("[MME]%*s"x"\n", 4*indent, "", ##args) +#else +# define M3AP_MME_LIST_OUT(x, args...) +#endif + +static int indent = 0; + + +m3ap_MME_internal_data_t m3ap_MME_internal_data; + +RB_GENERATE(m3ap_mme_map, m3ap_MME_data_s, entry, m3ap_MME_compare_assoc_id); + +int m3ap_MME_compare_assoc_id( + struct m3ap_MME_data_s *p1, struct m3ap_MME_data_s *p2) +{ + if (p1->assoc_id == -1) { + if (p1->cnx_id < p2->cnx_id) { + return -1; + } + + if (p1->cnx_id > p2->cnx_id) { + return 1; + } + } else { + if (p1->assoc_id < p2->assoc_id) { + return -1; + } + + if (p1->assoc_id > p2->assoc_id) { + return 1; + } + } + + /* Matching reference */ + return 0; +} + +uint16_t m3ap_MME_fetch_add_global_cnx_id(void) +{ + return ++m3ap_MME_internal_data.global_cnx_id; +} + +void m3ap_MME_prepare_internal_data(void) +{ + memset(&m3ap_MME_internal_data, 0, sizeof(m3ap_MME_internal_data)); + STAILQ_INIT(&m3ap_MME_internal_data.m3ap_MME_instances_head); +} + +void m3ap_MME_insert_new_instance(m3ap_MME_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&m3ap_MME_internal_data.m3ap_MME_instances_head, + new_instance_p, m3ap_MME_entries); +} + +void dump_mme_tree_m2(m3ap_MME_data_t *t) +{ + if (t == NULL) return; + printf("-----------------------\n"); + printf("MME id %d %s\n", t->MME_id, t->MME_name); + printf("state %d\n", t->state); + printf("nextstream %d\n", t->nextstream); + printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams); + printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id); + dump_mme_tree_m2(t->entry.rbe_left); + dump_mme_tree_m2(t->entry.rbe_right); +} + +void dump_mme_trees_m2(void) +{ +m3ap_MME_instance_t *zz; +STAILQ_FOREACH(zz, &m3ap_MME_internal_data.m3ap_MME_instances_head, + m3ap_MME_entries) { +printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +dump_mme_tree_m2(zz->m3ap_mme_head.rbh_root); +printf("---------------------------------------------\n"); +} +} + +struct m3ap_MME_data_s *m3ap_get_MME(m3ap_MME_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id) +{ + struct m3ap_MME_data_s temp; + struct m3ap_MME_data_s *found; + +printf("m3ap_get_MME at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +dump_mme_trees_m2(); + + memset(&temp, 0, sizeof(struct m3ap_MME_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &m3ap_MME_internal_data.m3ap_MME_instances_head, + m3ap_MME_entries) { + found = RB_FIND(m3ap_mme_map, &instance_p->m3ap_mme_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(m3ap_mme_map, &instance_p->m3ap_mme_head, &temp); + } + + return NULL; +} + + +m3ap_MME_instance_t *m3ap_MME_get_instance(instance_t instance) +{ + m3ap_MME_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &m3ap_MME_internal_data.m3ap_MME_instances_head, + m3ap_MME_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} + +/// utility functions + +void m3ap_dump_MME (m3ap_MME_data_t * MME_ref); + +void +m3ap_dump_MME_list (void) { + m3ap_MME_instance_t *inst = NULL; + struct m3ap_MME_data_s *found = NULL; + struct m3ap_MME_data_s temp; + + memset(&temp, 0, sizeof(struct m3ap_MME_data_s)); + + STAILQ_FOREACH (inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) { + found = RB_FIND(m3ap_mme_map, &inst->m3ap_mme_head, &temp); + m3ap_dump_MME (found); + } +} + +void m3ap_dump_MME (m3ap_MME_data_t * MME_ref) { + + if (MME_ref == NULL) { + return; + } + + M3AP_MME_LIST_OUT (""); + M3AP_MME_LIST_OUT ("MME name: %s", MME_ref->MME_name == NULL ? "not present" : MME_ref->MME_name); + M3AP_MME_LIST_OUT ("MME STATE: %07x", MME_ref->state); + M3AP_MME_LIST_OUT ("MME ID: %07x", MME_ref->MME_id); + indent++; + M3AP_MME_LIST_OUT ("SCTP cnx id: %d", MME_ref->cnx_id); + M3AP_MME_LIST_OUT ("SCTP assoc id: %d", MME_ref->assoc_id); + M3AP_MME_LIST_OUT ("SCTP instreams: %d", MME_ref->in_streams); + M3AP_MME_LIST_OUT ("SCTP outstreams: %d", MME_ref->out_streams); + indent--; +} + +m3ap_MME_data_t * m3ap_is_MME_pci_in_list (const uint32_t pci) +{ + m3ap_MME_instance_t *inst; + struct m3ap_MME_data_s *elm; + + STAILQ_FOREACH(inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) { + RB_FOREACH(elm, m3ap_mme_map, &inst->m3ap_mme_head) { + for (int i = 0; inum_cc; i++) { + if (elm->Nid_cell[i] == pci) { + return elm; + } + } + } + } + return NULL; +} + +m3ap_MME_data_t * m3ap_is_MME_id_in_list (const uint32_t MME_id) +{ + m3ap_MME_instance_t *inst; + struct m3ap_MME_data_s *elm; + + STAILQ_FOREACH(inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) { + RB_FOREACH(elm, m3ap_mme_map, &inst->m3ap_mme_head) { + if (elm->MME_id == MME_id) + return elm; + } + } + return NULL; +} + +m3ap_MME_data_t * m3ap_is_MME_assoc_id_in_list (const uint32_t sctp_assoc_id) +{ + m3ap_MME_instance_t *inst; + struct m3ap_MME_data_s *found; + struct m3ap_MME_data_s temp; + + temp.assoc_id = sctp_assoc_id; + temp.cnx_id = -1; + + STAILQ_FOREACH(inst, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) { + found = RB_FIND(m3ap_mme_map, &inst->m3ap_mme_head, &temp); + if (found != NULL){ + if (found->assoc_id == sctp_assoc_id) { + return found; + } + } + } + return NULL; +} diff --git a/openair3/M3AP/m3ap_MME_management_procedures.h b/openair3/M3AP/m3ap_MME_management_procedures.h new file mode 100644 index 0000000000..e966ee1f17 --- /dev/null +++ b/openair3/M3AP/m3ap_MME_management_procedures.h @@ -0,0 +1,54 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_management_procedures.h + * \brief m3ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_MME_MANAGEMENT_PROCEDURES_H_ +#define M3AP_MME_MANAGEMENT_PROCEDURES_H + +void m3ap_MME_prepare_internal_data(void); + +void dump_trees_m2(void); + +void m3ap_MME_insert_new_instance(m3ap_MME_instance_t *new_instance_p); + +m3ap_MME_instance_t *m3ap_MME_get_instance(uint8_t mod_id); + +uint16_t m3ap_MME_fetch_add_global_cnx_id(void); + +void m3ap_MME_prepare_internal_data(void); + +m3ap_MME_data_t* m3ap_is_MME_id_in_list(uint32_t MME_id); + +m3ap_MME_data_t* m3ap_is_MME_assoc_id_in_list(uint32_t sctp_assoc_id); + +m3ap_MME_data_t* m3ap_is_MME_pci_in_list (const uint32_t pci); + +struct m3ap_MME_data_s *m3ap_get_MME(m3ap_MME_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id); + +#endif /* M3AP_MME_MANAGEMENT_PROCEDURES_H_ */ diff --git a/openair3/M3AP/m3ap_common.c b/openair3/M3AP/m3ap_common.c index d61ead3580..5501997638 100644 --- a/openair3/M3AP/m3ap_common.c +++ b/openair3/M3AP/m3ap_common.c @@ -20,7 +20,7 @@ */ /*! \file m3ap_common.c - * \brief m3ap procedures for both MCE and MME + * \brief m3ap procedures for both eNB and MCE * \author Javier Morgade * \date 2019 * \version 0.1 diff --git a/openair3/M3AP/m3ap_common.h b/openair3/M3AP/m3ap_common.h index 83969bf9ef..7f68510314 100644 --- a/openair3/M3AP/m3ap_common.h +++ b/openair3/M3AP/m3ap_common.h @@ -38,14 +38,6 @@ #ifndef M3AP_COMMON_H_ #define M3AP_COMMON_H_ -/*! \file m3ap_common.h - * \brief m3ap procedures for both MCE and MME - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - - /** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation * @ingroup _ref_implementation_ * @{ diff --git a/openair3/M3AP/m3ap_decoder.c b/openair3/M3AP/m3ap_decoder.c new file mode 100644 index 0000000000..cee0a5ff41 --- /dev/null +++ b/openair3/M3AP/m3ap_decoder.c @@ -0,0 +1,217 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_decoder.c + * \brief m3ap decoder procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "assertions.h" +#include "intertask_interface.h" +#include "m3ap_common.h" +#include "m3ap_decoder.h" + +static int m3ap_decode_initiating_message(M3AP_M3AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage.procedureCode) { + case M3AP_ProcedureCode_id_mBMSsessionStart: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mBMSsessionStop: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_errorIndication: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_privateMessage: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_Reset: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mBMSsessionUpdate: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mCEConfigurationUpdate: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_m3Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + default: + M3AP_ERROR("Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage.procedureCode); + AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage.procedureCode); + return -1; + } + + return 0; + +} + + +static int m3ap_decode_successful_outcome(M3AP_M3AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome.procedureCode) { + case M3AP_ProcedureCode_id_mBMSsessionStart: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_successfuloutcome_message!\n"); + break; + case M3AP_ProcedureCode_id_mBMSsessionStop: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_succesfuloutcome_message!\n"); + break; + case M3AP_ProcedureCode_id_errorIndication: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_privateMessage: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_Reset: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mBMSsessionUpdate: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mCEConfigurationUpdate: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_m3Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_succesfuloutcome_message!\n"); + break; + default: + M3AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.successfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +static int m3ap_decode_unsuccessful_outcome(M3AP_M3AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome.procedureCode) { + case M3AP_ProcedureCode_id_mBMSsessionStart: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mBMSsessionStop: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_errorIndication: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_privateMessage: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_Reset: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mBMSsessionUpdate: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_mCEConfigurationUpdate: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + case M3AP_ProcedureCode_id_m3Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap__decode_initiating_message!\n"); + break; + default: + M3AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +int m3ap_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +{ + asn_dec_rval_t dec_ret; + + DevAssert(buffer != NULL); + + dec_ret = aper_decode(NULL, + &asn_DEF_M3AP_M3AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, pdu); + } + + if (dec_ret.code != RC_OK) { + M3AP_ERROR("Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case M3AP_M3AP_PDU_PR_initiatingMessage: + return m3ap_decode_initiating_message(pdu); + + case M3AP_M3AP_PDU_PR_successfulOutcome: + return m3ap_decode_successful_outcome(pdu); + + case M3AP_M3AP_PDU_PR_unsuccessfulOutcome: + return m3ap_decode_unsuccessful_outcome(pdu); + + default: + M3AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + + return -1; +} diff --git a/openair3/M3AP/m3ap_decoder.h b/openair3/M3AP/m3ap_decoder.h new file mode 100644 index 0000000000..6d228a1ceb --- /dev/null +++ b/openair3/M3AP/m3ap_decoder.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_decoder.h + * \brief m3ap decoder procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_DECODER_H_ +#define M3AP_DECODER_H_ + +int m3ap_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +__attribute__ ((warn_unused_result)); + +#endif /* M3AP_DECODER_H_ */ diff --git a/openair3/M3AP/m3ap_default_values.h b/openair3/M3AP/m3ap_default_values.h new file mode 100644 index 0000000000..79c78d5b96 --- /dev/null +++ b/openair3/M3AP/m3ap_default_values.h @@ -0,0 +1,47 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_default_values.h + * \brief default values for m3ap procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \company Vicomtech + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#ifndef M3AP_DEFAULT_VALUES_H_ +#define M3AP_DEFAULT_VALUES_H_ + +#define ENB_TAC (1) +#define ENB_MCC (208) +#define ENB_MNC (92) + +#define ENB_NAME "Eurecom ENB" +#define ENB_NAME_FORMAT (ENB_NAME" %u") + +#define M3AP_PORT_NUMBER (36444) +#define M3AP_SCTP_PPID (44) + +#endif /* M3AP_DEFAULT_VALUES_H_ */ + diff --git a/openair3/M3AP/m3ap_eNB_decoder.c b/openair3/M3AP/m3ap_eNB_decoder.c new file mode 100644 index 0000000000..ee0aaca388 --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_decoder.c @@ -0,0 +1,155 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_decoder.c + * \brief m3ap decoder procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "assertions.h" +#include "intertask_interface.h" +#include "m3ap_common.h" +#include "m3ap_eNB_decoder.h" + +static int m3ap_eNB_decode_initiating_message(M3AP_M3AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage.procedureCode) { + + case M3AP_ProcedureCode_id_m3Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); + break; + +// case M3AP_ProcedureCode_id_handoverPreparation: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); +// M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); +// break; +// +// case M3AP_ProcedureCode_id_uEContextRelease: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); +// M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); +// break; +// +// case M3AP_ProcedureCode_id_handoverCancel: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); +// M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); +// break; +// + default: + M3AP_ERROR("Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage.procedureCode); + AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage.procedureCode); + return -1; + } + + return 0; +} + +static int m3ap_eNB_decode_successful_outcome(M3AP_M3AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome.procedureCode) { + case M3AP_ProcedureCode_id_m3Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap_eNB_decode_successfuloutcome_message!\n"); + break; + +// case M3AP_ProcedureCode_id_handoverPreparation: +// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); +// M3AP_INFO("m3ap_eNB_decode_successfuloutcome_message!\n"); +// break; +// + default: + M3AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.successfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +static int m3ap_eNB_decode_unsuccessful_outcome(M3AP_M3AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome.procedureCode) { + case M3AP_ProcedureCode_id_m3Setup: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); + M3AP_INFO("m3ap_eNB_decode_unsuccessfuloutcome_message!\n"); + break; + + default: + M3AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +int m3ap_eNB_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +{ + asn_dec_rval_t dec_ret; + + DevAssert(buffer != NULL); + + dec_ret = aper_decode(NULL, + &asn_DEF_M3AP_M3AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, pdu); + } + + if (dec_ret.code != RC_OK) { + M3AP_ERROR("Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case M3AP_M3AP_PDU_PR_initiatingMessage: + return m3ap_eNB_decode_initiating_message(pdu); + + case M3AP_M3AP_PDU_PR_successfulOutcome: + return m3ap_eNB_decode_successful_outcome(pdu); + + case M3AP_M3AP_PDU_PR_unsuccessfulOutcome: + return m3ap_eNB_decode_unsuccessful_outcome(pdu); + + default: + M3AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + + return -1; +} diff --git a/openair3/M3AP/m3ap_eNB_decoder.h b/openair3/M3AP/m3ap_eNB_decoder.h new file mode 100644 index 0000000000..eddf10781e --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_decoder.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_decoder.h + * \brief m3ap decoder procedures for eNB + * \author Konstantinos Alexandris , Cedric Roux , Navid Nikaein + * \date 2018 + * \version 1.0 + */ + +#ifndef M3AP_ENB_DECODER_H_ +#define M3AP_ENB_DECODER_H_ + +int m3ap_eNB_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +__attribute__ ((warn_unused_result)); + +#endif /* M3AP_ENB_DECODER_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_encoder.c b/openair3/M3AP/m3ap_eNB_encoder.c new file mode 100644 index 0000000000..0f0d3c3188 --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_encoder.c @@ -0,0 +1,61 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_encoder.c + * \brief m3ap encoder procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" +#include "intertask_interface.h" +#include "m3ap_common.h" +#include "m3ap_eNB_encoder.h" + +int m3ap_eNB_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + ssize_t encoded; + + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)pdu); + } + + encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, pdu, (void **)buffer); + + if (encoded < 0) { + return -1; + } + + *len = encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, pdu); + return encoded; +} diff --git a/openair3/M3AP/m3ap_eNB_encoder.h b/openair3/M3AP/m3ap_eNB_encoder.h new file mode 100644 index 0000000000..1e22b59391 --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_encoder.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_encoder.h + * \brief m3ap encoder procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_ENB_ENCODER_H_ +#define M3AP_ENB_ENCODER_H_ + +int m3ap_eNB_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +__attribute__ ((warn_unused_result)); + +#endif /* M3AP_ENB_ENCODER_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_generate_messages.c b/openair3/M3AP/m3ap_eNB_generate_messages.c new file mode 100644 index 0000000000..157146ee0f --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_generate_messages.c @@ -0,0 +1,804 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_generate_messages.c + * \brief m3ap procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +//#include "M3AP_LastVisitedCell-Item.h" + +#include "m3ap_common.h" +#include "m3ap_eNB.h" +#include "m3ap_eNB_generate_messages.h" +#include "m3ap_eNB_encoder.h" +#include "m3ap_eNB_decoder.h" +#include "m3ap_ids.h" + +#include "m3ap_eNB_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +int m3ap_eNB_generate_m3_setup_request( + m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p) +{ + M3AP_M3AP_PDU_t pdu; + M3AP_M3SetupRequest_t *out; + M3AP_M3SetupRequestIEs_t *ie; + //M3AP_PLMN_Identity_t *plmn; + //ServedCells__Member *servedCellMember; + //M3AP_GU_Group_ID_t *gu; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(m3ap_eNB_data_p != NULL); + + m3ap_eNB_data_p->state = M3AP_ENB_STATE_WAITING; + + /* Prepare the M3AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_m3Setup; + pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_M3SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.M3SetupRequest; + + /* mandatory */ + ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_GlobalENB_ID; + //ie->criticality = M3AP_Criticality_reject; + //ie->value.present = M3AP_M2SetupRequest_IEs__value_PR_GlobalENB_ID; + //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &ie->value.choice.GlobalENB_ID.pLMN_Identity); + //ie->value.choice.GlobalENB_ID.eNB_ID.present = M3AP_ENB_ID_PR_macro_eNB_ID; + //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); + //M3AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], + // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], + // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_ServedCells; + //ie->criticality = M3AP_Criticality_reject; + //ie->value.present = M3AP_M2SetupRequest_IEs__value_PR_ServedCells; + //{ + // for (int i = 0; inum_cc; i++){ + // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); + // { + // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; + + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); + // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, + // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); + + // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + // plmn = (M3AP_PLMN_Identity_t *)calloc(1,sizeof(M3AP_PLMN_Identity_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); + // } + + // if (instance_p->frame_type[i] == FDD) { + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M3AP_EUTRA_Mode_Info_PR_fDD; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + // switch (instance_p->N_RB_DL[i]) { + // case 6: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; + // break; + // case 15: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; + // break; + // case 25: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; + // break; + // case 50: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; + // break; + // case 75: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; + // break; + // case 100: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; + // break; + // default: + // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + // break; + // } + // } + // else { + // AssertFatal(0,"M2Setuprequest not supported for TDD!"); + // } + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + // } + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_GUGroupIDList; + //ie->criticality = M3AP_Criticality_reject; + //ie->value.present = M3AP_M2SetupRequest_IEs__value_PR_GUGroupIDList; + //{ + // gu = (M3AP_GU_Group_ID_t *)calloc(1, sizeof(M3AP_GU_Group_ID_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &gu->pLMN_Identity); + // //@TODO: consider to update this value + // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + M3AP_ERROR("Failed to encode M3 setup request\n"); + return -1; + } + + //MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 M3Setup/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); + + m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int m3ap_eNB_generate_m3_setup_response(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p) +{ + M3AP_M3AP_PDU_t pdu; + M3AP_M3SetupResponse_t *out; + M3AP_M3SetupResponseIEs_t *ie; + //M3AP_PLMN_Identity_t *plmn; + //ServedCells__Member *servedCellMember; + //M3AP_GU_Group_ID_t *gu; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(m3ap_eNB_data_p != NULL); + + /* Prepare the M3AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_m3Setup; + pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_M3SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.M3SetupResponse; + + /* mandatory */ + ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_GlobalENB_ID; + //ie->criticality = M3AP_Criticality_reject; + //ie->value.present = M3AP_M3SetupResponse_IEs__value_PR_GlobalENB_ID; + //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &ie->value.choice.GlobalENB_ID.pLMN_Identity); + //ie->value.choice.GlobalENB_ID.eNB_ID.present = M3AP_ENB_ID_PR_macro_eNB_ID; + //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); + //M3AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], + // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], + // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_ServedCells; + //ie->criticality = M3AP_Criticality_reject; + //ie->value.present = M3AP_M3SetupResponse_IEs__value_PR_ServedCells; + //{ + // for (int i = 0; inum_cc; i++){ + // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); + // { + // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; + + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); + // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, + // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); + + // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + // plmn = (M3AP_PLMN_Identity_t *)calloc(1,sizeof(M3AP_PLMN_Identity_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); + // } + + // if (instance_p->frame_type[i] == FDD) { + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M3AP_EUTRA_Mode_Info_PR_fDD; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + // switch (instance_p->N_RB_DL[i]) { + // case 6: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; + // break; + // case 15: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; + // break; + // case 25: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; + // break; + // case 50: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; + // break; + // case 75: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; + // break; + // case 100: + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; + // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; + // break; + // default: + // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + // break; + // } + // } + // else { + // AssertFatal(0,"M3Setupresponse not supported for TDD!"); + // } + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + // } + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_GUGroupIDList; + //ie->criticality = M3AP_Criticality_reject; + //ie->value.present = M3AP_M3SetupResponse_IEs__value_PR_GUGroupIDList; + //{ + // gu = (M3AP_GU_Group_ID_t *)calloc(1, sizeof(M3AP_GU_Group_ID_t)); + // { + // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + // &gu->pLMN_Identity); + // //@TODO: consider to update this value + // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); + // } + // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); + //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + M3AP_ERROR("Failed to encode M3 setup response\n"); + return -1; + } + + m3ap_eNB_data_p->state = M3AP_ENB_STATE_READY; + + //MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 M3Setup/successfulOutcome assoc_id %u", m3ap_eNB_data_p->assoc_id); + + m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int m3ap_eNB_generate_m3_setup_failure(instance_t instance, + uint32_t assoc_id, + M3AP_Cause_PR cause_type, + long cause_value, + long time_to_wait) +{ + M3AP_M3AP_PDU_t pdu; + M3AP_M3SetupFailure_t *out; + M3AP_M3SetupFailureIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + /* Prepare the M3AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.unsuccessfulOutcome.procedureCode = M3AP_ProcedureCode_id_m3Setup; + pdu.choice.unsuccessfulOutcome.criticality = M3AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = M3AP_UnsuccessfulOutcome__value_PR_M3SetupFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.M3SetupFailure; + + /* mandatory */ + ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_Cause; + //ie->criticality = M3AP_Criticality_ignore; + //ie->value.present = M3AP_M3SetupFailure_IEs__value_PR_Cause; + + //m3ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional: consider to handle this later */ + ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); + //ie->id = M3AP_ProtocolIE_ID_id_TimeToWait; + //ie->criticality = M3AP_Criticality_ignore; + //ie->value.present = M3AP_M3SetupFailure_IEs__value_PR_TimeToWait; + + //if (time_to_wait > -1) { + // ie->value.choice.TimeToWait = time_to_wait; + //} + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + M3AP_ERROR("Failed to encode M3 setup failure\n"); + return -1; + } + + //MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, + // MSC_M3AP_TARGET_ENB, NULL, 0, + // "0 M3Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", + // assoc_id, cause_type, cause_value); + + m3ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); + + return ret; +} + +int m3ap_eNB_set_cause (M3AP_Cause_t * cause_p, + M3AP_Cause_PR cause_type, + long cause_value) +{ + + DevAssert (cause_p != NULL); + cause_p->present = cause_type; + + switch (cause_type) { + case M3AP_Cause_PR_radioNetwork: + cause_p->choice.misc = cause_value; + break; + + case M3AP_Cause_PR_transport: + cause_p->choice.misc = cause_value; + break; + + case M3AP_Cause_PR_protocol: + cause_p->choice.misc = cause_value; + break; + + case M3AP_Cause_PR_misc: + cause_p->choice.misc = cause_value; + break; + + default: + return -1; + } + + return 0; +} + +//int m3ap_eNB_generate_m2_handover_request (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// m3ap_handover_req_t *m3ap_handover_req, int ue_id) +//{ +// +// M3AP_M3AP_PDU_t pdu; +// M3AP_HandoverRequest_t *out; +// M3AP_HandoverRequest_IEs_t *ie; +// M3AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; +// M3AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; +// M3AP_LastVisitedCell_Item_t *lastVisitedCell_Item; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m3ap_eNB_data_p != NULL); +// +// /* Prepare the M3AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; +// pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_HandoverRequest; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; +// +// /* mandatory */ +// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_UE_M3AP_ID; +// ie->value.choice.UE_M3AP_ID = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_Cause; +// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = M3AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_TargetCell_ID; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_ECGI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.ECGI.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(m3ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_GUMMEI_ID; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_GUMMEI; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); +// //@TODO: consider to update these values +// INT16_TO_OCTET_STRING(m3ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); +// MME_CODE_TO_OCTET_STRING(m3ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_UE_ContextInformation; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; +// //@TODO: consider to update this value +// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m3ap_handover_req->mme_ue_s1ap_id; +// +// KENB_STAR_TO_BIT_STRING(m3ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); +// +// if (m3ap_handover_req->kenb_ncc >=0) { // Check this condition +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m3ap_handover_req->kenb_ncc; +// } +// else { +// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; +// } +// +// ENCRALG_TO_BIT_STRING(m3ap_handover_req->security_capabilities.encryption_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); +// +// INTPROTALG_TO_BIT_STRING(m3ap_handover_req->security_capabilities.integrity_algorithms, +// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); +// +// //@TODO: update with proper UEAMPR +// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); +// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_ToBeSetup_ItemIEs = (M3AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M3AP_E_RABs_ToBeSetup_ItemIEs_t)); +// e_RABS_ToBeSetup_ItemIEs->id = M3AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; +// e_RABS_ToBeSetup_ItemIEs->criticality = M3AP_Criticality_ignore; +// e_RABS_ToBeSetup_ItemIEs->value.present = M3AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; +// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; +// { +// e_RABs_ToBeSetup_Item->e_RAB_ID = m3ap_handover_req->e_rabs_tobesetup[i].e_rab_id; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m3ap_handover_req->e_rab_param[i].qos.qci; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m3ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m3ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; +// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m3ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m3ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8); +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m3ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8; +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = +// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, +// m3ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// INT32_TO_OCTET_STRING(m3ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); +// } +// } +// +// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m3ap_handover_req->rrc_buffer, m3ap_handover_req->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_UE_HistoryInformation; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; +// //@TODO: consider to update this value +// { +// lastVisitedCell_Item = (M3AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M3AP_LastVisitedCell_Item_t)); +// lastVisitedCell_Item->present = M3AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; +// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, +// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); +// MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); +// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M3AP_Cell_Size_small; +// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; +// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M3AP_ERROR("Failed to encode X2 handover request\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); +// +// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m3ap_eNB_generate_m2_handover_request_ack (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// m3ap_handover_req_ack_t *m3ap_handover_req_ack) +//{ +// +// M3AP_M3AP_PDU_t pdu; +// M3AP_HandoverRequestAcknowledge_t *out; +// M3AP_HandoverRequestAcknowledge_IEs_t *ie; +// M3AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; +// M3AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m3ap_eNB_data_p != NULL); +// +// ue_id = m3ap_handover_req_ack->m2_id_target; +// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M3AP handover message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; +// pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_handoverPreparation; +// pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; +// pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; +// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; +// +// /* mandatory */ +// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M3AP_ID; +// ie->value.choice.UE_M3AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M3AP_ID_1; +// ie->value.choice.UE_M3AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_E_RABs_Admitted_List; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; +// +// { +// for (int i=0;inb_e_rabs_tobesetup;i++) { +// e_RABS_Admitted_ItemIEs = (M3AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M3AP_E_RABs_Admitted_ItemIEs_t)); +// e_RABS_Admitted_ItemIEs->id = M3AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; +// e_RABS_Admitted_ItemIEs->criticality = M3AP_Criticality_ignore; +// e_RABS_Admitted_ItemIEs->value.present = M3AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; +// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; +// { +// e_RABs_Admitted_Item->e_RAB_ID = m3ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; +// } +// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); +// } +// } +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer; +// +// OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m3ap_handover_req_ack->rrc_buffer, m3ap_handover_req_ack->rrc_buffer_size); +// +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M3AP_ERROR("Failed to encode X2 handover response\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m3ap_eNB_data_p->assoc_id); +// +// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m3ap_eNB_generate_m2_ue_context_release (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, m3ap_ue_context_release_t *m3ap_ue_context_release) +//{ +// +// M3AP_M3AP_PDU_t pdu; +// M3AP_UEContextRelease_t *out; +// M3AP_UEContextRelease_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m3ap_eNB_data_p != NULL); +// +// ue_id = m3ap_find_id_from_rnti(&instance_p->id_manager, m3ap_ue_context_release->rnti); +// if (ue_id == -1) { +// M3AP_ERROR("could not find UE %x\n", m3ap_ue_context_release->rnti); +// exit(1); +// } +// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); +// id_target = ue_id; +// +// /* Prepare the M3AP ue context relase message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_uEContextRelease; +// pdu.choice.initiatingMessage.criticality = M3AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_UEContextRelease; +// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; +// +// /* mandatory */ +// ie = (M3AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M3AP_UEContextRelease_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_UEContextRelease_IEs__value_PR_UE_M3AP_ID; +// ie->value.choice.UE_M3AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* mandatory */ +// ie = (M3AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M3AP_UEContextRelease_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_UEContextRelease_IEs__value_PR_UE_M3AP_ID_1; +// ie->value.choice.UE_M3AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M3AP_ERROR("Failed to encode X2 UE Context Release\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); +// +// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} +// +//int m3ap_eNB_generate_m2_handover_cancel (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// int m2_ue_id, +// m3ap_handover_cancel_cause_t cause) +//{ +// M3AP_M3AP_PDU_t pdu; +// M3AP_HandoverCancel_t *out; +// M3AP_HandoverCancel_IEs_t *ie; +// int ue_id; +// int id_source; +// int id_target; +// +// uint8_t *buffer; +// uint32_t len; +// int ret = 0; +// +// DevAssert(instance_p != NULL); +// DevAssert(m3ap_eNB_data_p != NULL); +// +// ue_id = m2_ue_id; +// id_source = ue_id; +// id_target = m3ap_id_get_id_target(&instance_p->id_manager, ue_id); +// +// /* Prepare the M3AP handover cancel message to encode */ +// memset(&pdu, 0, sizeof(pdu)); +// pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; +// pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_handoverCancel; +// pdu.choice.initiatingMessage.criticality = M3AP_Criticality_ignore; +// pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_HandoverCancel; +// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; +// +// /* mandatory */ +// ie = (M3AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M3AP_HandoverCancel_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_reject; +// ie->value.present = M3AP_HandoverCancel_IEs__value_PR_UE_M3AP_ID; +// ie->value.choice.UE_M3AP_ID = id_source; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// /* optional */ +// if (id_target != -1) { +// ie = (M3AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M3AP_HandoverCancel_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverCancel_IEs__value_PR_UE_M3AP_ID_1; +// ie->value.choice.UE_M3AP_ID_1 = id_target; +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// } +// +// /* mandatory */ +// ie = (M3AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M3AP_HandoverCancel_IEs_t)); +// ie->id = M3AP_ProtocolIE_ID_id_Cause; +// ie->criticality = M3AP_Criticality_ignore; +// ie->value.present = M3AP_HandoverCancel_IEs__value_PR_Cause; +// switch (cause) { +// case M3AP_T_RELOC_PREP_TIMEOUT: +// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M3AP_CauseRadioNetwork_trelocprep_expiry; +// break; +// case M3AP_TX2_RELOC_OVERALL_TIMEOUT: +// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; +// ie->value.choice.Cause.choice.radioNetwork = +// M3AP_CauseRadioNetwork_tx2relocoverall_expiry; +// break; +// default: +// /* we can't come here */ +// M3AP_ERROR("unhandled cancel cause\n"); +// exit(1); +// } +// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); +// +// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { +// M3AP_ERROR("Failed to encode X2 Handover Cancel\n"); +// abort(); +// return -1; +// } +// +// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); +// +// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); +// +// return ret; +//} diff --git a/openair3/M3AP/m3ap_eNB_generate_messages.h b/openair3/M3AP/m3ap_eNB_generate_messages.h new file mode 100644 index 0000000000..ab6c7ca615 --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_generate_messages.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_generate_messages.h + * \brief m3ap procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_ENB_GENERATE_MESSAGES_H_ +#define M3AP_ENB_GENERATE_MESSAGES_H_ + +#include "m3ap_eNB_defs.h" +#include "m3ap_common.h" + +int m3ap_eNB_generate_m3_setup_request(m3ap_eNB_instance_t *instance_p, + m3ap_eNB_data_t *m3ap_eNB_data_p); + +int m3ap_eNB_generate_m3_setup_response(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p); + +int m3ap_eNB_generate_m3_setup_failure(instance_t instance, + uint32_t assoc_id, + M3AP_Cause_PR cause_type, + long cause_value, + long time_to_wait); + +int m3ap_eNB_set_cause (M3AP_Cause_t * cause_p, + M3AP_Cause_PR cause_type, + long cause_value); + +//int m3ap_eNB_generate_m2_handover_request (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// m3ap_handover_req_t *m3ap_handover_req, int ue_id); +// +//int m3ap_eNB_generate_m2_handover_request_ack (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// m3ap_handover_req_ack_t *m3ap_handover_req_ack); +// +//int m3ap_eNB_generate_m2_ue_context_release (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// m3ap_ue_context_release_t *m3ap_ue_context_release); +// +//int m3ap_eNB_generate_m2_handover_cancel (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, +// int m2_ue_id, +// m3ap_handover_cancel_cause_t cause); + +#endif /* M3AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_handler.c b/openair3/M3AP/m3ap_eNB_handler.c new file mode 100644 index 0000000000..4fda97142d --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_handler.c @@ -0,0 +1,985 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_handler.c + * \brief m3ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m3ap_common.h" +#include "m3ap_eNB_defs.h" +#include "m3ap_eNB_handler.h" +#include "m3ap_eNB_decoder.h" +#include "m3ap_ids.h" + +#include "m3ap_eNB_management_procedures.h" +#include "m3ap_eNB_generate_messages.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +static +int m3ap_eNB_handle_m3_setup_request (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +static +int m3ap_eNB_handle_m3_setup_response (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +static +int m3ap_eNB_handle_m3_setup_failure (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu); +// +//static +//int m3ap_eNB_handle_handover_preparation (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu); +//static +//int m3ap_eNB_handle_handover_response (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu); +// +//static +//int m3ap_eNB_handle_ue_context_release (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu); +// +//static +//int m3ap_eNB_handle_handover_cancel (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu); + +/* Handlers matrix. Only eNB related procedure present here */ +m3ap_message_decoded_callback m3ap_messages_callback[][3] = { + { 0, 0, 0 }, /* MBMSSessionStart */ + { 0, 0, 0 }, /* MBMSSessionStop */ + { 0, 0, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MBMSSchedulingInformation */ + { 0, 0, 0 }, /* reset */ + { m3ap_eNB_handle_m3_setup_request, m3ap_eNB_handle_m3_setup_response, m3ap_eNB_handle_m3_setup_failure }, /* M3 Setup */ + { 0, 0, 0 }, /* eNBConfigurationUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { 0, 0, 0 }, /* MBMSServiceCounting */ +}; + +char *m3ap_direction2String(int m3ap_dir) { +static char *m3ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m3ap_direction_String[m3ap_dir]); +} + +void m3ap_handle_m3_setup_message(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *enb_desc_p, int sctp_shutdown) +{ + if (sctp_shutdown) { + /* A previously connected eNB has been shutdown */ + + /* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated eNB */ + if (enb_desc_p->state == M3AP_ENB_STATE_CONNECTED) { + enb_desc_p->state = M3AP_ENB_STATE_DISCONNECTED; + + if (instance_p-> m3_target_enb_associated_nb > 0) { + /* Decrease associated eNB number */ + instance_p-> m3_target_enb_associated_nb --; + } + + /* If there are no more associated eNB, inform eNB app */ + if (instance_p->m3_target_enb_associated_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_M3AP, M3AP_DEREGISTERED_MCE_IND); + M3AP_DEREGISTERED_MCE_IND(message_p).nb_mme = 0; + itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); + } + } + } else { + /* Check that at least one setup message is pending */ + DevCheck(instance_p->m3_target_enb_pending_nb > 0, + instance_p->instance, + instance_p->m3_target_enb_pending_nb, 0); + + if (instance_p->m3_target_enb_pending_nb > 0) { + /* Decrease pending messages number */ + instance_p->m3_target_enb_pending_nb --; + } + + /* If there are no more pending messages, inform eNB app */ + if (instance_p->m3_target_enb_pending_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_M3AP, M3AP_REGISTER_MCE_CNF); + M3AP_REGISTER_MCE_CNF(message_p).nb_mme = instance_p->m3_target_enb_associated_nb; + itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); + } + } +} + + +int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t *const data, const uint32_t data_length) +{ + M3AP_M3AP_PDU_t pdu; + int ret = 0; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + //printf("Data length received: %d\n", data_length); + + if (m3ap_eNB_decode_pdu(&pdu, data, data_length) < 0) { + M3AP_ERROR("Failed to decode PDU\n"); + return -1; + } + + switch (pdu.present) { + + case M3AP_M3AP_PDU_PR_initiatingMessage: + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( + m3ap_message_decoded_callback))) { + //|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { + M3AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + M3AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m3ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + /* Calling the right handler */ + ret = (*m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + break; + + case M3AP_M3AP_PDU_PR_successfulOutcome: + /* Checking procedure Code and direction of message */ + if (pdu.choice.successfulOutcome.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( + m3ap_message_decoded_callback))) { + //|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { + M3AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", + assoc_id, pdu.choice.successfulOutcome.procedureCode); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m3ap_messages_callback[pdu.choice.successfulOutcome.procedureCode][pdu.present - 1] == NULL) { + M3AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.successfulOutcome.procedureCode, + m3ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + /* Calling the right handler */ + ret = (*m3ap_messages_callback[pdu.choice.successfulOutcome.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + break; + + case M3AP_M3AP_PDU_PR_unsuccessfulOutcome: + /* Checking procedure Code and direction of message */ + if (pdu.choice.unsuccessfulOutcome.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( + m3ap_message_decoded_callback))) { + //|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { + M3AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", + assoc_id, pdu.choice.unsuccessfulOutcome.procedureCode); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m3ap_messages_callback[pdu.choice.unsuccessfulOutcome.procedureCode][pdu.present - 1] == NULL) { + M3AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.unsuccessfulOutcome.procedureCode, + m3ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + /* Calling the right handler */ + ret = (*m3ap_messages_callback[pdu.choice.unsuccessfulOutcome.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + break; + + default: + M3AP_ERROR("[SCTP %d] Direction %d exceed expected\n", + assoc_id, pdu.present); + break; + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return ret; +} + +int +m3ap_eNB_handle_m3_setup_request(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) +{ + + M3AP_M3SetupRequest_t *m3SetupRequest; + //M3AP_M3SetupRequestIEs_t *ie; + //ServedCells__Member *servedCellMember; + + m3ap_eNB_instance_t *instance_p; + m3ap_eNB_data_t *m3ap_eNB_data; + uint32_t eNB_id = 0; + + DevAssert (pdu != NULL); + m3SetupRequest = &pdu->choice.initiatingMessage.value.choice.M3SetupRequest; + + /* + * We received a new valid M3 Setup Request on a stream != 0. + * * * * This should not happen -> reject eNB m3 setup request. + */ + + if (stream != 0) { + M3AP_ERROR("Received new m3 setup request on stream != 0\n"); + /* + * Send a m3 setup failure with protocol cause unspecified + */ + return m3ap_eNB_generate_m3_setup_failure (instance, + assoc_id, + M3AP_Cause_PR_protocol, + M3AP_CauseProtocol_unspecified, + -1); + } + + M3AP_DEBUG("Received a new M3 setup request\n"); + + //M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequestIEs_t, ie, m3SetupRequest, + // M3AP_ProtocolIE_ID_id_GlobalENB_ID, true); + //if (ie == NULL ) { + // M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + // return -1; + //} else { + // if (ie->value.choice.GlobalENB_ID.eNB_ID.present == M3AP_ENB_ID_PR_macro_eNB_ID) { + // // Home eNB ID = 28 bits + // uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; + + // if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { + // //TODO: handle case were size != 28 -> notify ? reject ? + // } + + // eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); + // M3AP_DEBUG("Home eNB id: %07x\n", eNB_id); + // } else { + // // Macro eNB = 20 bits + // uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; + + // if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { + // //TODO: handle case were size != 20 -> notify ? reject ? + // } + + // eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); + // M3AP_DEBUG("macro eNB id: %05x\n", eNB_id); + // } + //} + + M3AP_DEBUG("Adding eNB to the list of associated eNBs\n"); + + if ((m3ap_eNB_data = m3ap_is_eNB_id_in_list (eNB_id)) == NULL) { + /* + * eNB has not been found in list of associated eNB, + * * * * Add it to the tail of list and initialize data + */ + if ((m3ap_eNB_data = m3ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { + /* + * ?? + */ + return -1; + } else { + m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; + m3ap_eNB_data->eNB_id = eNB_id; + } + } else { + m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; + /* + * eNB has been found in list, consider the m3 setup request as a reset connection, + * * * * reseting any previous UE state if sctp association is != than the previous one + */ + if (m3ap_eNB_data->assoc_id != assoc_id) { + /* + * ??: Send an overload cause... + */ + M3AP_ERROR("Rejecting m3 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, m3ap_eNB_data->assoc_id, assoc_id); + + m3ap_eNB_generate_m3_setup_failure (instance, + assoc_id, + M3AP_Cause_PR_protocol, + M3AP_CauseProtocol_unspecified, + -1); + return -1; + } + /* + * TODO: call the reset procedure + */ + } + + /* Set proper pci */ +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequest_IEs_t, ie, m2SetupRequest, +// M3AP_ProtocolIE_ID_id_ServedCells, true); +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// if (ie->value.choice.ServedCells.list.count > 0) { +// m3ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; +// for (int i=0; ivalue.choice.ServedCells.list.count;i++) { +// servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; +// m3ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; +// } +// } +// + instance_p = m3ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + return m3ap_eNB_generate_m3_setup_response(instance_p, m3ap_eNB_data); +} + +static +int m3ap_eNB_handle_m3_setup_response(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) +{ + + M3AP_M3SetupResponse_t *m3SetupResponse; + //M3AP_M3SetupResponseIEs_t *ie; + //ServedCells__Member *servedCellMember; + + m3ap_eNB_instance_t *instance_p; + m3ap_eNB_data_t *m3ap_eNB_data; + //uint32_t eNB_id = 0; + + DevAssert (pdu != NULL); + m3SetupResponse = &pdu->choice.successfulOutcome.value.choice.M3SetupResponse; + + /* + * We received a new valid M3 Setup Response on a stream != 0. + * * * * This should not happen -> reject eNB m3 setup response. + */ + + if (stream != 0) { + M3AP_ERROR("Received new m3 setup response on stream != 0\n"); + } + + if ((m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0)) == NULL) { + M3AP_ERROR("[SCTP %d] Received M3 setup response for non existing " + "eNB context\n", assoc_id); + return -1; + } + + M3AP_DEBUG("Received a new M3 setup response\n"); + + // M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupResponseIEs_t, ie, m3SetupResponse, + // M3AP_ProtocolIE_ID_id_GlobalENB_ID, true); + + // if (ie == NULL ) { + // M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + // return -1; + // } +// if (ie->value.choice.GlobalENB_ID.eNB_ID.present == M3AP_ENB_ID_PR_macro_eNB_ID) { +// // Home eNB ID = 28 bits +// uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; +// +// if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { +// //TODO: handle case were size != 28 -> notify ? reject ? +// } +// +// eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); +// M3AP_DEBUG("Home eNB id: %07x\n", eNB_id); +// } else { +// // Macro eNB = 20 bits +// uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; +// +// if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { +// //TODO: handle case were size != 20 -> notify ? reject ? +// } +// +// eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); +// M3AP_DEBUG("macro eNB id: %05x\n", eNB_id); +// } +// + M3AP_DEBUG("Adding eNB to the list of associated eNBs\n"); + +// if ((m3ap_eNB_data = m3ap_is_eNB_id_in_list (eNB_id)) == NULL) { +// /* +// * eNB has not been found in list of associated eNB, +// * * * * Add it to the tail of list and initialize data +// */ +// if ((m3ap_eNB_data = m3ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { +// /* +// * ??: Send an overload cause... +// */ +// return -1; +// } else { +// m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; +// m3ap_eNB_data->eNB_id = eNB_id; +// } +// } else { +// m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; +// /* +// * TODO: call the reset procedure +// */ +// } +// + /* Set proper pci */ +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupResponse_IEs_t, ie, m2SetupResponse, +// M3AP_ProtocolIE_ID_id_ServedCells, true); +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// if (ie->value.choice.ServedCells.list.count > 0) { +// m3ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; +// for (int i=0; ivalue.choice.ServedCells.list.count;i++) { +// servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; +// m3ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; +// } +// } +// + /* Optionaly set the target eNB name */ + + /* The association is now ready as source and target eNBs know parameters of each other. + * Mark the association as connected. + */ + m3ap_eNB_data->state = M3AP_ENB_STATE_READY; + + instance_p = m3ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + instance_p->m3_target_enb_associated_nb ++; + m3ap_handle_m3_setup_message(instance_p, m3ap_eNB_data, 0); + + return 0; +} + +static +int m3ap_eNB_handle_m3_setup_failure(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + M3AP_M3AP_PDU_t *pdu) +{ + + M3AP_M3SetupFailure_t *m3SetupFailure; + M3AP_M3SetupFailureIEs_t *ie; + + m3ap_eNB_instance_t *instance_p; + m3ap_eNB_data_t *m3ap_eNB_data; + + DevAssert(pdu != NULL); + + m3SetupFailure = &pdu->choice.unsuccessfulOutcome.value.choice.M3SetupFailure; + + /* + * We received a new valid M3 Setup Failure on a stream != 0. + * * * * This should not happen -> reject eNB m3 setup failure. + */ + + if (stream != 0) { + M3AP_WARN("[SCTP %d] Received m3 setup failure on stream != 0 (%d)\n", + assoc_id, stream); + } + + if ((m3ap_eNB_data = m3ap_get_eNB (NULL, assoc_id, 0)) == NULL) { + M3AP_ERROR("[SCTP %d] Received M3 setup failure for non existing " + "eNB context\n", assoc_id); + return -1; + } + + M3AP_DEBUG("Received a new M3 setup failure\n"); + + M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupFailureIEs_t, ie, m3SetupFailure, + M3AP_ProtocolIE_ID_id_Cause, true); + + if (ie == NULL ) { + M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + // need a FSM to handle all cases + if ((ie->value.choice.Cause.present == M3AP_Cause_PR_misc) && + (ie->value.choice.Cause.choice.misc == M3AP_CauseMisc_unspecified)) { + M3AP_WARN("Received M3 setup failure for eNB ... eNB is not ready\n"); + } else { + M3AP_ERROR("Received m3 setup failure for eNB... please check your parameters\n"); + } + + m3ap_eNB_data->state = M3AP_ENB_STATE_WAITING; + + instance_p = m3ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + m3ap_handle_m3_setup_message(instance_p, m3ap_eNB_data, 0); + + return 0; +} + +//static +//int m3ap_eNB_handle_handover_preparation (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu) +//{ +// +// M3AP_HandoverRequest_t *x2HandoverRequest; +// M3AP_HandoverRequest_IEs_t *ie; +// +// M3AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; +// M3AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; +// +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *m3ap_eNB_data; +// MessageDef *msg; +// int ue_id; +// +// DevAssert (pdu != NULL); +// x2HandoverRequest = &pdu->choice.initiatingMessage.value.choice.HandoverRequest; +// +// if (stream == 0) { +// M3AP_ERROR ("Received new x2 handover request on stream == 0\n"); +// /* TODO: send a x2 failure response */ +// return 0; +// } +// +// M3AP_DEBUG ("Received a new X2 handover request\n"); +// +// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); +// DevAssert(m3ap_eNB_data != NULL); +// +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_REQ); +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, +// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// /* allocate a new M3AP UE ID */ +// ue_id = m3ap_allocate_new_id(&instance_p->id_manager); +// if (ue_id == -1) { +// M3AP_ERROR("could not allocate a new M3AP UE ID\n"); +// /* TODO: cancel handover: send HO preparation failure to source eNB */ +// exit(1); +// } +// /* rnti is unknown yet, must not be set to -1, 0 is fine */ +// m3ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_M3AP_ID, ue_id); +// m3ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET); +// +// M3AP_HANDOVER_REQ(msg).m2_id = ue_id; +// +// //M3AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. +// //measResultListEUTRA.list.array[ncell_index]->physCellId; +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, +// M3AP_ProtocolIE_ID_id_GUMMEI_ID, true); +// +// TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, M3AP_HANDOVER_REQ(msg).ue_gummei.mcc, +// M3AP_HANDOVER_REQ(msg).ue_gummei.mnc, M3AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); +// OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, M3AP_HANDOVER_REQ(msg).ue_gummei.mme_code); +// OCTET_STRING_TO_INT16(&ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID, M3AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id); +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, +// M3AP_ProtocolIE_ID_id_UE_ContextInformation, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// M3AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID; +// +// /* TODO: properly store Target Cell ID */ +// +// M3AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; +// +// M3AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = +// BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); +// M3AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms = +// BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); +// +// //M3AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr; +// +// if ((ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf) && +// (ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.size == 32)) { +// memcpy(M3AP_HANDOVER_REQ(msg).kenb, ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf, 32); +// M3AP_HANDOVER_REQ(msg).kenb_ncc = ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount; +// } else { +// M3AP_WARN ("Size of eNB key star does not match the expected value\n"); +// } +// +// if (ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count > 0) { +// +// M3AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count; +// +// for (int i=0;ivalue.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count;i++) { +// e_RABS_ToBeSetup_ItemIEs = (M3AP_E_RABs_ToBeSetup_ItemIEs_t *) ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.array[i]; +// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; +// +// M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_ToBeSetup_Item->e_RAB_ID ; +// +// memcpy(M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.buffer, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); +// +// M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.length = +// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; +// +// OCTET_STRING_TO_INT32(&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID, +// M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid); +// +// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI; +// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; +// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; +// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability; +// } +// +// } +// else { +// M3AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n"); +// } +// +// M3AP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context; +// +// if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct m3ap_handover_req_ack_s*/) +// { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } +// +// memcpy(M3AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); +// M3AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; +// +// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); +// +// return 0; +//} +// +//static +//int m3ap_eNB_handle_handover_response (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu) +//{ +// M3AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck; +// M3AP_HandoverRequestAcknowledge_IEs_t *ie; +// +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *m3ap_eNB_data; +// MessageDef *msg; +// int ue_id; +// int id_source; +// int id_target; +// int rnti; +// +// DevAssert (pdu != NULL); +// x2HandoverRequestAck = &pdu->choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; +// +// if (stream == 0) { +// M3AP_ERROR ("Received new x2 handover response on stream == 0\n"); +// /* TODO: send a x2 failure response */ +// return 0; +// } +// +// M3AP_DEBUG ("Received a new X2 handover response\n"); +// +// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); +// DevAssert(m3ap_eNB_data != NULL); +// +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_REQ_ACK); +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, +// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// id_source = ie->value.choice.UE_M3AP_ID; +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, +// M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// id_target = ie->value.choice.UE_M3AP_ID_1; +// +// ue_id = id_source; +// +// if (ue_id != m3ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { +// M3AP_WARN("incorrect/unknown M3AP IDs for UE (old ID %d new ID %d), ignoring handover response\n", +// id_source, id_target); +// return 0; +// } +// +// rnti = m3ap_id_get_rnti(&instance_p->id_manager, ue_id); +// +// /* id_target is a new information, store it */ +// m3ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target); +// m3ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_SOURCE_OVERALL); +// m3ap_set_reloc_overall_timer(&instance_p->id_manager, ue_id, +// m3ap_timer_get_tti(&instance_p->timers)); +// +// M3AP_HANDOVER_REQ_ACK(msg).rnti = rnti; +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, +// M3AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); +// +// M3AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer; +// +// if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct m3ap_handover_req_ack_s*/) +// { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } +// +// memcpy(M3AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); +// M3AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; +// +// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); +// return 0; +//} +// +// +//static +//int m3ap_eNB_handle_ue_context_release (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu) +//{ +// M3AP_UEContextRelease_t *x2UEContextRelease; +// M3AP_UEContextRelease_IEs_t *ie; +// +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *m3ap_eNB_data; +// MessageDef *msg; +// int ue_id; +// int id_source; +// int id_target; +// +// DevAssert (pdu != NULL); +// x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease; +// +// if (stream == 0) { +// M3AP_ERROR ("Received new x2 ue context release on stream == 0\n"); +// /* TODO: send a x2 failure response */ +// return 0; +// } +// +// M3AP_DEBUG ("Received a new X2 ue context release\n"); +// +// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); +// DevAssert(m3ap_eNB_data != NULL); +// +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// msg = itti_alloc_new_message(TASK_M3AP, M3AP_UE_CONTEXT_RELEASE); +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, +// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// id_source = ie->value.choice.UE_M3AP_ID; +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, +// M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// id_target = ie->value.choice.UE_M3AP_ID_1; +// +// ue_id = id_source; +// if (ue_id != m3ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { +// M3AP_WARN("incorrect/unknown M3AP IDs for UE (old ID %d new ID %d), ignoring UE context release\n", +// id_source, id_target); +// return 0; +// } +// +// if (id_target != m3ap_id_get_id_target(&instance_p->id_manager, ue_id)) { +// M3AP_ERROR("UE context release: bad id_target for UE %x (id_source %d) expected %d got %d, ignoring message\n", +// m3ap_id_get_rnti(&instance_p->id_manager, ue_id), +// id_source, +// m3ap_id_get_id_target(&instance_p->id_manager, ue_id), +// id_target); +// return 0; +// } +// +// M3AP_UE_CONTEXT_RELEASE(msg).rnti = m3ap_id_get_rnti(&instance_p->id_manager, ue_id); +// +// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); +// +// m3ap_release_id(&instance_p->id_manager, ue_id); +// +// return 0; +//} +// +//static +//int m3ap_eNB_handle_handover_cancel (instance_t instance, +// uint32_t assoc_id, +// uint32_t stream, +// M3AP_M3AP_PDU_t *pdu) +//{ +// M3AP_HandoverCancel_t *x2HandoverCancel; +// M3AP_HandoverCancel_IEs_t *ie; +// +// m3ap_eNB_instance_t *instance_p; +// m3ap_eNB_data_t *m3ap_eNB_data; +// MessageDef *msg; +// int ue_id; +// int id_source; +// int id_target; +// m3ap_handover_cancel_cause_t cause; +// +// DevAssert (pdu != NULL); +// x2HandoverCancel = &pdu->choice.initiatingMessage.value.choice.HandoverCancel; +// +// if (stream == 0) { +// M3AP_ERROR ("Received new x2 handover cancel on stream == 0\n"); +// return 0; +// } +// +// M3AP_DEBUG ("Received a new X2 handover cancel\n"); +// +// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); +// DevAssert(m3ap_eNB_data != NULL); +// +// instance_p = m3ap_eNB_get_instance(instance); +// DevAssert(instance_p != NULL); +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, +// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// id_source = ie->value.choice.UE_M3AP_ID; +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, +// M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID, false); +// +// if (ie == NULL ) { +// M3AP_INFO("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// id_target = -1; +// } else +// id_target = ie->value.choice.UE_M3AP_ID_1; +// +// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, +// M3AP_ProtocolIE_ID_id_Cause, true); +// +// if (ie == NULL ) { +// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); +// return -1; +// } +// +// if (ie->value.present != M3AP_HandoverCancel_IEs__value_PR_Cause || +// ie->value.choice.Cause.present != M3AP_Cause_PR_radioNetwork || +// !(ie->value.choice.Cause.choice.radioNetwork == +// M3AP_CauseRadioNetwork_trelocprep_expiry || +// ie->value.choice.Cause.choice.radioNetwork == +// M3AP_CauseRadioNetwork_tx2relocoverall_expiry)) { +// M3AP_ERROR("%s %d: Cause not supported (only T_reloc_prep and TX2_reloc_overall handled)\n",__FILE__,__LINE__); +// return -1; +// } +// +// switch (ie->value.choice.Cause.choice.radioNetwork) { +// case M3AP_CauseRadioNetwork_trelocprep_expiry: +// cause = M3AP_T_RELOC_PREP_TIMEOUT; +// break; +// case M3AP_CauseRadioNetwork_tx2relocoverall_expiry: +// cause = M3AP_TX2_RELOC_OVERALL_TIMEOUT; +// break; +// default: /* can't come here */ exit(1); +// } +// +// ue_id = m3ap_find_id_from_id_source(&instance_p->id_manager, id_source); +// if (ue_id == -1) { +// M3AP_WARN("Handover cancel: UE not found (id_source = %d), ignoring message\n", id_source); +// return 0; +// } +// +// if (id_target != -1 && +// id_target != m3ap_id_get_id_target(&instance_p->id_manager, ue_id)) { +// M3AP_ERROR("Handover cancel: bad id_target for UE %x (id_source %d) expected %d got %d\n", +// m3ap_id_get_rnti(&instance_p->id_manager, ue_id), +// id_source, +// m3ap_id_get_id_target(&instance_p->id_manager, ue_id), +// id_target); +// exit(1); +// } +// +// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_CANCEL); +// +// M3AP_HANDOVER_CANCEL(msg).rnti = m3ap_id_get_rnti(&instance_p->id_manager, ue_id); +// M3AP_HANDOVER_CANCEL(msg).cause = cause; +// +// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); +// +// m3ap_release_id(&instance_p->id_manager, ue_id); +// +// return 0; +//} diff --git a/openair3/M3AP/m3ap_eNB_handler.h b/openair3/M3AP/m3ap_eNB_handler.h new file mode 100644 index 0000000000..d0c97ac532 --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_handler.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_handler.h + * \brief m3ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_ENB_HANDLERS_H_ +#define M3AP_ENB_HANDLERS_H_ + +#include "m3ap_eNB_defs.h" + +void m3ap_handle_m3_setup_message(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + +#endif /* M3AP_ENB_HANDLERS_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_itti_messaging.c b/openair3/M3AP/m3ap_eNB_itti_messaging.c new file mode 100644 index 0000000000..834b429ccb --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_itti_messaging.c @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_itti_messaging.c + * \brief m3ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +#include "m3ap_eNB_itti_messaging.h" + +void m3ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_M3AP, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m3ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_M3AP, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} diff --git a/openair3/M3AP/m3ap_eNB_itti_messaging.h b/openair3/M3AP/m3ap_eNB_itti_messaging.h new file mode 100644 index 0000000000..134b00e4a9 --- /dev/null +++ b/openair3/M3AP/m3ap_eNB_itti_messaging.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_itti_messaging.h + * \brief m3ap tasks for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_ENB_ITTI_MESSAGING_H_ +#define M3AP_ENB_ITTI_MESSAGING_H_ + +void m3ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + + +void m3ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); + + +#endif /* M3AP_ENB_ITTI_MESSAGING_H_ */ diff --git a/openair3/M3AP/m3ap_encoder.c b/openair3/M3AP/m3ap_encoder.c new file mode 100644 index 0000000000..2e1cbf80af --- /dev/null +++ b/openair3/M3AP/m3ap_encoder.c @@ -0,0 +1,61 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_encoder.c + * \brief m3ap encoder procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" +#include "intertask_interface.h" +#include "m3ap_common.h" +#include "m3ap_encoder.h" + +int m3ap_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + ssize_t encoded; + + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)pdu); + } + + encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, pdu, (void **)buffer); + + if (encoded < 0) { + return -1; + } + + *len = encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, pdu); + return encoded; +} diff --git a/openair3/M3AP/m3ap_encoder.h b/openair3/M3AP/m3ap_encoder.h new file mode 100644 index 0000000000..db444a611e --- /dev/null +++ b/openair3/M3AP/m3ap_encoder.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_encoder.h + * \brief m3ap encoder procedures + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_ENCODER_H_ +#define M3AP_ENCODER_H_ + +int m3ap_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +__attribute__ ((warn_unused_result)); + +#endif /* M3AP_ENCODER_H_ */ diff --git a/openair3/M3AP/m3ap_handler.c b/openair3/M3AP/m3ap_handler.c new file mode 100644 index 0000000000..832aa0dbac --- /dev/null +++ b/openair3/M3AP/m3ap_handler.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_eNB_handler.c + * \brief m3ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "m3ap_common.h" +#include "m3ap_MCE_defs.h" +#include "m3ap_handler.h" +#include "m3ap_decoder.h" +#include "m3ap_ids.h" + +#include "m3ap_MCE_management_procedures.h" +//#include "m3ap_MCE_generate_messages.h" + +#include "m3ap_MME_interface_management.h" +#include "m3ap_MCE_interface_management.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +/* Handlers matrix. Only eNB related procedure present here */ +m3ap_message_decoded_callback m3ap_messages_callback[][3] = { + { MCE_handle_MBMS_SESSION_START_REQUEST, MME_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */ + { MCE_handle_MBMS_SESSION_STOP_REQUEST, MME_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */ + { 0, 0, 0 }, /* Error Indication */ + { 0, 0, 0 }, /* Reset */ + { 0, 0, 0 }, /* ??? */ + { MCE_handle_MBMS_SESSION_UPDATE_REQUEST, MME_handle_MBMS_SESSION_UPDATE_RESPONSE, 0 }, /* MBMSSessionUpdate */ + { 0, 0, 0 }, /* MCEConfigurationUpdate */ + { MME_handle_M3_SETUP_REQUEST, MCE_handle_M3_SETUP_RESPONSE, 0 } /* M3 Setup */ +}; + +char *m3ap_direction2String(int m3ap_dir) { +static char *m3ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(m3ap_direction_String[m3ap_dir]); +} + + +int m3ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + M3AP_M3AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + int i=0; + for( i=0; i < data_length; i++) + printf("%02X",data[i]); + printf("\n"); + + if (m3ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(M3AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( + m3ap_message_decoded_callback)) + || (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(M3AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + LOG_E(M3AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + m3ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(M3AP, "Calling handler with instance %d\n",instance); + ret = (*m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); + return ret; +} + + diff --git a/openair3/M3AP/m3ap_handler.h b/openair3/M3AP/m3ap_handler.h new file mode 100644 index 0000000000..4b01307807 --- /dev/null +++ b/openair3/M3AP/m3ap_handler.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m2ap_handler.h + * \brief m2ap handler procedures for eNB + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M2AP_MCE_OLD_HANDLERS_H_ +#define M2AP_MCE_OLD_HANDLERS_H_ + +#include "m2ap_eNB_defs.h" + +//void m3ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); + +//int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + //const uint8_t * const data, const uint32_t data_length); + +int m3ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + + +#endif /* M2AP_MCE_HANDLERS_H_ */ diff --git a/openair3/M3AP/m3ap_ids.c b/openair3/M3AP/m3ap_ids.c new file mode 100644 index 0000000000..8e0a9f2106 --- /dev/null +++ b/openair3/M3AP/m3ap_ids.c @@ -0,0 +1,128 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "m3ap_ids.h" + +#include + +void m3ap_id_manager_init(m3ap_id_manager *m) +{ + int i; + memset(m, 0, sizeof(m3ap_id_manager)); + for (i = 0; i < M3AP_MAX_IDS; i++) + m->ids[i].rnti = -1; +} + +int m3ap_allocate_new_id(m3ap_id_manager *m) +{ + int i; + for (i = 0; i < M3AP_MAX_IDS; i++) + if (m->ids[i].rnti == -1) { + m->ids[i].rnti = 0; + m->ids[i].id_source = -1; + m->ids[i].id_target = -1; + return i; + } + return -1; +} + +void m3ap_release_id(m3ap_id_manager *m, int id) +{ + m->ids[id].rnti = -1; +} + +int m3ap_find_id(m3ap_id_manager *m, int id_source, int id_target) +{ + int i; + for (i = 0; i < M3AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source && + m->ids[i].id_target == id_target) + return i; + return -1; +} + +int m3ap_find_id_from_id_source(m3ap_id_manager *m, int id_source) +{ + int i; + for (i = 0; i < M3AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source) + return i; + return -1; +} + +int m3ap_find_id_from_rnti(m3ap_id_manager *m, int rnti) +{ + int i; + for (i = 0; i < M3AP_MAX_IDS; i++) + if (m->ids[i].rnti == rnti) + return i; + return -1; +} + +void m3ap_set_ids(m3ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target) +{ + m->ids[ue_id].rnti = rnti; + m->ids[ue_id].id_source = id_source; + m->ids[ue_id].id_target = id_target; +} + +/* real type of target is m3ap_eNB_data_t * */ +void m3ap_id_set_target(m3ap_id_manager *m, int ue_id, void *target) +{ + m->ids[ue_id].target = target; +} + +void m3ap_id_set_state(m3ap_id_manager *m, int ue_id, m3id_state_t state) +{ + m->ids[ue_id].state = state; +} + +void m3ap_set_reloc_prep_timer(m3ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].t_reloc_prep_start = time; +} + +void m3ap_set_reloc_overall_timer(m3ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].tm3_reloc_overall_start = time; +} + +int m3ap_id_get_id_source(m3ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_source; +} + +int m3ap_id_get_id_target(m3ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_target; +} + +int m3ap_id_get_rnti(m3ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].rnti; +} + +void *m3ap_id_get_target(m3ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].target; +} diff --git a/openair3/M3AP/m3ap_ids.h b/openair3/M3AP/m3ap_ids.h new file mode 100644 index 0000000000..bc5a3c3898 --- /dev/null +++ b/openair3/M3AP/m3ap_ids.h @@ -0,0 +1,80 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef M3AP_IDS_H_ +#define M3AP_IDS_H_ + +#include + +/* maximum number of simultaneous handovers, do not set too high */ +#define M3AP_MAX_IDS 16 + +/* + * state: + * - when starting handover in source, UE is in state M3ID_STATE_SOURCE_PREPARE + * - after receiving HO_ack in source, UE is in state M3ID_STATE_SOURCE_OVERALL + * - in target, UE is in state X2ID_STATE_TARGET + * The state is used to check timers. + */ +typedef enum { + M3ID_STATE_SOURCE_PREPARE, + M3ID_STATE_SOURCE_OVERALL, + M3ID_STATE_TARGET +} m3id_state_t; + +typedef struct { + int rnti; /* -1 when free */ + int id_source; + int id_target; + + /* the target eNB. Real type is m3ap_eNB_data_t * */ + void *target; + + /* state: needed to check timers */ + m3id_state_t state; + + /* timers */ + uint64_t t_reloc_prep_start; + uint64_t tm3_reloc_overall_start; +} m3ap_id; + +typedef struct { + m3ap_id ids[M3AP_MAX_IDS]; +} m3ap_id_manager; + +void m3ap_id_manager_init(m3ap_id_manager *m); +int m3ap_allocate_new_id(m3ap_id_manager *m); +void m3ap_release_id(m3ap_id_manager *m, int id); +int m3ap_find_id(m3ap_id_manager *, int id_source, int id_target); +int m3ap_find_id_from_id_source(m3ap_id_manager *, int id_source); +int m3ap_find_id_from_rnti(m3ap_id_manager *, int rnti); +void m3ap_set_ids(m3ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target); +void m3ap_id_set_state(m3ap_id_manager *m, int ue_id, m3id_state_t state); +/* real type of target is m3ap_eNB_data_t * */ +void m3ap_id_set_target(m3ap_id_manager *m, int ue_id, void *target); +void m3ap_set_reloc_prep_timer(m3ap_id_manager *m, int ue_id, uint64_t time); +void m3ap_set_reloc_overall_timer(m3ap_id_manager *m, int ue_id, uint64_t time); +int m3ap_id_get_id_source(m3ap_id_manager *m, int ue_id); +int m3ap_id_get_id_target(m3ap_id_manager *m, int ue_id); +int m3ap_id_get_rnti(m3ap_id_manager *m, int ue_id); +void *m3ap_id_get_target(m3ap_id_manager *m, int ue_id); + +#endif /* M3AP_IDS_H_ */ diff --git a/openair3/M3AP/m3ap_itti_messaging.c b/openair3/M3AP/m3ap_itti_messaging.c new file mode 100644 index 0000000000..b906747640 --- /dev/null +++ b/openair3/M3AP/m3ap_itti_messaging.c @@ -0,0 +1,96 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_MCE_itti_messaging.c + * \brief m3ap tasks for MCE + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#include "intertask_interface.h" + +#include "m3ap_itti_messaging.h" + +void m3ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + //LOG_W(M3AP,"assoc_id %d, stream %d\n",assoc_id,stream); + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m3ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m3ap_MME_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + + +void m3ap_MME_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} diff --git a/openair3/M3AP/m3ap_itti_messaging.h b/openair3/M3AP/m3ap_itti_messaging.h new file mode 100644 index 0000000000..8a4069da9b --- /dev/null +++ b/openair3/M3AP/m3ap_itti_messaging.h @@ -0,0 +1,48 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file m3ap_itti_messaging.h + * \brief m3ap tasks for MME + * \author Javier Morgade + * \date 2019 + * \version 0.1 + */ + +#ifndef M3AP_MCE_ITTI_MESSAGING_H_ +#define M3AP_MCE_ITTI_MESSAGING_H_ + +void m3ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + + +void m3ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); + + +void m3ap_MME_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + + +void m3ap_MME_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); + + + + +#endif /* M3AP_MCE_ITTI_MESSAGING_H_ */ diff --git a/openair3/M3AP/m3ap_timers.c b/openair3/M3AP/m3ap_timers.c new file mode 100644 index 0000000000..39498cc8eb --- /dev/null +++ b/openair3/M3AP/m3ap_timers.c @@ -0,0 +1,105 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "m3ap_timers.h" +#include "assertions.h" +#include "PHY/defs_common.h" /* TODO: try to not include this */ +#include "m3ap_messages_types.h" +#include "m3ap_MCE_defs.h" +#include "m3ap_ids.h" +#include "m3ap_MCE_management_procedures.h" +//#include "m3ap_eNB_generate_messages.h" + +void m3ap_timers_init(m3ap_timers_t *t, int t_reloc_prep, int tm3_reloc_overall) +{ + t->tti = 0; + t->t_reloc_prep = t_reloc_prep; + t->tm3_reloc_overall = tm3_reloc_overall; +} + +void m3ap_check_timers(instance_t instance) +{ + //m3ap_eNB_instance_t *instance_p; + //m3ap_timers_t *t; + //m3ap_id_manager *m; + //int i; + //m3ap_handover_cancel_cause_t cause; + //void *target; + //MessageDef *msg; + //int m2_ongoing; + + //instance_p = m3ap_eNB_get_instance(instance); + //DevAssert(instance_p != NULL); + + //t = &instance_p->timers; + //m = &instance_p->id_manager; + + ///* increment subframe count */ + //t->tti++; + + //m2_ongoing = 0; + + //for (i = 0; i < M3AP_MAX_IDS; i++) { + // if (m->ids[i].rnti == -1) continue; + // m2_ongoing++; + + // if (m->ids[i].state == M2ID_STATE_SOURCE_PREPARE && + // t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) { + // LOG_I(M3AP, "M2 timeout reloc prep\n"); + // /* t_reloc_prep timed out */ + // cause = M3AP_T_RELOC_PREP_TIMEOUT; + // goto timeout; + // } + + // if (m->ids[i].state == M2ID_STATE_SOURCE_OVERALL && + // t->tti > m->ids[i].tm2_reloc_overall_start + t->tm2_reloc_overall) { + // LOG_I(M3AP, "M2 timeout reloc overall\n"); + // /* tm2_reloc_overall timed out */ + // cause = M3AP_TM2_RELOC_OVERALL_TIMEOUT; + // goto timeout; + // } + + // /* no timeout -> check next UE */ + // continue; + + // timeout: + // /* inform target about timeout */ + // target = m3ap_id_get_target(m, i); + // m3ap_eNB_generate_m2_handover_cancel(instance_p, target, i, cause); + + // /* inform RRC of cancellation */ + // msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_CANCEL); + // M3AP_HANDOVER_CANCEL(msg).rnti = m3ap_id_get_rnti(m, i); + // M3AP_HANDOVER_CANCEL(msg).cause = cause; + // itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + // /* remove UE from M3AP */ + // m3ap_release_id(m, i); + //} + + //if (m2_ongoing && t->tti % 1000 == 0) + // LOG_I(M3AP, "M2 has %d process ongoing\n", m2_ongoing); +} + +uint64_t m3ap_timer_get_tti(m3ap_timers_t *t) +{ + return t->tti; +} diff --git a/openair3/M3AP/m3ap_timers.h b/openair3/M3AP/m3ap_timers.h new file mode 100644 index 0000000000..95dcbfc9d9 --- /dev/null +++ b/openair3/M3AP/m3ap_timers.h @@ -0,0 +1,45 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef M3AP_TIMERS_H_ +#define M3AP_TIMERS_H_ + +#include +#include "platform_types.h" + +typedef struct { + /* incremented every TTI (every millisecond when in realtime). + * Used to check timers. + * 64 bits gives us more than 500 million years of (realtime) processing. + * It should be enough. + */ + uint64_t tti; + + /* timer values (unit: TTI, ie. millisecond when in realtime) */ + int t_reloc_prep; + int tm3_reloc_overall; +} m3ap_timers_t; + +void m3ap_timers_init(m3ap_timers_t *t, int t_reloc_prep, int tm3_reloc_overall); +void m3ap_check_timers(instance_t instance); +uint64_t m3ap_timer_get_tti(m3ap_timers_t *t); + +#endif /* M3AP_TIMERS_H_ */ diff --git a/openair3/MME_APP/enb_paramdef_mme.h b/openair3/MME_APP/enb_paramdef_mme.h new file mode 100644 index 0000000000..3d65036553 --- /dev/null +++ b/openair3/MME_APP/enb_paramdef_mme.h @@ -0,0 +1,174 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/enb_paramdef_mce.h + * \brief definition of configuration parameters for MME modules + * \author Javier MORGADE + * \date 2019 + * \version 0.1 + * \company VICOMTECH Spain + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + +#include "common/config/config_paramdesc.h" +#include "RRC_paramsvalues.h" + +#define ENB_CONFIG_STRING_MME_PARAMETERS "mme_parameters" +//#define ENB_CONFIG_STRING_SCHEDULING_INFO_BR "scheduling_info_br" +//#define ENB_CONFIG_STRING_RSRP_RANGE_LIST "rsrp_range_list" +//#define ENB_CONFIG_STRING_PRACH_CONFIG_COMMON_V1310 "prach_ConfigCommon_v1310" +//#define ENB_CONFIG_STRING_MPDCCH_START_SF_CSS_RA_R13 "mpdcch_startSF_CSS_RA_r13" +//#define ENB_CONFIG_STRING_MPDCCH_START_SF_CSS_RA_R13_VAL "mpdcch_startSF_CSS_RA_r13_val" +//#define ENB_CONFIG_STRING_PRACH_HOPPING_OFFSET_R13 "prach_HoppingOffset_r13" +//#define ENB_CONFIG_STRING_SCHEDULING_INFO_SIB1_BR_R13 "schedulingInfoSIB1_BR_r13" +//#define ENB_CONFIG_STRING_CELL_SELECTION_INFO_CE_R13 "cellSelectionInfoCE_r13" +//#define ENB_CONFIG_STRING_Q_RX_LEV_MIN_CE_R13 "q_RxLevMinCE_r13" +//#define ENB_CONFIG_STRING_BANDWIDTH_REDUCED_ACCESS_RELATED_INFO_R13 "bandwidthReducedAccessRelatedInfo_r13" +//#define ENB_CONFIG_STRING_SI_WINDOW_LENGTH_BR_R13 "si_WindowLength_BR_r13" +//#define ENB_CONFIG_STRING_SI_REPETITION_PATTERN_R13 "si_RepetitionPattern_r13" +//#define ENB_CONFIG_STRING_FDD_DOWNLINK_OR_TDD_SUBFRAME_BITMAP_BR_R13 "fdd_DownlinkOrTddSubframeBitmapBR_r13" +//#define ENB_CONFIG_STRING_FDD_DOWNLINK_OR_TDD_SUBFRAME_BITMAP_BR_VAL_R13 "fdd_DownlinkOrTddSubframeBitmapBR_val_r13" +//#define ENB_CONFIG_STRING_START_SYMBOL_BR_R13 "startSymbolBR_r13" +//#define ENB_CONFIG_STRING_SI_HOPPING_CONFIG_COMMON_R13 "si_HoppingConfigCommon_r13" +//#define ENB_CONFIG_STRING_SI_VALIDITY_TIME_R13 "si_ValidityTime_r13" +//#define ENB_CONFIG_STRING_FREQ_HOPPING_PARAMETERS_DL_R13 "freqHoppingParametersDL_r13" +//#define ENB_CONFIG_STRING_MPDCCH_PDSCH_HOPPING_NB_R13 "mpdcch_pdsch_HoppingNB_r13" +//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_A_R13 "interval_DLHoppingConfigCommonModeA_r13" +//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_A_R13_VAL "interval_DLHoppingConfigCommonModeA_r13_val" +//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_B_R13 "interval_DLHoppingConfigCommonModeB_r13" +//#define ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_B_R13_VAL "interval_DLHoppingConfigCommonModeB_r13_val" +//#define ENB_CONFIG_STRING_MPDCCH_PDSCH_HOPPING_OFFSET_R13 "mpdcch_pdsch_HoppingOffset_r13" +//#define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13 "preamble_TransMax_ce_r13" +//#define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13_VAL "preamble_TransMax_ce_r13_val" +//#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13" +//#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13" +//#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" +//#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" +//#define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" +//#define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI" +//#define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13" +//#define ENB_CONFIG_STRING_LAST_PREAMBLE_R13 "lastPreamble_r13" +//#define ENB_CONFIG_STRING_RA_RESPONSE_WINDOW_SIZE_R13 "ra_ResponseWindowSize_r13" +//#define ENB_CONFIG_STRING_MAC_CONTENTION_RESOLUTION_TIMER_R13 "mac_ContentionResolutionTimer_r13" +//#define ENB_CONFIG_STRING_RAR_HOPPING_CONFIG_R13 "rar_HoppingConfig_r13" +//#define ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13 "rach_CE_LevelInfoList_r13" +//#define ENB_CONFIG_STRING_PRACH_CONFIG_INDEX_BR "prach_config_index_br" +//#define ENB_CONFIG_STRING_PRACH_FREQ_OFFSET_BR "prach_freq_offset_br" +//#define ENB_CONFIG_STRING_PRACH_STARTING_SUBFRAME_R13 "prach_StartingSubframe_r13" +//#define ENB_CONFIG_STRING_MAX_NUM_PER_PREAMBLE_ATTEMPT_CE_R13 "maxNumPreambleAttemptCE_r13" +//#define ENB_CONFIG_STRING_NUM_REPETITION_PER_PREAMBLE_ATTEMPT_R13 "numRepetitionPerPreambleAttempt_r13" +//#define ENB_CONFIG_STRING_MPDCCH_NUM_REPETITION_RA_R13 "mpdcch_NumRepetition_RA_r13" +//#define ENB_CONFIG_STRING_PRACH_HOPPING_CONFIG_R13 "prach_HoppingConfig_r13" +//#define ENB_CONFIG_SRING_MAX_AVAILABLE_NARROW_BAND "max_available_narrow_band" +//#define ENB_CONFIG_STRING_PRACH_PARAMETERS_CE_R13 "prach_parameters_ce_r13" +//#define ENB_CONFIG_STRING_PUCCH_INFO_VALUE "pucch_info_value" +//#define ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13 "n1PUCCH_AN_InfoList_r13" +//#define ENB_CONFIG_STRING_PCCH_CONFIG_V1310 "pcch_config_v1310" +//#define ENB_CONFIG_STRING_PAGING_NARROWBANDS_R13 "paging_narrowbands_r13" +//#define ENB_CONFIG_STRING_MPDCCH_NUMREPETITION_PAGING_R13 "mpdcch_numrepetition_paging_r13" +//#define ENB_CONFIG_STRING_NB_V1310 "nb_v1310" +//#define ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13 "sib2_freq_hoppingParameters_r13" + +typedef struct ccparams_MME_s { + /// indicator that eMTC is configured for this cell + int32_t MME_configured; + // /// the SIB2 parameters for eMTC SIB2 + // ccparams_lte_t ccparams; + // int si_Narrowband_r13; + // int si_TBS_r13; + // int systemInfoValueTagSi_r13; + // int firstPreamble_r13; + // int lastPreamble_r13; + // int ra_ResponseWindowSize_r13; + // int mac_ContentionResolutionTimer_r13; + // int rar_HoppingConfig_r13; + // int rsrp_range_br; + // int prach_config_index_br; + // int prach_freq_offset_br; + // int prach_StartingSubframe_r13; + // int maxNumPreambleAttemptCE_r13; + // int numRepetitionPerPreambleAttempt_r13; + // int mpdcch_NumRepetition_RA_r13; + // int prach_HoppingConfig_r13; + // int *maxavailablenarrowband; + // int pucch_info_value; + // int paging_narrowbands_r13; + // int mpdcch_numrepetition_paging_r13; + // int nb_v1310; + // char *pucch_NumRepetitionCE_Msg4_Level0_r13; + // char *pucch_NumRepetitionCE_Msg4_Level1_r13; + // char *pucch_NumRepetitionCE_Msg4_Level2_r13; + // char *pucch_NumRepetitionCE_Msg4_Level3_r13; + // int sib2_mpdcch_pdsch_hoppingNB_r13; + // char *sib2_interval_DLHoppingConfigCommonModeA_r13; + // int sib2_interval_DLHoppingConfigCommonModeA_r13_val; + // char *sib2_interval_DLHoppingConfigCommonModeB_r13; + // int sib2_interval_DLHoppingConfigCommonModeB_r13_val; + // char *sib2_interval_ULHoppingConfigCommonModeA_r13; + // int sib2_interval_ULHoppingConfigCommonModeA_r13_val; + // char *sib2_interval_ULHoppingConfigCommonModeB_r13; + // int sib2_interval_ULHoppingConfigCommonModeB_r13_val; + // int sib2_mpdcch_pdsch_hoppingOffset_r13; + // int pusch_HoppingOffset_v1310; + // int hyperSFN_r13; + // int eDRX_Allowed_r13; + // int q_RxLevMinCE_r13; + // int q_QualMinRSRQ_CE_r13; + // char *si_WindowLength_BR_r13; + // char *si_RepetitionPattern_r13; + // int startSymbolBR_r13; + // char *si_HoppingConfigCommon_r13; + // char *si_ValidityTime_r13; + // char *mpdcch_pdsch_HoppingNB_r13; + // int interval_DLHoppingConfigCommonModeA_r13_val; + // int interval_DLHoppingConfigCommonModeB_r13_val; + // int mpdcch_pdsch_HoppingOffset_r13; + // char *preambleTransMax_CE_r13; + // int prach_HoppingOffset_r13; + // int schedulingInfoSIB1_BR_r13; + // int64_t fdd_DownlinkOrTddSubframeBitmapBR_val_r13; + // char *cellSelectionInfoCE_r13; + // char *bandwidthReducedAccessRelatedInfo_r13; + // char *fdd_DownlinkOrTddSubframeBitmapBR_r13; + // char *fdd_UplinkSubframeBitmapBR_r13; + // char *freqHoppingParametersDL_r13; + // char *interval_DLHoppingConfigCommonModeA_r13; + // char *interval_DLHoppingConfigCommonModeB_r13; + // char *prach_ConfigCommon_v1310; + // char *mpdcch_startSF_CSS_RA_r13; + // char *mpdcch_startSF_CSS_RA_r13_val; + // char *pdsch_maxNumRepetitionCEmodeA_r13; + // char *pdsch_maxNumRepetitionCEmodeB_r13; + // char *pusch_maxNumRepetitionCEmodeA_r13; + // char *pusch_maxNumRepetitionCEmodeB_r13; +} ccparams_MME_t; + + +#define MMEPARAMS_DESC(MMEconfig) { \ + {"MME_configured", NULL, 0, iptr:&MMEconfig->MME_configured, defintval:0, TYPE_UINT, 0} \ +} + +#define MMEPARAMS_CHECK { \ + { .s5= {NULL }} \ +} + diff --git a/openair3/MME_APP/mme_app.c b/openair3/MME_APP/mme_app.c new file mode 100644 index 0000000000..534aec8b34 --- /dev/null +++ b/openair3/MME_APP/mme_app.c @@ -0,0 +1,580 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mme_app.c + ------------------- + AUTHOR : Javier Morgade + COMPANY : VICOMTECH Spain + EMAIL : javier.morgade@ieee.org +*/ + +#include +#include + +#include "mme_app.h" +#include "mme_config.h" +#include "assertions.h" +#include "common/ran_context.h" +#include "targets/RT/USER/lte-softmodem.h" + +#include "common/utils/LOG/log.h" + +# include "intertask_interface.h" +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# include "gtpv1u_eNB_task.h" +# include "flexran_agent.h" + +# include "x2ap_eNB.h" +# include "x2ap_messages_types.h" +# include "m2ap_eNB.h" +# include "m3ap_MME.h" +# include "m2ap_messages_types.h" +//# include "m3ap_eNB.h" +# include "m3ap_messages_types.h" +# define X2AP_ENB_REGISTER_RETRY_DELAY 10 + +#include "openair1/PHY/INIT/phy_init.h" +extern unsigned char NB_MCE_INST; + +extern RAN_CONTEXT_t RC; + +# define MCE_REGISTER_RETRY_DELAY 10 + +#include "targets/RT/USER/lte-softmodem.h" + + + + +/*------------------------------------------------------------------------------*/ + +//static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, uint32_t mce_id_end) { +// uint32_t mce_id; +// MessageDef *msg_p; +// uint32_t register_mce_pending = 0; +// +// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { +// { +// // M3AP registration +// /* note: there is an implicit relationship between the data structure and the message name */ +// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_REGISTER_MCE_REQ); +// //RCconfig_S1(msg_p, mce_id); +// +// //if (mce_id == 0) +// //RCconfig_gtpu(); +// +// //LOG_I(MME_APP,"default drx %d\n",((M3AP_REGISTER_MCE_REQ(msg_p)).default_drx)); +// +// LOG_I(ENB_APP,"[MCE %d] MCE_app_register via M3AP for instance %d\n", mce_id, ENB_MODULE_ID_TO_INSTANCE(mce_id)); +// itti_send_msg_to_task (TASK_M3AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); +// +// //if (NODE_IS_DU(node_type)) { // F1AP registration +// // // configure F1AP here for F1C +// // LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); +// // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); +// // RCconfig_DU_F1(msg_p, enb_id); +// +// // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); +// // itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); +// // // configure GTPu here for F1U +// //} +// //else { // S1AP registration +// // /* note: there is an implicit relationship between the data structure and the message name */ +// // msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); +// // RCconfig_S1(msg_p, enb_id); +// +// // if (enb_id == 0) RCconfig_gtpu(); +// +// // LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx)); +// +// // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); +// // itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); +// //} +// +// register_mce_pending++; +// } +// } +// +// return register_mce_pending; +//} + + +/*------------------------------------------------------------------------------*/ +//static uint32_t MCE_app_register_x2(uint32_t mce_id_start, uint32_t mce_id_end) { +// uint32_t mce_id; +// MessageDef *msg_p; +// uint32_t register_mce_m2_pending = 0; +// +// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { +// { +// msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); +// RCconfig_X2(msg_p, mce_id); +// itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); +// register_mce_x2_pending++; +// } +// } +// +// return register_mce_x2_pending; +//} + +/*------------------------------------------------------------------------------*/ +//static uint32_t MCE_app_register_m2(uint32_t mce_id_start, uint32_t mce_id_end) { +// uint32_t mce_id; +// MessageDef *msg_p; +// uint32_t register_mce_m2_pending = 0; +// +// LOG_W(MME_APP,"Register ..."); +// for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { +// { +// // LOG_W(MME_APP,"Register commes inside ...\n"); +// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_REGISTER_MCE_REQ); +// //RCconfig_M2_MCE(msg_p, mce_id); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); +// // LOG_W(MME_APP,"Register sent ...\n"); +// register_mce_m2_pending++; +// } +// } +// +// return register_mce_m2_pending; +//} +// +// +// +static uint32_t MME_app_handle_m3ap_setup_req(instance_t instance){ + + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_SETUP_RESP); + itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} +static uint32_t MME_app_handle_m3ap_session_start_resp(instance_t instance){ + + + return 0; +} +// +//static uint32_t MME_app_handle_m3ap_session_stop_resp(instance_t instance){ +// +// +// return 0; +//} + + + +// +//static uint32_t MCE_app_send_m2ap_mbms_scheduling_information(instance_t instance){ +// +// uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_MBMS_SCHEDULING_INFORMATION); +// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} +// +static uint32_t MME_app_send_m3ap_session_start_req(instance_t instance){ + + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_START_REQ); + itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} +//static uint32_t MME_app_send_m3ap_session_stop_req(instance_t instance){ +// +// //uint32_t mce_id=0; +// MessageDef *msg_p; +// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_STOP_REQ); +// itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); +// +// return 0; +//} +static uint32_t MME_app_send_m3ap_session_update_req(instance_t instance){ + + //uint32_t mce_id=0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_UPDATE_REQ); + itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); + + return 0; +} +/*------------------------------------------------------------------------------*/ +void *MME_app_task(void *args_p) { + //uint32_t mce_nb = RC.nb_inst; + //uint32_t mce_id_start = 0; + //uint32_t mce_id_end = mce_id_start + mce_nb; + //uint32_t register_mce_pending=0; + //uint32_t registered_mce=0; + //long mce_register_retry_timer_id; + //uint32_t m2_register_mce_pending = 0; + // uint32_t x2_registered_mce = 0; + // long x2_mce_register_retry_timer_id; + // uint32_t m2_register_mce_pending = 0; + // uint32_t m2_registered_mce = 0; + // long m2_mce_register_retry_timer_id; + long m3_mme_register_session_start_timer_id; + MessageDef *msg_p = NULL; + instance_t instance; + int result; + /* for no gcc warnings */ + (void)instance; + itti_mark_task_ready (TASK_MME_APP); + + /* Try to register each MCE */ + // This assumes that node_type of all RRC instances is the same + if (EPC_MODE_ENABLED) { + //register_mce_pending = MCE_app_register(RC.rrc[0]->node_type, mce_id_start, mce_id_end); + } + + /* Try to register each MCE with each other */ + // if (is_x2ap_enabled() && !NODE_IS_DU(RC.rrc[0]->node_type)) { + // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end); + // } + if ( is_m3ap_MME_enabled() ){ + RCconfig_MME(); + } + // /* Try to register each MCE with MCE each other */ + //if (is_m3ap_MME_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) { + //m2_register_mce_pending = MCE_app_register_m2 (mce_id_start, mce_id_end); + //} + + do { + // Wait for a message + itti_receive_msg (TASK_MME_APP, &msg_p); + instance = ITTI_MSG_INSTANCE (msg_p); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(MME_APP, " *** Exiting MME_APP thread\n"); + itti_exit_task (); + break; + + case MESSAGE_TEST: + LOG_I(MME_APP, "MME_APP Received %s\n", ITTI_MSG_NAME(msg_p)); + break; + + case SOFT_RESTART_MESSAGE: + //handle_reconfiguration(instance); + break; + + case M3AP_REGISTER_MCE_CNF: //M3AP_REGISTER_MCE_CNF debería + //AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n"); + // if (EPC_MODE_ENABLED) { + // LOG_I(MME_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + // M3AP_REGISTER_MCE_CNF(msg_p).nb_mme); + // DevAssert(register_mce_pending > 0); + // register_mce_pending--; + + // /* Check if at least MCE is registered with one MME */ + // if (M3AP_REGISTER_MCE_CNF(msg_p).nb_mme > 0) { + // registered_mce++; + // } + + // /* Check if all register MCE requests have been processed */ + // if (register_mce_pending == 0) { + // if (registered_mce == mce_nb) { + // /* If all MCE are registered, start L2L1 task */ + // // MessageDef *msg_init_p; + // // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + // // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + // } else { + // LOG_W(MME_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n", + // mce_nb - registered_mce, MCE_REGISTER_RETRY_DELAY); + + // /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MME_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &mce_register_retry_timer_id) < 0) { + // LOG_E(MME_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n"); + // sleep(MCE_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // registered_mce = 0; + // register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end); + // } + // } + // } + // } /* if (EPC_MODE_ENABLED) */ + + break; + + // case M3AP_SETUP_RESP: + // //AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/MCE\n"); + + // //LOG_I(MME_APP, "Received %s: associated ngran_MCE_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), + // //F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate); + // + // //handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p)); + // handle_m3ap_setup_resp(&M3AP_SETUP_RESP(msg_p)); + + // DevAssert(register_mce_pending > 0); + // register_mce_pending--; + + // /* Check if at least MCE is registered with one MME */ + // //if (M3AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) { + // // registered_enb++; + // //} + + // /* Check if all register MCE requests have been processed */ + // if (register_mce_pending == 0) { + // if (registered_mce == mce_nb) { + // /* If all MCE cells are registered, start L2L1 task */ + // MessageDef *msg_init_p; + + // //msg_init_p = itti_alloc_new_message (TASK_MME_APP, INITIALIZE_MESSAGE); + // //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + + // } else { + // LOG_W(MME_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n", + // mce_nb - registered_mce, MCE_REGISTER_RETRY_DELAY); + + // /* Restart the MCE registration process in MCE_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (MCE_REGISTER_RETRY_DELAY, 0, TASK_MME_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &mce_register_retry_timer_id) < 0) { + // LOG_E(ENB_APP, " Can not start MCE register retry timer, use \"sleep\" instead!\n"); + + // sleep(MCE_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // registered_mce = 0; + // register_mce_pending = MCE_app_register (RC.rrc[0]->node_type,mce_id_start, mce_id_end);//, enb_properties_p); + // } + // } + // } + + // break; + + case M3AP_DEREGISTERED_MCE_IND: //M3AP_DEREGISTERED_MCE_IND debería + if (EPC_MODE_ENABLED) { + LOG_W(MME_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme); + /* TODO handle recovering of registration */ + } + + break; + + case TIMER_HAS_EXPIRED: + //if (EPC_MODE_ENABLED) { + // LOG_I(MME_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); + + // if (TIMER_HAS_EXPIRED (msg_p).timer_id == mce_register_retry_timer_id) { + // /* Restart the registration process */ + // registered_mce = 0; + // //register_mce_pending = MCE_app_register (RC.rrc[0]->node_type, mce_id_start, mce_id_end); + // } + + // //if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_mce_register_retry_timer_id) { + // // /* Restart the registration process */ + // // x2_registered_mce = 0; + // // x2_register_mce_pending = MCE_app_register_x2 (mce_id_start, mce_id_end); + // //} + //} /* if (EPC_MODE_ENABLED) */ + if(TIMER_HAS_EXPIRED(msg_p).timer_id == m3_mme_register_session_start_timer_id){ + MME_app_send_m3ap_session_start_req(0); + } + + break; + + // case X2AP_DEREGISTERED_ENB_IND: + // LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2); + // /* TODO handle recovering of registration */ + // break; + + // case X2AP_REGISTER_ENB_CNF: + // LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // X2AP_REGISTER_ENB_CNF(msg_p).nb_x2); + // DevAssert(x2_register_enb_pending > 0); + // x2_register_enb_pending--; + + // /* Check if at least MCE is registered with one target MCE */ + // if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) { + // x2_registered_enb++; + // } + + // /* Check if all register MCE requests have been processed */ + // if (x2_register_enb_pending == 0) { + // if (x2_registered_enb == enb_nb) { + // /* If all MCE are registered, start RRC HO task */ + // } else { + // uint32_t x2_not_associated = enb_nb - x2_registered_enb; + // LOG_W(ENB_APP, " %d MCE %s not associated with the target\n", + // x2_not_associated, x2_not_associated > 1 ? "are" : "is"); + + // // timer to retry + // /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */ + // if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, + // INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, + // &x2_enb_register_retry_timer_id) < 0) { + // LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n"); + // sleep(X2AP_ENB_REGISTER_RETRY_DELAY); + // /* Restart the registration process */ + // x2_registered_enb = 0; + // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end); + // } + // } + // } + + // break; + + // case M2AP_DEREGISTERED_ENB_IND: + // LOG_W(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2); + // /* TODO handle recovering of registration */ + // break; + + // case M2AP_REGISTER_ENB_CNF: + // LOG_I(ENB_APP, "[MCE %d] Received %s: associated MCE %d\n", instance, ITTI_MSG_NAME (msg_p), + // M2AP_REGISTER_ENB_CNF(msg_p).nb_m2); + // DevAssert(m2_register_enb_pending > 0); + // m2_register_enb_pending--; + + // /* Check if at least MCE is registered with one target MCE */ + // if (M2AP_REGISTER_ENB_CNF(msg_p).nb_m2 > 0) { + // m2_registered_enb++; + // } + + // /* Check if all register MCE requests have been processed */ + // if (m2_register_enb_pending == 0) { + // if (m2_registered_enb == enb_nb) { + // /* If all MCE are registered, start RRC HO task */ + // } else { + // uint32_t m2_not_associated = enb_nb - m2_registered_enb; + // LOG_W(ENB_APP, " %d MCE %s not associated with the target\n", + // m2_not_associated, m2_not_associated > 1 ? "are" : "is"); + + // // timer to retry + // /* Restart the MCE registration process in ENB_REGISTER_RETRY_DELAY seconds */ + // //if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, + // // INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, + // // &x2_enb_register_retry_timer_id) < 0) { + // // LOG_E(ENB_APP, " Can not start MCE X2AP register: retry timer, use \"sleep\" instead!\n"); + // // sleep(X2AP_ENB_REGISTER_RETRY_DELAY); + // // /* Restart the registration process */ + // // x2_registered_enb = 0; + // // x2_register_enb_pending = MCE_app_register_x2 (enb_id_start, enb_id_end); + // //} + // } + // } + + // break; + case M3AP_RESET: + LOG_I(MME_APP,"Received M3AP_RESET message %s\n",ITTI_MSG_NAME(msg_p)); + break; + + case M3AP_SETUP_REQ: + LOG_I(MME_APP,"Received M3AP_REQ message %s\n",ITTI_MSG_NAME(msg_p)); + MME_app_handle_m3ap_setup_req(0); + if(timer_setup(1,0,TASK_MME_APP,INSTANCE_DEFAULT,TIMER_ONE_SHOT,NULL,&m3_mme_register_session_start_timer_id)<0){ + } + //MME_app_send_m3ap_session_start_req(0); + break; + + case M3AP_MBMS_SESSION_START_RESP: + LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_START_RESP message %s\n",ITTI_MSG_NAME(msg_p)); + MME_app_handle_m3ap_session_start_resp(0); + //MME_app_send_m3ap_session_stop_req(0); + break; + + case M3AP_MBMS_SESSION_STOP_RESP: + LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_STOP_RESP message %s\n",ITTI_MSG_NAME(msg_p)); + MME_app_send_m3ap_session_update_req(0); + break; + + case M3AP_MBMS_SESSION_UPDATE_RESP: + LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_UPDATE_RESP message %s\n",ITTI_MSG_NAME(msg_p)); + // trigger something new here !!!!!! + break; + + case M3AP_MBMS_SESSION_UPDATE_FAILURE: + LOG_I(MME_APP,"Received M3AP_MBMS_SESSION_UPDATE_FAILURE message %s\n",ITTI_MSG_NAME(msg_p)); + break; + + case M3AP_MCE_CONFIGURATION_UPDATE: + LOG_I(MME_APP,"Received M3AP_MCE_CONFIGURATION_UPDATE message %s\n",ITTI_MSG_NAME(msg_p)); + break; + + default: + LOG_E(MME_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while (1); + + return NULL; +} + +//void handle_reconfiguration(module_id_t mod_id) { +// struct timespec start, end; +// clock_gettime(CLOCK_MONOTONIC, &start); +// flexran_agent_info_t *flexran = RC.flexran[mod_id]; +// LOG_I(ENB_APP, "lte-softmodem soft-restart requested\n"); +// +// if (ENB_WAIT == flexran->node_ctrl_state) { +// /* this is already waiting, just release */ +// pthread_mutex_lock(&flexran->mutex_node_ctrl); +// flexran->node_ctrl_state = ENB_NORMAL_OPERATION; +// pthread_mutex_unlock(&flexran->mutex_node_ctrl); +// pthread_cond_signal(&flexran->cond_node_ctrl); +// return; +// } +// +// if (stop_L1L2(mod_id) < 0) { +// LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); +// return; +// } +// +// /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not +// * executed by the FlexRAN thread */ +// if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { +// LOG_I(ENB_APP, " * MCE %d: Waiting for FlexRAN RTController command *\n", mod_id); +// pthread_mutex_lock(&flexran->mutex_node_ctrl); +// flexran->node_ctrl_state = ENB_WAIT; +// +// while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) +// pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); +// +// pthread_mutex_unlock(&flexran->mutex_node_ctrl); +// } +// +// if (restart_L1L2(mod_id) < 0) { +// LOG_E(ENB_APP, "can not restart, killing lte-softmodem\n"); +// exit_fun("can not restart L1L2, killing lte-softmodem"); +// return; +// } +// +// clock_gettime(CLOCK_MONOTONIC, &end); +// end.tv_sec -= start.tv_sec; +// +// if (end.tv_nsec >= start.tv_nsec) { +// end.tv_nsec -= start.tv_nsec; +// } else { +// end.tv_sec -= 1; +// end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; +// } +// +// LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); +//} + + diff --git a/openair3/MME_APP/mme_app.h b/openair3/MME_APP/mme_app.h new file mode 100644 index 0000000000..796bfa796c --- /dev/null +++ b/openair3/MME_APP/mme_app.h @@ -0,0 +1,41 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mme_app.h + ------------------- + AUTHOR : Javier Morgade + COMPANY : VICOMTECH Spain + EMAIL : javier.morgade@ieee.org +*/ + +#ifndef MME_APP_H_ +#define MME_APP_H_ + +#include +#include "platform_types.h" + + +void *MME_app_task(void *args_p); + +//void handle_reconfiguration(module_id_t mod_id); + +#endif /* MME_APP_H_ */ diff --git a/openair3/MME_APP/mme_config.c b/openair3/MME_APP/mme_config.c new file mode 100644 index 0000000000..04dba67567 --- /dev/null +++ b/openair3/MME_APP/mme_config.c @@ -0,0 +1,111 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mme_config.c + ------------------- + AUTHOR : Javier Morgade + COMPANY : VICOMTECH, Spain + EMAIL : javier.morgade@ieee.org +*/ + +#include +#include + +#include "common/utils/LOG/log.h" +#include "assertions.h" +#include "mme_config.h" +#include "UTIL/OTG/otg.h" +#include "UTIL/OTG/otg_externs.h" +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" +#include "common/ran_context.h" +#include "sctp_default_values.h" +#include "LTE_SystemInformationBlockType2.h" +#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "PHY/phy_extern.h" +#include "PHY/INIT/phy_init.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "nfapi_vnf.h" +#include "nfapi_pnf.h" + +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "enb_paramdef.h" +#include "proto_agent.h" + +int RCconfig_MME(void ) { + //int num_enbs = 0; + //char *enb_interface_name_for_S1U = NULL; + char *mme_interface_name_for_m3_mce = NULL; + //char *enb_ipv4_address_for_S1U = NULL; + char *mme_ipv4_address_for_m3c = NULL; + //uint32_t enb_port_for_S1U = 0; + uint32_t mme_port_for_m3c = 0; + char *address = NULL; + char *cidr = NULL; + //char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; + char mmepath[MAX_OPTNAME_SIZE*2 + 8]; + //paramdef_t ENBSParams[] = ENBSPARAMS_DESC; + //paramdef_t GTPUParams[] = GTPUPARAMS_DESC; + + paramdef_t MMEParams[] = MME_NETPARAMS_DESC; + + ///* get number of active eNodeBs */ + //config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + //num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; + //AssertFatal (num_enbs >0, + // "Failed to parse config file no active eNodeBs in %s \n", ENB_CONFIG_STRING_ACTIVE_ENBS); + //sprintf(gtpupath,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,0,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + sprintf(mmepath,"%s.[%i].%s","MMEs",0,MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + //config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); + config_get(MMEParams,sizeof(MMEParams)/sizeof(paramdef_t),mmepath); + //cidr = enb_ipv4_address_for_S1U; + cidr = mme_ipv4_address_for_m3c; + address = strtok(cidr, "/"); + + //LOG_W(MME_APP,"cidr %s\n",cidr); + //LOG_W(MME_APP,"address %s\n",address); + //LOG_W(MME_APP,"mme_interface_name_for_m3_mce %s\n",mme_interface_name_for_m3_mce); + //LOG_W(MME_APP,"mme_ipv4_address_for_m3c %s\n",mme_ipv4_address_for_m3c); + //LOG_W(MME_APP,"mme_port_for_m3c %d\n",mme_port_for_m3c); + + if (address) { + MessageDef *message; + AssertFatal((message = itti_alloc_new_message(TASK_MME_APP, M3AP_MME_SCTP_REQ))!=NULL,""); + M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv6 = 0; + M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4 = 1; + strcpy( M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4_address, address); + LOG_I(MME_APP,"Configuring M3_C address : %s\n",address/*,M3AP_MME_SCTP_REQ(message).mme_m3_ip_address*/); + M3AP_MME_SCTP_REQ(message).mme_port_for_M3C = mme_port_for_m3c; + itti_send_msg_to_task (TASK_M3AP_MME, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + } else + LOG_E(MCE_APP,"invalid address for M2AP\n"); + + + + return 0; +} + diff --git a/openair3/MME_APP/mme_config.h b/openair3/MME_APP/mme_config.h new file mode 100644 index 0000000000..97b2fae032 --- /dev/null +++ b/openair3/MME_APP/mme_config.h @@ -0,0 +1,52 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + mme_config.h + AUTHOR : Javier Morgade + COMPANY : Vicomtech, Spain + EMAIL : javier.morgade@ieee.org +*/ + +#ifndef MME_CONFIG_H_ +#define MME_CONFIG_H_ +#include +#include +#include +#include + +#include "commonDef.h" +#include "platform_types.h" +#include "platform_constants.h" +#include "PHY/impl_defs_lte.h" +#include "PHY/defs_eNB.h" +#include "s1ap_messages_types.h" +#include "f1ap_messages_types.h" +#include "LTE_SystemInformationBlockType2.h" +#include "rrc_messages_types.h" +#include "RRC/LTE/rrc_defs.h" +#include +#include "enb_paramdef.h" + +int RCconfig_MME(void); + +#endif /* MME_CONFIG_H_ */ +/** @} */ From 2bd1e119dd823564c5a11bad7a512ad853fe6884 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:58:47 +0200 Subject: [PATCH 020/134] missing file ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair3/COMMON/messages_types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair3/COMMON/messages_types.h b/openair3/COMMON/messages_types.h index 56a16da554..f91881bf11 100644 --- a/openair3/COMMON/messages_types.h +++ b/openair3/COMMON/messages_types.h @@ -38,5 +38,7 @@ #include "sgw_lite_messages_types.h" #include "udp_messages_types.h" #include "mme_app_messages_types.h" +#include "m2ap_messages_types.h" + #endif /* MESSAGES_TYPES_H_ */ From 334e3a57efa04be79779b5728265da9ed9c82cd6 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 13:59:53 +0200 Subject: [PATCH 021/134] 1. Reference config file defined with basic MBMS configuration stuff 2. Dedicated MBMS tasks manager: -If MBMS gets enabled through softmodem config file it will launch SCTP task (to check with S1 interface) 3. "On the flight" dynamic RU configuration update mechanism implemented ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- .../rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf | 417 ++++++++++++++++++ cmake_targets/CMakeLists.txt | 176 +++++++- targets/COMMON/create_tasks.h | 1 + targets/COMMON/create_tasks_mbms.c | 148 +++++++ targets/COMMON/create_tasks_mbms.h | 34 ++ targets/RT/USER/lte-enb.c | 2 + targets/RT/USER/lte-ru.c | 8 + targets/RT/USER/lte-softmodem.c | 2 + targets/RT/USER/ru_control.c | 56 +++ 9 files changed, 836 insertions(+), 8 deletions(-) create mode 100644 ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf create mode 100644 targets/COMMON/create_tasks_mbms.c create mode 100644 targets/COMMON/create_tasks_mbms.h diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf new file mode 100644 index 0000000000..cda4c0a461 --- /dev/null +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf @@ -0,0 +1,417 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 2; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -104; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "DISABLE" + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.3"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + + ////////// MCE parameters: + target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///M2 + enable_enb_m2 = "yes"; + + + mbms_configuration_data_list = ( + { + mbsfn_sync_area = 0x0001; + mbms_service_area_list=( + { + mbms_service_area=0x0001; + } + ); + } + + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; + ENB_PORT_FOR_M2C = 36443; # Spec 36443 + }; + } +); + +MCEs = ( + { + MCE_ID = 0xe00; + + MCE_name = "MCE-Vicomtech-LTEBox"; + + //M2 + enable_mce_m2 = "yes"; + + //M3 + enable_mce_m3 = "yes"; + + target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + + NETWORK_INTERFACES : + { + #ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + #ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + #ENB_INTERFACE_NAME_FOR_S1U = "lo"; + #ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + #ENB_IPV4_ADDRESS_FOR_S1U = "224.10.10.10/24"; + #ENB_PORT_FOR_S1U = 2152; # Spec 2152 + #ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + #ENB_PORT_FOR_X2C = 36422; # Spec 36422 + #ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; + #ENB_PORT_FOR_M2C = 36443; # Spec 36443 + MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; + MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; + MCE_PORT_FOR_M2C = 36443; # Spec 36443 + + MCE_INTERFACE_NAME_FOR_M3_MME = "lo"; + MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; + MCE_PORT_FOR_M3C = 36444; # Spec 36444 + #MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.8/24"; + #MME_PORT_FOR_M3C = 36444; # Spec 36444 + + }; + + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + }; + + mbms_sched_info : + { + mcch_update_time = 10; + mbms_area_config_list = ( + { + common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6) + mbms_area_id = 0; + pmch_config_list = ( + { + allocated_sf_end=32; + data_mcs=14; + mch_scheduling_period = 0; #rf8(0) + mbms_session_list = ( + { + #plnm + service_id ->tmgi + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + } + service_id=0; #keep this allways as 0 (workaround for TUN if) + lcid=6; #this must be properly defined lcid:8+service:0 -> rab_id:8 + } + ); + } + ); + + mbms_sf_config_list = ( + { + radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) + radioframe_alloocation_offset=0; + num_frame="oneFrame"; + subframe_allocation=57; #xx100000 + //num_frame="fourFrame"; + //subframe_allocation=14548987; # + } + ); + + } + ); + }; + + + mcch_config_per_mbsfn_area = ( + { + mbsfn_area = 0; + pdcch_length = 1; #s1(0), s2(1) + repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3) + offset = 0; + modification_period = 0; #rf512(0; rf1024(1) + subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100101 + mcs = 1; #n2(0), n7(1), n13(2), n19(3) + } + // , + // { + // mbsfn_area = 0; + // pdcch_length = 0; #s1(0), s2(1) + // repetition_period = 2; #rf32(0), rf64(1), rf128(2), rf256(3) + // offset = 0; + // modification_period = 1; #rf512(0; rf1024(1) + // subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000 + // mcs = 0; #n2(0), n7(1), n13(2), n19(3) + // } + + ); + #); #end mbms_scheduling_info + + } +); +MMEs = ( + { + MME_ID = 0xe00; + + MME_name = "MME-MBMS-Vicomtech-LTEBox"; + + //M3 + enable_mme_m3 = "yes"; + NETWORK_INTERFACES : + { + #ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + #ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + #ENB_INTERFACE_NAME_FOR_S1U = "lo"; + #ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + #ENB_IPV4_ADDRESS_FOR_S1U = "224.10.10.10/24"; + #ENB_PORT_FOR_S1U = 2152; # Spec 2152 + #ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + #ENB_PORT_FOR_X2C = 36422; # Spec 36422 + #ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; + #ENB_PORT_FOR_M2C = 36443; # Spec 36443 + #MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; + #MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; + #MCE_PORT_FOR_M2C = 36443; # Spec 36443 + + MME_INTERFACE_NAME_FOR_M3_MCE = "lo"; + #MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; + #MCE_PORT_FOR_M3C = 36444; # Spec 36444 + MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24"; + MME_PORT_FOR_M3C = 36444; # Spec 36444 + + }; + } +); + + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "no" + tr_preference = "udp_if4p5" + nb_tx = 2 + nb_rx = 2 + att_tx = 0 + att_rx = 0; + eNB_instances = [0]; + is_slave = "no"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; +}; diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0a20060af8..5c999e353a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -405,6 +405,145 @@ add_library(S1AP_ENB ) add_dependencies(S1AP_ENB rrc_flag s1ap_flag) + +#M2AP +# Same limitation as described in RRC/S1AP: unknown generated file list +# so we generate it at cmake time +############## +add_list1_option(M2AP_RELEASE R14 "M2AP ASN.1 grammar version" R14) + +set(M2AP_DIR ${OPENAIR2_DIR}/M2AP) +if (${M2AP_RELEASE} STREQUAL "R8") + make_version(M2AP_VERSION 8 9 0) + set(M2AP_ASN_FILES m2ap-8.9.0.asn1) +elseif (${M2AP_RELEASE} STREQUAL "R11") + make_version(M2AP_VERSION 11 9 0) + set(M2AP_ASN_FILES m2ap-11.9.0.asn1) +elseif (${M2AP_RELEASE} STREQUAL "R12") + make_version(M2AP_VERSION 12 9 0) + set(M2AP_ASN_FILES m2ap-12.9.0.asn1) +elseif (${M2AP_RELEASE} STREQUAL "R14") + make_version(M2AP_VERSION 14 0 0) + set(M2AP_ASN_FILES m2ap-14.0.0.asn1) +elseif (${M2AP_RELEASE} STREQUAL "R15") + make_version(M2AP_VERSION 15 1 0) + set(M2AP_ASN_FILES m2ap-15.1.0.asn1) +endif(${M2AP_RELEASE} STREQUAL "R8") +add_definitions(-DM2AP_VERSION=${M2AP_VERSION}) +set(M2AP_ASN_DIR ${M2AP_DIR}/MESSAGES/ASN1/${M2AP_RELEASE}) +set(M2AP_C_DIR ${asn1_generated_dir}/M2AP_${M2AP_RELEASE}) + +# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make +execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}" "M2AP_" -fno-include-deps -DEMIT_ASN_DEBUG=1 + RESULT_VARIABLE ret) +if (NOT ${ret} STREQUAL 0) + message(FATAL_ERROR "${ret}: error") +endif (NOT ${ret} STREQUAL 0) + +file(GLOB M2AP_source ${M2AP_C_DIR}/*.c) + +add_custom_target ( + m2_flag ALL + COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}" "M2AP_" -fno-include-deps + DEPENDS ${M2AP_ASN_DIR}/${M2AP_ASN_FILES} + ) + +add_library(M2AP_LIB + ${M2AP_source} + ${M2AP_DIR}/m2ap_common.c + ) +add_dependencies(M2AP_LIB rrc_flag m2_flag) + +include_directories ("${M2AP_C_DIR}") +include_directories ("${M2AP_DIR}") + +add_library(M2AP_ENB + ${M2AP_DIR}/m2ap_eNB.c + ${M2AP_DIR}/m2ap_MCE.c + ${M2AP_DIR}/m2ap_decoder.c + ${M2AP_DIR}/m2ap_encoder.c + ${M2AP_DIR}/m2ap_MCE_handler.c + ${M2AP_DIR}/m2ap_eNB_handler.c + ${M2AP_DIR}/m2ap_itti_messaging.c + ${M2AP_DIR}/m2ap_eNB_management_procedures.c + ${M2AP_DIR}/m2ap_eNB_generate_messages.c + ${M2AP_DIR}/m2ap_MCE_management_procedures.c + ${M2AP_DIR}/m2ap_MCE_generate_messages.c + ${M2AP_DIR}/m2ap_ids.c + ${M2AP_DIR}/m2ap_timers.c + ${M2AP_DIR}/m2ap_MCE_interface_management.c + ${M2AP_DIR}/m2ap_eNB_interface_management.c + ) +add_dependencies(M2AP_ENB rrc_flag m2_flag) + +#M3AP +# Same limitation as described in RRC/S1AP: unknown generated file list +# so we generate it at cmake time +############## +add_list1_option(M3AP_RELEASE R14 "M3AP ASN.1 grammar version" R14) + +set(M3AP_DIR ${OPENAIR3_DIR}/M3AP) +if (${M3AP_RELEASE} STREQUAL "R8") + make_version(M3AP_VERSION 8 9 0) + set(M3AP_ASN_FILES m3ap-8.9.0.asn1) +elseif (${M3AP_RELEASE} STREQUAL "R11") + make_version(M3AP_VERSION 11 9 0) + set(M3AP_ASN_FILES m3ap-11.9.0.asn1) +elseif (${M3AP_RELEASE} STREQUAL "R12") + make_version(M3AP_VERSION 12 9 0) + set(M3AP_ASN_FILES m3ap-12.9.0.asn1) +elseif (${M3AP_RELEASE} STREQUAL "R14") + make_version(M3AP_VERSION 14 0 0) + set(M3AP_ASN_FILES m3ap-14.0.0.asn1) +elseif (${M3AP_RELEASE} STREQUAL "R15") + make_version(M3AP_VERSION 15 1 0) + set(M3AP_ASN_FILES m3ap-15.1.0.asn1) +endif(${M3AP_RELEASE} STREQUAL "R8") +add_definitions(-DM3AP_VERSION=${M3AP_VERSION}) +set(M3AP_ASN_DIR ${M3AP_DIR}/MESSAGES/ASN1/${M3AP_RELEASE}) +set(M3AP_C_DIR ${asn1_generated_dir}/M3AP_${M3AP_RELEASE}) + +# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make +execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}" "M3AP_" -fno-include-deps + RESULT_VARIABLE ret) +if (NOT ${ret} STREQUAL 0) + message(FATAL_ERROR "${ret}: error") +endif (NOT ${ret} STREQUAL 0) + +file(GLOB M3AP_source ${M3AP_C_DIR}/*.c) + +add_custom_target ( + m3_flag ALL + COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}" "M3AP_" -fno-include-deps + DEPENDS ${M3AP_ASN_DIR}/${M3AP_ASN_FILES} + ) + +add_library(M3AP_LIB + ${M3AP_source} + ${M3AP_DIR}/m3ap_common.c + ) +add_dependencies(M3AP_LIB rrc_flag m3_flag) + +include_directories ("${M3AP_C_DIR}") +include_directories ("${M3AP_DIR}") + +add_library(M3AP_ENB + ${M3AP_DIR}/m3ap_decoder.c + ${M3AP_DIR}/m3ap_encoder.c + ${M3AP_DIR}/m3ap_MCE_handler.c + ${M3AP_DIR}/m3ap_MME_handler.c + ${M3AP_DIR}/m3ap_MME.c + ${M3AP_DIR}/m3ap_MME_management_procedures.c + ${M3AP_DIR}/m3ap_MME_interface_management.c + ${M3AP_DIR}/m3ap_MCE.c + ${M3AP_DIR}/m3ap_MCE_management_procedures.c + ${M3AP_DIR}/m3ap_MCE_interface_management.c + ${M3AP_DIR}/m3ap_itti_messaging.c + ${M3AP_DIR}/m3ap_ids.c + ${M3AP_DIR}/m3ap_timers.c + ) +add_dependencies(M3AP_ENB rrc_flag m3_flag) + #X2AP # Same limitation as described in RRC/S1AP: unknown generated file list # so we generate it at cmake time @@ -763,6 +902,7 @@ include_directories("${OPENAIR1_DIR}") include_directories("${OPENAIR2_DIR}") include_directories("${OPENAIR3_DIR}/NAS/TOOLS") include_directories("${OPENAIR2_DIR}/ENB_APP") +include_directories("${OPENAIR2_DIR}/MCE_APP") include_directories("${OPENAIR2_DIR}/LAYER2/RLC") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0") @@ -785,9 +925,12 @@ include_directories("${OPENAIR3_DIR}/SECU") include_directories("${OPENAIR3_DIR}/SCTP") include_directories("${OPENAIR3_DIR}/S1AP") include_directories("${OPENAIR2_DIR}/X2AP") +include_directories("${OPENAIR2_DIR}/M2AP") include_directories("${OPENAIR2_DIR}/F1AP") include_directories("${OPENAIR3_DIR}/UDP") include_directories("${OPENAIR3_DIR}/GTPV1-U") +include_directories("${OPENAIR3_DIR}/M3AP") +include_directories("${OPENAIR3_DIR}/MME_APP") include_directories("${OPENAIR_DIR}/targets/COMMON") include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY") @@ -1371,6 +1514,7 @@ set(L2_SRC # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_S1AP.c + ${RRC_DIR}/rrc_eNB_M2AP.c ${RRC_DIR}/rrc_eNB_UE_context.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface.c @@ -1461,12 +1605,20 @@ set (ENB_APP_SRC ${OPENAIR2_DIR}/ENB_APP/RRC_config_tools.c ) + +set (MCE_APP_SRC + ${OPENAIR2_DIR}/MCE_APP/mce_app.c + ${OPENAIR2_DIR}/MCE_APP/mce_config.c + ) + + add_library(L2 ${L2_SRC} ${MAC_SRC} - ${ENB_APP_SRC}) + ${ENB_APP_SRC} + ${MCE_APP_SRC}) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) -add_dependencies(L2 rrc_flag s1ap_flag x2_flag) +add_dependencies(L2 rrc_flag s1ap_flag x2_flag m2_flag m3_flag) add_library(L2_UE ${L2_SRC_UE} @@ -1500,6 +1652,13 @@ set (GTPV1U_SRC add_library(GTPV1U ${GTPV1U_SRC}) add_dependencies(GTPV1U rrc_flag) +set (MME_APP_SRC + ${OPENAIR3_DIR}/MME_APP/mme_app.c + ${OPENAIR3_DIR}/MME_APP/mme_config.c +) +add_library(MME_APP ${MME_APP_SRC}) +add_dependencies(MME_APP rrc_flag s1ap_flag x2_flag m2_flag m3_flag) + set(SCTP_SRC ${OPENAIR3_DIR}/SCTP/sctp_common.c ${OPENAIR3_DIR}/SCTP/sctp_eNB_task.c @@ -2070,6 +2229,7 @@ add_executable(lte-softmodem ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c @@ -2089,7 +2249,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 + RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2157,7 +2317,7 @@ add_executable(lte-uesoftmodem add_dependencies(lte-uesoftmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-uesoftmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2236,7 +2396,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) add_executable(test_epc_play_scenario @@ -2255,7 +2415,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) @@ -2291,12 +2451,12 @@ if (${T_TRACER}) dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim ulsim cu_test du_test #all "add_library" definitions - ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP + ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_eth_transpro FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA SECU_CN SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY L2 default_sched - remote_sched RAL CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS + remote_sched RAL CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX coding) if (TARGET ${i}) add_dependencies(${i} generate_T) diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h index ff1d9ace51..339f4aaa8f 100644 --- a/targets/COMMON/create_tasks.h +++ b/targets/COMMON/create_tasks.h @@ -28,6 +28,7 @@ extern void *l2l1_task(void *arg); int create_tasks(uint32_t enb_nb); int create_tasks_ue(uint32_t ue_nb); +int create_tasks_mbms(uint32_t enb_nb); #endif #endif /* CREATE_TASKS_H_ */ diff --git a/targets/COMMON/create_tasks_mbms.c b/targets/COMMON/create_tasks_mbms.c new file mode 100644 index 0000000000..5f81592b96 --- /dev/null +++ b/targets/COMMON/create_tasks_mbms.c @@ -0,0 +1,148 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +# include "intertask_interface.h" +# include "create_tasks.h" +# include "common/utils/LOG/log.h" +# include "targets/RT/USER/lte-softmodem.h" +# include "common/ran_context.h" + +#ifdef OPENAIR2 + #include "sctp_eNB_task.h" + #include "x2ap_eNB.h" + #include "s1ap_eNB.h" + #include "udp_eNB_task.h" + #include "gtpv1u_eNB_task.h" + #include "m2ap_eNB.h" + #include "m2ap_MCE.h" + #include "m3ap_MME.h" + #include "m3ap_MCE.h" + #if ENABLE_RAL + #include "lteRALue.h" + #include "lteRALenb.h" + #endif + #include "RRC/LTE/rrc_defs.h" +#endif +# include "f1ap_cu_task.h" +# include "f1ap_du_task.h" +# include "enb_app.h" +# include "mce_app.h" +# include "mme_app.h" + +//extern RAN_CONTEXT_t RC; + +int create_tasks_mbms(uint32_t enb_nb) { + // LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb); + // ngran_node_t type = RC.rrc[0]->node_type; + int rc; + + if (enb_nb == 0) return 0; + + if(!EPC_MODE_ENABLED){ + rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for SCTP failed\n"); + } + + + LOG_I(MME_APP, "Creating MME_APP eNB Task\n"); + rc = itti_create_task (TASK_MME_APP, MME_app_task, NULL); + AssertFatal(rc >= 0, "Create task for MME APP failed\n"); + + if (is_m3ap_MME_enabled()) { + rc = itti_create_task(TASK_M3AP_MME, m3ap_MME_task, NULL); + AssertFatal(rc >= 0, "Create task for M3AP MME failed\n"); + } + + LOG_I(MCE_APP, "Creating MCE_APP eNB Task\n"); + rc = itti_create_task (TASK_MCE_APP, MCE_app_task, NULL); + AssertFatal(rc >= 0, "Create task for MCE APP failed\n"); + + +// LOG_I(ENB_APP, "Creating ENB_APP eNB Task\n"); +// rc = itti_create_task (TASK_ENB_APP, eNB_app_task, NULL); +// AssertFatal(rc >= 0, "Create task for eNB APP failed\n"); +// +// LOG_I(RRC,"Creating RRC eNB Task\n"); +// rc = itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL); +// AssertFatal(rc >= 0, "Create task for RRC eNB failed\n"); +// +// if (EPC_MODE_ENABLED) { +// rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); +// AssertFatal(rc >= 0, "Create task for SCTP failed\n"); +// } +// rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); +// AssertFatal(rc >= 0, "Create task for SCTP failed\n"); +// +// +// if (EPC_MODE_ENABLED && !NODE_IS_DU(type)) { +// rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL); +// AssertFatal(rc >= 0, "Create task for S1AP failed\n"); +// if (!(get_softmodem_params()->emulate_rf)){ +// rc = itti_create_task(TASK_UDP, udp_eNB_task, NULL); +// AssertFatal(rc >= 0, "Create task for UDP failed\n"); +// } +// rc = itti_create_task(TASK_GTPV1_U, gtpv1u_eNB_task, NULL); +// AssertFatal(rc >= 0, "Create task for GTPV1U failed\n"); +// if (is_x2ap_enabled()) { +// rc = itti_create_task(TASK_X2AP, x2ap_task, NULL); +// AssertFatal(rc >= 0, "Create task for X2AP failed\n"); +// } else { +// LOG_I(X2AP, "X2AP is disabled.\n"); +// } +// } +//// + if(!EPC_MODE_ENABLED){ + // rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); + // AssertFatal(rc >= 0, "Create task for SCTP failed\n"); + rc = itti_create_task(TASK_UDP, udp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for UDP failed\n"); + rc = itti_create_task(TASK_GTPV1_U, gtpv1u_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for GTPV1U failed\n"); + } +/// +// if (NODE_IS_CU(type)) { +// rc = itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL); +// AssertFatal(rc >= 0, "Create task for CU F1AP failed\n"); +// } +// +// if (NODE_IS_DU(type)) { +// rc = itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL); +// AssertFatal(rc >= 0, "Create task for DU F1AP failed\n"); +// } +// + + if (is_m3ap_MCE_enabled()) { + rc = itti_create_task(TASK_M3AP_MCE, m3ap_MCE_task, NULL); + AssertFatal(rc >= 0, "Create task for M3AP MCE failed\n"); + + } + if (is_m2ap_MCE_enabled()) { + rc = itti_create_task(TASK_M2AP_MCE, m2ap_MCE_task, NULL); + AssertFatal(rc >= 0, "Create task for M2AP failed\n"); + } + + if (is_m2ap_eNB_enabled()) { + rc = itti_create_task(TASK_M2AP_ENB, m2ap_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for M2AP failed\n"); + } + + return 0; +} diff --git a/targets/COMMON/create_tasks_mbms.h b/targets/COMMON/create_tasks_mbms.h new file mode 100644 index 0000000000..339f4aaa8f --- /dev/null +++ b/targets/COMMON/create_tasks_mbms.h @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef CREATE_TASKS_H_ +#define CREATE_TASKS_H_ + +#if defined(ENABLE_ITTI) +/* External declaration of L2L1 task that depend on the target */ +extern void *l2l1_task(void *arg); + +int create_tasks(uint32_t enb_nb); +int create_tasks_ue(uint32_t ue_nb); +int create_tasks_mbms(uint32_t enb_nb); +#endif + +#endif /* CREATE_TASKS_H_ */ diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 1ad25febac..3cb1171782 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1280,6 +1280,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); eNB->if_inst->schedule_response = schedule_response; eNB->if_inst->PHY_config_req = phy_config_request; + eNB->if_inst->PHY_config_update_sib2_req = phy_config_update_sib2_request; + eNB->if_inst->PHY_config_update_sib13_req = phy_config_update_sib13_request; memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); memset((void *)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); LOG_I(PHY,"Setting indication lists\n"); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 89abd12499..06be260f1d 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1800,6 +1800,14 @@ void *ru_thread( void *param ) { #endif // wakeup all eNB processes waiting for this RU if (ru->num_eNB>0) wakeup_L1s(ru); + + //Workaround ... this must be properly handled + if(ru->if_south!=LOCAL_RF && RC.eNB[0][0]!=NULL){ + if(ru->frame_parms.num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){ + ru->frame_parms = RC.eNB[0][0]->frame_parms;//->frame_parms; + LOG_W(PHY,"RU MBSFN SF PARAMS Updated\n"); + } + } #ifndef PHY_TX_THREAD diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 70b458a7fe..1bc02f358c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -708,6 +708,8 @@ int main( int argc, char **argv ) { pthread_mutex_unlock(&sync_mutex); config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); } + create_tasks_mbms(1); + // wait for end of program LOG_UI(ENB_APP,"TYPE TO TERMINATE\n"); // CI -- Flushing the std outputs for the previous marker to show on the eNB / DU / CU log file diff --git a/targets/RT/USER/ru_control.c b/targets/RT/USER/ru_control.c index 0f043c8fa3..2b4ba05689 100644 --- a/targets/RT/USER/ru_control.c +++ b/targets/RT/USER/ru_control.c @@ -493,6 +493,27 @@ void configure_rru(int idx, } +static int send_update_rru(RU_t * ru, LTE_DL_FRAME_PARMS * fp){ + //ssize_t msg_len/*,len*/; + int i; + //LTE_DL_FRAME_PARMS *fp = &RC.eNB[0][0]->frame_parms; + RRU_CONFIG_msg_t rru_config_msg; + memset((void *)&rru_config_msg,0,sizeof(rru_config_msg)); + rru_config_msg.type = RRU_config_update; + rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); + LOG_I(PHY,"Sending RAU tick to RRU %d %lu bytes\n",ru->idx,rru_config_msg.len); + + RRU_config_t *config = (RRU_config_t *)&rru_config_msg.msg[0]; + config->num_MBSFN_config=fp->num_MBSFN_config; + for(i=0; i < fp->num_MBSFN_config; i++){ + config->MBSFN_config[i] = fp->MBSFN_config[i]; + LOG_W(PHY,"Configuration send to RAU (num MBSFN %d, MBSFN_SubframeConfig[%d] pattern is %x )\n",config->num_MBSFN_config,i,config->MBSFN_config[i].mbsfn_SubframeConfig); + + } + AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), + "RU %d cannot access remote radio\n",ru->idx); + return 0; +} void* ru_thread_control( void* param ) { @@ -502,6 +523,7 @@ void* ru_thread_control( void* param ) { RRU_CONFIG_msg_t rru_config_msg; ssize_t msg_len; int len; + int ru_sf_update=0; // SF config update flag (MBSFN) // Start IF device if any if (ru->start_if) { @@ -523,6 +545,16 @@ void* ru_thread_control( void* param ) { if (ru->state == RU_IDLE && ru->if_south != LOCAL_RF) send_tick(ru); + if (ru->state == RU_RUN && ru->if_south != LOCAL_RF){ + LTE_DL_FRAME_PARMS *fp = &RC.eNB[0][0]->frame_parms; + LOG_D(PHY,"Check MBSFN SF changes\n"); + if(fp->num_MBSFN_config != ru_sf_update){ + ru_sf_update = fp->num_MBSFN_config; + LOG_W(PHY,"RU SF should be updated ... calling send_update_rru(ru)\n"); + send_update_rru(ru,fp); + } + } + if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, @@ -656,6 +688,30 @@ void* ru_thread_control( void* param ) { } } break; + case RRU_config_update: //RRU + if (ru->if_south == LOCAL_RF){ + LOG_W(PHY,"Configuration update received from RAU \n"); + + msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); + + LOG_W(PHY,"New MBSFN config received from RAU --- num_MBSFN_config %d\n",((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config); + ru->frame_parms.num_MBSFN_config = ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config; + for(int i=0; i < ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config; i++){ + ru->frame_parms.MBSFN_config[i].mbsfn_SubframeConfig=((RRU_config_t *)&rru_config_msg.msg[0])->MBSFN_config[i].mbsfn_SubframeConfig; + LOG_W(PHY,"Configuration received from RAU (num MBSFN %d, MBSFN_SubframeConfig[%d] pattern is %x )\n", + ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config, + i, + ((RRU_config_t *)&rru_config_msg.msg[0])->MBSFN_config[i].mbsfn_SubframeConfig + ); + } + } else LOG_E(PHY,"Received RRU_config msg...Ignoring\n"); + break; + case RRU_config_update_ok: //RAU + if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_config_update_ok msg...Ignoring\n"); + else{ + LOG_W(PHY,"Received RRU_config_update_ok msg...\n"); + } + break; case RRU_start: // RRU if (ru->if_south == LOCAL_RF){ From de96a823652b4fea9af94c035f6cbb9b69115bc1 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 14:12:05 +0200 Subject: [PATCH 022/134] -Dissable temporary some features at RU -Refence config file cleanup ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- .../rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf | 46 ++----------------- targets/RT/USER/lte-ru.c | 4 ++ 2 files changed, 7 insertions(+), 43 deletions(-) diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf index cda4c0a461..c9d96f27b5 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf @@ -221,16 +221,6 @@ MCEs = ( NETWORK_INTERFACES : { - #ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - #ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; - #ENB_INTERFACE_NAME_FOR_S1U = "lo"; - #ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; - #ENB_IPV4_ADDRESS_FOR_S1U = "224.10.10.10/24"; - #ENB_PORT_FOR_S1U = 2152; # Spec 2152 - #ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; - #ENB_PORT_FOR_X2C = 36422; # Spec 36422 - #ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; - #ENB_PORT_FOR_M2C = 36443; # Spec 36443 MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; MCE_PORT_FOR_M2C = 36443; # Spec 36443 @@ -238,9 +228,6 @@ MCEs = ( MCE_INTERFACE_NAME_FOR_M3_MME = "lo"; MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; MCE_PORT_FOR_M3C = 36444; # Spec 36444 - #MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.8/24"; - #MME_PORT_FOR_M3C = 36444; # Spec 36444 - }; plnm: @@ -272,7 +259,7 @@ MCEs = ( mnc_length = 2; } service_id=0; #keep this allways as 0 (workaround for TUN if) - lcid=6; #this must be properly defined lcid:8+service:0 -> rab_id:8 + lcid=6; #this must be properly defined lcid:6+service:0 -> rab_id:6 } ); } @@ -283,7 +270,7 @@ MCEs = ( radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) radioframe_alloocation_offset=0; num_frame="oneFrame"; - subframe_allocation=57; #xx100000 + subframe_allocation=57; #xx111001 //num_frame="fourFrame"; //subframe_allocation=14548987; # } @@ -301,20 +288,9 @@ MCEs = ( repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3) offset = 0; modification_period = 0; #rf512(0; rf1024(1) - subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100101 + subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000 mcs = 1; #n2(0), n7(1), n13(2), n19(3) } - // , - // { - // mbsfn_area = 0; - // pdcch_length = 0; #s1(0), s2(1) - // repetition_period = 2; #rf32(0), rf64(1), rf128(2), rf256(3) - // offset = 0; - // modification_period = 1; #rf512(0; rf1024(1) - // subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000 - // mcs = 0; #n2(0), n7(1), n13(2), n19(3) - // } - ); #); #end mbms_scheduling_info @@ -330,23 +306,7 @@ MMEs = ( enable_mme_m3 = "yes"; NETWORK_INTERFACES : { - #ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - #ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; - #ENB_INTERFACE_NAME_FOR_S1U = "lo"; - #ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; - #ENB_IPV4_ADDRESS_FOR_S1U = "224.10.10.10/24"; - #ENB_PORT_FOR_S1U = 2152; # Spec 2152 - #ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; - #ENB_PORT_FOR_X2C = 36422; # Spec 36422 - #ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; - #ENB_PORT_FOR_M2C = 36443; # Spec 36443 - #MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; - #MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; - #MCE_PORT_FOR_M2C = 36443; # Spec 36443 - MME_INTERFACE_NAME_FOR_M3_MCE = "lo"; - #MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; - #MCE_PORT_FOR_M3C = 36444; # Spec 36444 MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24"; MME_PORT_FOR_M3C = 36444; # Spec 36444 diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 06be260f1d..988d1e5be7 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -107,6 +107,8 @@ static int DEFENBS[] = {0}; #include "pdcp.h" +//#define MBMS_EXPERIMENTAL + extern volatile int oai_exit; extern int emulate_rf; extern int numerology; @@ -1801,6 +1803,7 @@ void *ru_thread( void *param ) { // wakeup all eNB processes waiting for this RU if (ru->num_eNB>0) wakeup_L1s(ru); +#ifdef MBMS_EXPERIMENTAL //Workaround ... this must be properly handled if(ru->if_south!=LOCAL_RF && RC.eNB[0][0]!=NULL){ if(ru->frame_parms.num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){ @@ -1808,6 +1811,7 @@ void *ru_thread( void *param ) { LOG_W(PHY,"RU MBSFN SF PARAMS Updated\n"); } } +#endif #ifndef PHY_TX_THREAD From 8565b28a3118d19d774c061434060f9873c2e4fb Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 14:40:34 +0200 Subject: [PATCH 023/134] LOG level decreassed BUGIFX PDCP MBMS PIPE ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair1/PHY/INIT/lte_init.c | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 4 ++-- openair2/M2AP/m2ap_MCE_management_procedures.c | 8 ++++---- openair2/X2AP/x2ap_eNB_management_procedures.c | 4 ++-- openair3/M3AP/m3ap_MCE_management_procedures.c | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index b483c2cbe0..7f377fcd49 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -357,7 +357,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config) { int CC_id = phy_config->CC_id; nfapi_config_request_t *cfg = phy_config->cfg; - LOG_E(PHY,"configure sib3 Mod_id(%d), CC_id(%d) cfg %p\n",Mod_id,CC_id,cfg); + LOG_I(PHY,"configure sib3 Mod_id(%d), CC_id(%d) cfg %p\n",Mod_id,CC_id,cfg); LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; LOG_I (PHY, "[eNB%d] Applying MBSFN_Area_id %d for index %d\n", Mod_id, (uint16_t)cfg->embms_sib13_config.mbsfn_area_id_r9.value, (uint8_t)cfg->embms_sib13_config.mbsfn_area_idx.value); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 9ad57db7a1..c5b481e27f 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -272,8 +272,8 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p //pdcp_t *pdcp_p = NULL; int len; rb_id_t rab_id = mbms_rab_id;//DEFAULT_RAB_ID; - //if(mbms_rab_id > 9 || mbms_rab_id < 4) - //h_rc = 2; + if(mbms_rab_id > 9 || mbms_rab_id < 4) + h_rc = 2; if(UE_NAS_USE_TUN) return 0; diff --git a/openair2/M2AP/m2ap_MCE_management_procedures.c b/openair2/M2AP/m2ap_MCE_management_procedures.c index 007340501a..3934a57c74 100644 --- a/openair2/M2AP/m2ap_MCE_management_procedures.c +++ b/openair2/M2AP/m2ap_MCE_management_procedures.c @@ -116,9 +116,9 @@ void dump_mce_trees_m2(void) m2ap_MCE_instance_t *zz; STAILQ_FOREACH(zz, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) { -printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +//printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); dump_mce_tree_m2(zz->m2ap_mce_head.rbh_root); -printf("---------------------------------------------\n"); +//printf("---------------------------------------------\n"); } } @@ -129,8 +129,8 @@ struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p, struct m2ap_MCE_data_s temp; struct m2ap_MCE_data_s *found; -printf("m2ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); -dump_mce_trees_m2(); +//printf("m2ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +//dump_mce_trees_m2(); memset(&temp, 0, sizeof(struct m2ap_MCE_data_s)); diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c index 986ca10902..469a76a261 100644 --- a/openair2/X2AP/x2ap_eNB_management_procedures.c +++ b/openair2/X2AP/x2ap_eNB_management_procedures.c @@ -129,8 +129,8 @@ struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p, struct x2ap_eNB_data_s temp; struct x2ap_eNB_data_s *found; -printf("x2ap_get_eNB at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); -dump_trees(); +//printf("x2ap_get_eNB at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +//dump_trees(); memset(&temp, 0, sizeof(struct x2ap_eNB_data_s)); diff --git a/openair3/M3AP/m3ap_MCE_management_procedures.c b/openair3/M3AP/m3ap_MCE_management_procedures.c index 106d211f10..32901ca869 100644 --- a/openair3/M3AP/m3ap_MCE_management_procedures.c +++ b/openair3/M3AP/m3ap_MCE_management_procedures.c @@ -129,8 +129,8 @@ struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p, struct m3ap_MCE_data_s temp; struct m3ap_MCE_data_s *found; -printf("m3ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); -dump_trees_m3(); +//printf("m3ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id); +//dump_trees_m3(); memset(&temp, 0, sizeof(struct m3ap_MCE_data_s)); From 9393ad95bf3945c95c153e52da976b631116ad7b Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 14 Sep 2019 15:57:14 +0200 Subject: [PATCH 024/134] commit just to trigger CI again: looks no commercial UEs were connected during the test ? ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf index c9d96f27b5..5daaa8d13a 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf @@ -292,6 +292,7 @@ MCEs = ( mcs = 1; #n2(0), n7(1), n13(2), n19(3) } ); + #); #end mbms_scheduling_info } From ae4beed07df2165044f3b50f2805ad1f5f96ed37 Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Javier Morgade" Date: Mon, 16 Sep 2019 09:41:08 +0200 Subject: [PATCH 025/134] BUGFIX ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 552e870c59..763da2f15e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -669,7 +669,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } TBS = - get_TBS_DL(cc->pmch_Config[0]->dataMCS_r9/*cc->MCH_pdu.mcs*/, to_prb(cc->mib->message.dl_Bandwidth)); + get_TBS_DL(/*cc->pmch_Config[0]->dataMCS_r9*/cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // do not let mcch and mtch multiplexing when relaying is active // for sync area 1, so not transmit data From 4405275bb3997a9e7351ea38724e7fd5e24bedc7 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 16 Sep 2019 12:13:59 +0200 Subject: [PATCH 026/134] MBMS UE/eNB scheduler adjustments to avoid RLC misalignments and false MTCH detections ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 7 ++++--- openair2/LAYER2/MAC/ue_procedures.c | 15 ++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 763da2f15e..31f685e906 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -504,6 +504,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint8_t num_sf_alloc=0; for( int iii=0; iii < 6; iii++) num_sf_alloc += ( 0x39 & (0x80>>iii)) == (0x80 >> iii); + num_sf_alloc = 1; // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC @@ -734,13 +735,13 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS %d pmch_stop %d msi_sfs %d\n", MTCH, frameP, subframeP, rlc_status.bytes_in_buffer,TBS,msi_pmch_stop,msi_sfs); - if (rlc_status.bytes_in_buffer > 0 /*&& msi_pmch_stop > 0*/ /*msi_pmch_stop>=num_sf_alloc*/ ) { + if (rlc_status.bytes_in_buffer > 0 || msi_pmch_stop > 0 /*msi_pmch_stop>=num_sf_alloc*/ ) { //if(rlc_status.bytes_in_buffer > 0){ LOG_I(MAC, - "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n", + "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d) rlc_status.bytes_in_buffer %d\n", module_idP, CC_id, frameP, TBS - header_len_mcch - header_len_msi - - sdu_length_total - header_len_mtch, header_len_mtch); + sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer); sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, 0, //not used (char *) diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index c58b2a937a..db8f715636 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -1400,23 +1400,24 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ for (j = 0; j < 6; j++) num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j)); + //num_sf_alloc=1; } for (l = 0; l < 28; l++) { - if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= num_sf_alloc) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= 1/*num_sf_alloc*/) { if (UE_mac_inst[module_idP].pmch_stop_mtch[l] != 2047) { if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL){ mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationPeriod; long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; if(UE_mac_inst[module_idP].common_num_sf_alloc >= UE_mac_inst[module_idP].pmch_stop_mtch[l]){ - //LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc); + //LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc); + mtch_mcs = -1; - } - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period); - - + }/*else + LOG_W(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);*/ + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period); } else mtch_mcs = -1; From cad6e8a274518dcf46c2a3174044b1ed5bb312bd Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 16 Sep 2019 13:59:27 +0200 Subject: [PATCH 027/134] Enable MBMS USRP E2E operation -reference config files updated ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- .../enb.band17.tm1.25PRB.usrpb210.conf | 273 ++++++++++++ .../enb.band17.tm1.mbms.25PRB.usrpb210.conf | 417 ++++++++++++++++++ targets/RT/USER/lte-ru.c | 4 +- 3 files changed, 692 insertions(+), 2 deletions(-) create mode 100644 ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf create mode 100644 ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf diff --git a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf new file mode 100644 index 0000000000..db1c5eae2a --- /dev/null +++ b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf @@ -0,0 +1,273 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + // In seconds + rrc_inactivity_threshold = 30; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 17; + downlink_frequency = 736000000L; + uplink_frequency_offset = -30000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -25; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "eth0"; + FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf new file mode 100644 index 0000000000..fbb8c5d6f8 --- /dev/null +++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf @@ -0,0 +1,417 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + // In seconds + rrc_inactivity_threshold = 30; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 17; + downlink_frequency = 736000000L; + uplink_frequency_offset = -30000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -25; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + ///M2 + target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_enb_m2 = "yes"; + + mbms_configuration_data_list = ( + { + mbsfn_sync_area = 0x0001; + mbms_service_area_list=( + { + mbms_service_area=0x0001; + } + ); + } + + ); + + + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; + ENB_PORT_FOR_M2C = 36443; # Spec 36443 + }; + } +); + +MCEs = ( + { + MCE_ID = 0xe00; + + MCE_name = "MCE-Vicomtech-LTEBox"; + + //M2 + enable_mce_m2 = "yes"; + + //M3 + enable_mce_m3 = "yes"; + + target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + + NETWORK_INTERFACES : + { + MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; + MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; + MCE_PORT_FOR_M2C = 36443; # Spec 36443 + + MCE_INTERFACE_NAME_FOR_M3_MME = "lo"; + MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; + MCE_PORT_FOR_M3C = 36444; # Spec 36444 + }; + + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + }; + + mbms_sched_info : + { + mcch_update_time = 10; + mbms_area_config_list = ( + { + common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6) + mbms_area_id = 0; + pmch_config_list = ( + { + allocated_sf_end=64; + data_mcs=10; + mch_scheduling_period = 0; #rf8(0) + mbms_session_list = ( + { + #plnm + service_id ->tmgi + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + } + service_id=0; + lcid=8; #this must be properly defined lcid:8+service:0 -> rab_id:8 + } + ); + } + ); + + mbms_sf_config_list = ( + { + radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) + radioframe_alloocation_offset=0; + num_frame="oneFrame"; + subframe_allocation=57; #xx100000 + //num_frame="fourFrame"; + //subframe_allocation=14548987; # + } + + ); + + } + ); + }; + mcch_config_per_mbsfn_area = ( + { + mbsfn_area = 0; + pdcch_length = 1; #s1(0), s2(1) + repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3) + offset = 0; + modification_period = 0; #rf512(0; rf1024(1) + subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100101 + mcs = 0; #n2(0), n7(1), n13(2), n19(3) + } + ); + #); #end mbms_scheduling_info + + } +); + + +MMEs = ( + { + MME_ID = 0xe00; + + MME_name = "MME-MBMS-Vicomtech-LTEBox"; + + //M3 + enable_mme_m3 = "yes"; + NETWORK_INTERFACES : + { + MME_INTERFACE_NAME_FOR_M3_MCE = "lo"; + MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24"; + MME_PORT_FOR_M3C = 36444; # Spec 36444 + + }; + } +); + + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "eth0"; + FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 988d1e5be7..b75ac502b8 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -107,7 +107,7 @@ static int DEFENBS[] = {0}; #include "pdcp.h" -//#define MBMS_EXPERIMENTAL +#define MBMS_EXPERIMENTAL extern volatile int oai_exit; extern int emulate_rf; @@ -1805,7 +1805,7 @@ void *ru_thread( void *param ) { #ifdef MBMS_EXPERIMENTAL //Workaround ... this must be properly handled - if(ru->if_south!=LOCAL_RF && RC.eNB[0][0]!=NULL){ + if(ru->if_south==LOCAL_RF && ru->function==eNodeB_3GPP && RC.eNB[0][0]!=NULL){ if(ru->frame_parms.num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){ ru->frame_parms = RC.eNB[0][0]->frame_parms;//->frame_parms; LOG_W(PHY,"RU MBSFN SF PARAMS Updated\n"); From 5f29a4e5a0706c01d2fb5b4cfd32f2e9e833705d Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 16 Sep 2019 22:36:50 +0200 Subject: [PATCH 028/134] Code cleanup -Removing unused files ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/M2AP/m2ap_MCE_interface_management.c | 490 +-------- openair2/M2AP/m2ap_eNB_interface_management.c | 66 -- openair3/M3AP/m3ap_eNB_decoder.c | 155 --- openair3/M3AP/m3ap_eNB_decoder.h | 35 - openair3/M3AP/m3ap_eNB_encoder.c | 61 -- openair3/M3AP/m3ap_eNB_encoder.h | 35 - openair3/M3AP/m3ap_eNB_generate_messages.c | 804 -------------- openair3/M3AP/m3ap_eNB_generate_messages.h | 63 -- openair3/M3AP/m3ap_eNB_handler.c | 985 ------------------ openair3/M3AP/m3ap_eNB_handler.h | 39 - openair3/M3AP/m3ap_eNB_itti_messaging.c | 62 -- openair3/M3AP/m3ap_eNB_itti_messaging.h | 39 - 12 files changed, 2 insertions(+), 2832 deletions(-) delete mode 100644 openair3/M3AP/m3ap_eNB_decoder.c delete mode 100644 openair3/M3AP/m3ap_eNB_decoder.h delete mode 100644 openair3/M3AP/m3ap_eNB_encoder.c delete mode 100644 openair3/M3AP/m3ap_eNB_encoder.h delete mode 100644 openair3/M3AP/m3ap_eNB_generate_messages.c delete mode 100644 openair3/M3AP/m3ap_eNB_generate_messages.h delete mode 100644 openair3/M3AP/m3ap_eNB_handler.c delete mode 100644 openair3/M3AP/m3ap_eNB_handler.h delete mode 100644 openair3/M3AP/m3ap_eNB_itti_messaging.c delete mode 100644 openair3/M3AP/m3ap_eNB_itti_messaging.h diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c index 903e395197..cb8f48bf34 100644 --- a/openair2/M2AP/m2ap_MCE_interface_management.c +++ b/openair2/M2AP/m2ap_MCE_interface_management.c @@ -568,19 +568,6 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_configuration_list); -//------------- - - - - -// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); -//------------- -//------------- - -// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie+1); -//------------- - - /* xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie); xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_Item,mbsfn_area_configuration_item_ie_1); @@ -593,323 +580,14 @@ ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_conf ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - // LOG_D(M2AP,"%p\n",&pdu); - // LOG_D(M2AP,"%p\n",out); - // LOG_D(M2AP,"%p\n",ie); - // LOG_D(M2AP,"%p\n",mbsfn_area_configuration_item_ie); - // LOG_D(M2AP,"%p\n",&mbsfn_area_configuration_item_ie->value.choice); - // { - // /* PMCH_Configuration_List */ - // - // M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; - // pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); - // { - // pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; - // pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; - // pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; - // M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; - // pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; - // { - // //pmch_configuration_item->allocatedSubframesEnd; - // pmch_configuration_item->pmch_Configuration.dataMCS=13; - // //pmch_configuration_item->mchSchedulingPeriod; - // MBMSsessionListPerPMCH_Item__Member *member; - // member = (MBMSsessionListPerPMCH_Item__Member*)calloc(1,sizeof(MBMSsessionListPerPMCH_Item__Member)); - // LOG_D(M2AP,"%p,%p,%p\n",pmch_configuration_item,&pmch_configuration_item->mbms_Session_List.list,member); - // ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,member); - // } - // //// - // // //ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies); - // - // } - // - // M2AP_PMCH_Configuration_List_t * pmch_list = &mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List; - // - // ASN_SEQUENCE_ADD(&pmch_list->list,pmch_configuration_item_ies); - // LOG_D(M2AP,"%p,%p\n",&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); - // //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); - // //ASN_SET_ADD(&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); - // //ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies); - - // /* MBSFN_Subframe_ConfigurationList */ - // M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configurationitem; - // mbsfn_subframe_configurationitem =(M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t)); - // { - // mbsfn_subframe_configurationitem->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item; - // mbsfn_subframe_configurationitem->criticality = M2AP_Criticality_reject; - // mbsfn_subframe_configurationitem->value.present=M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration; - // } - // - // //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configurationitem); - // LOG_D(M2AP,"%p,%p\n",&mbsfn_area_configuration_item_ie->value.choice.PMCH_Configuration_List.list,mbsfn_subframe_configurationitem); - // //ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item_ie->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configurationitem); -//// -//// M2AP_Common_Subframe_Allocation_Period_t * common_subframe_allocation_period; -//// M2AP_MBSFN_Area_ID_t * mbsfn_area_id; - // } - // LOG_D(M2AP,"%p,%p\n",&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); - // //ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); - // ASN_SET_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie); - - // M2AP_MBSFN_Area_Configuration_Item_t *mbsfn_area_configuration_item_ie_2; - // mbsfn_area_configuration_item_ie_2 =(M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); - // { - // // mbsfn_area_configuration_item_ie->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List; - // /* PMCH_Configuration_List */ - // // M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; - // // pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); - // // pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; - // // pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; - // // pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; - // // M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; - // // pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; - // //// - // // ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie,pmch_configuration_item_ies); - - // /* MBSFN_Subframe_ConfigurationList */ - // M2AP_MBSFN_Subframe_ConfigurationItem_t * mbsfn_subframe_configurationitem; - // mbsfn_subframe_configurationitem =(M2AP_MBSFN_Subframe_ConfigurationItem_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_ConfigurationItem_t)); - // { - // mbsfn_subframe_configurationitem->id = M2AP_ProtocolIE_ID_id_MBSFN_Subframe_Configuration_Item; - // mbsfn_subframe_configurationitem->criticality = M2AP_Criticality_reject; - // mbsfn_subframe_configurationitem->value.present=M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration; - // //M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration; - // //mbsfn_subframe_configuration = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t)); - // //ASN_SEQUENCE_ADD(mbsfn_subframe_configurationitem,mbsfn_subframe_configuration); - // M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration; - // mbsfn_subframe_configuration = &mbsfn_subframe_configurationitem->value.choice.MBSFN_Subframe_Configuration; - // } - // - // ASN_SEQUENCE_ADD(mbsfn_area_configuration_item_ie_2,mbsfn_subframe_configurationitem); - - // } - - // ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item_ie_2); - - - -// M2AP_MBSFN_Area_Configuration_List_t * m2ap_mbsfn_area_configuration_list; -// m2ap_mbsfn_area_configuration_list = &ie->value.choice.MBSFN_Area_Configuration_List; -// { -// M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; -// pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); -// pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; -// pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; -// pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; -// M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; -// pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; -// -// ASN_SEQUENCE_ADD(&m2ap_mbsfn_area_configuration_list->PMCH_Configuration_List.list,pmch_configuration_item_ies); -// } -// -// int num_mbsfn_available =0; // ? -// LOG_I(M2AP, "num_mbsfn_available = %d \n", num_mbsfn_available); -// for (i=0; -// iid = M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_Item; -// //mbms_configuration_data_item_ies>criticality = M2AP_Criticality_reject; -// //mbms_mbsfn_area_configuration_item_ies->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_M2AP_MBSFN_Area_Configuration_Item; -// -// M2AP_MBSFN_Area_Configuration_Item_t * mbsfn_area_configuration_item; -// mbsfn_area_configuration_item = (M2AP_MBSFN_Area_Configuration_Item_t*)calloc(1,sizeof(M2AP_MBSFN_Area_Configuration_Item_t)); -// //mbsfn_area_configuration_item = &mbms_mbsfn_area_configuration_item_ies->value.choice.M2AP_MBSFN_Area_Configuration_Item; -// mbsfn_area_configuration_item->value.present = M2AP_MBSFN_Area_Configuration_Item__value_PR_PMCH_Configuration_List; -// -// M2AP_PMCH_Configuration_ItemIEs_t * pmch_configuration_item_ies; -// pmch_configuration_item_ies = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); -// pmch_configuration_item_ies->id = M2AP_ProtocolIE_ID_id_PMCH_Configuration_Item; -// pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; -// pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; -// M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; -// pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; -// //memset((void*)&pmch_configuration_item,0,sizeof(M2AP_PMCH_Configuration_Item_t)); -// -// ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); -//// if(0) -//// { -//// /* PMCH_Configuration_List */ -//// LOG_I(M2AP, "num_pmch_available = %d \n", num_mbsfn_available); -//// int num_pmch_available =0; // ? -//// for (j=0; -//// jid = (M2AP_PMCH_Configuration_ItemIEs_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_ItemIEs_t)); -//// pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; -//// pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; -//// -//// M2AP_PMCH_Configuration_Item_t * pmch_configuration_item; -//// //pmch_configuration_item = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t)); -//// pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; -//// { -//// /* PMCH_Configuration */ -//// /* allocateSubframesEnd */ -//// //pmch_configuration_item.pmch_Configuration.allocatedSubframesEnd=; -//// /* dataMCS */ -//// //pmch_configuration_item.pmch_Configuration.dataMCS=; -//// /* MCH_Scheduling_Period*/ -//// //pmch_configuration_item.pmch_Configuration.mchSchedulingPeriod=; -//// -//// /* MBMSsessionListPerPMCH */ -//// LOG_I(M2AP, "num_mbms_session_available = %d \n", num_mbsfn_available); -//// int num_mbms_session_available =1; // ? -//// for(k=0; -//// ktmgi=; -//// //session_list_per_pmch_item->lcid=; -//// //ASN_SEQUENCE_ADD(&pmch_configuration_item->mbms_Session_List.list,mbsfn_area_configuration_item); -//// } -//// -//// } -//// ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.PMCH_Configuration_List.list,pmch_configuration_item_ies); -//// } -//// -//// /* MBSFN_Subframe_ConfigurationList */ -//// int num_mbsfn_subframe_available=0; -//// for(j=0; -//// jMBSFN_Subframe_Configuration.radioframeAllocationPeriod=; -//// //mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.radioframeAllocationOffset=; -//// //mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.subframeAllocation.oneFrame=; -//// //mbsfn_subframe_configuration_item->MBSFN_Subframe_Configuration.subframeAllocation.fourFrames=; -//// -//// ASN_SEQUENCE_ADD(&mbsfn_area_configuration_item->value.choice.MBSFN_Subframe_ConfigurationList.list,mbsfn_subframe_configuration_item); -//// -//// } -//// /* Common_subframe_Allocation_Period */ -//// mbsfn_area_configuration_item->value.choice.Common_Subframe_Allocation_Period=0; -//// /* MBSFN_Area_ID */ -//// mbsfn_area_configuration_item->value.choice.MBSFN_Area_ID=0; -//// /*MBMS_Suspension_Notification_List*/ -//// //TODO -//// } -// //ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List.list,mbsfn_area_configuration_item); -// ASN_SEQUENCE_ADD(&m2ap_mbsfn_area_configuration_list->list,mbsfn_area_configuration_item); -// -// } - - + /* encode */ if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){ return -1; } - /*if (m2ap_encode_pdu(&pdu,&buffer,&len) < 0){ - return -1; - }*/ - - /*buffer = &m2ap_message[0]; - len = 62; - for(int i=0; i < len; i++ ) - printf("%02X",buffer[i]); - printf("\n");*/ - - - //printf("m2ap_mce_data_from_enb %p %p %d\n",m2ap_mce_data_from_enb, buffer, len); - m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); return 0; - - -// buffer2 = &m2ap_message[0]; -// len2 = 62; -// for(int i=0; i < len2; i++ ) -// printf("%02X",buffer2[i]); -// printf("\n"); -// -// M2AP_M2AP_PDU_t pdu2; -// memset(&pdu2, 0, sizeof(pdu2)); -// if (m2ap_decode_pdu(&pdu2, buffer2, len2) < 0) { -// LOG_E(M2AP, "SCHEDULING Failed to decode PDU\n"); -// //return -1; -// }else{ -// LOG_D(M2AP, "SCHEDULING OK to decode PDU\n"); -// } -// -// -// M2AP_MbmsSchedulingInformation_t *container2; -// M2AP_MbmsSchedulingInformation_Ies_t *ie2; -// int i2 = 0; -// container2 = &pdu2.choice.initiatingMessage.value.choice.MbmsSchedulingInformation; -// M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie2, container2,M2AP_ProtocolIE_ID_id_MCCH_Update_Time ,true); -// LOG_D(M2AP, "SCHEDULING id %d\n",ie2->id); -// M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MbmsSchedulingInformation_Ies_t, ie2, container2,M2AP_ProtocolIE_ID_id_MBSFN_Area_Configuration_List ,true); -// LOG_D(M2AP, "SCHEDULING id %d\n",ie2->id); -// -// -// -// //M2AP_MBSFN_Area_Configuration_Item_t * kk = &ie->value.choice.MBSFN_Area_Configuration_List.list.array[0]; -// //printf("M2AP_MBSFN_Area_Configuration_Item %d\n",kk->id); -// -// const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID((void*)&ie2->value.choice.MBSFN_Area_Configuration_List); -// void * memb_ptr = list->array[0]; -// const asn_anonymous_sequence_ *list2 = _A_CSEQUENCE_FROM_VOID((void*)memb_ptr); -// -// -// void * memb_ptr1 = list2->array[0]; -// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item1 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr1; -// M2AP_PMCH_Configuration_Item_t * m2ap_pmchconfiguration_item =&(((M2AP_PMCH_Configuration_ItemIEs_t*)m2ap_mbsfn_area_configuration_item1->value.choice.PMCH_Configuration_List.list.array[0])->value.choice.PMCH_Configuration_Item); -// printf("dataMCS %d\n",m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS); -// m2ap_pmchconfiguration_item->pmch_Configuration.dataMCS=4; -// printf("allocatedSubframesEnd %d\n",m2ap_pmchconfiguration_item->pmch_Configuration.allocatedSubframesEnd); -// M2AP_PMCH_Configuration_t * m2ap_pmchconfiguration = &m2ap_pmchconfiguration_item->pmch_Configuration; -// printf("M2AP_PMCH_Configuration_t dataMCS %d\n",m2ap_pmchconfiguration->dataMCS); -// printf("M2AP_PMCH_Configuration_t allocatedSubframesEnd %d\n",m2ap_pmchconfiguration->allocatedSubframesEnd); -// M2AP_MBMSsessionListPerPMCH_Item_t * m2ap_mbsfnsessionlistperPMCH = &m2ap_pmchconfiguration_item->mbms_Session_List; -// M2AP_TMGI_t * tmgi = &m2ap_mbsfnsessionlistperPMCH->list.array[0]->tmgi; -// M2AP_PLMN_Identity_t * pLMNidentity = &tmgi->pLMNidentity; -// MCC_MNC_TO_PLMNID(0,1,3/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/ -// ,pLMNidentity); -// -// -// OCTET_STRING_t * serviceID = &tmgi->serviceID; -// M2AP_LCID_t * lcid = &m2ap_mbsfnsessionlistperPMCH->list.array[0]->lcid; //long -// -// -// void * memb_ptr2 = list2->array[1]; -// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item2 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr2; -// M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_subframe_configuration_item =&(((M2AP_MBSFN_Subframe_ConfigurationItem_t*)m2ap_mbsfn_area_configuration_item2->value.choice.MBSFN_Subframe_ConfigurationList.list.array[0])->value.choice.MBSFN_Subframe_Configuration); -// //M2AP_MBSFN_Subframe_Configuration_t * m2ap_mbsfn_subframe_configuration = &m2ap_mbsfn_subframe_configuration_item->value.choice.MBSFN_Subframe_Configuration; -// printf("oneframe ? %d\n",(m2ap_mbsfn_subframe_configuration_item->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame)); -// -// -// void * memb_ptr3 = list2->array[2]; -// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item3 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr3; -// M2AP_Common_Subframe_Allocation_Period_t * m2ap_mbsfn_common_subframe_allocation_period = (M2AP_Common_Subframe_Allocation_Period_t*)m2ap_mbsfn_area_configuration_item3->value.choice.Common_Subframe_Allocation_Period; -// -// void * memb_ptr4 = list2->array[3]; -// M2AP_MBSFN_Area_Configuration_Item_t * m2ap_mbsfn_area_configuration_item4 = (M2AP_MBSFN_Area_Configuration_Item_t*)memb_ptr4; -// M2AP_MBSFN_Area_ID_t * m2ap_mbsfn_area_id = (M2AP_MBSFN_Area_ID_t*)m2ap_mbsfn_area_configuration_item4->value.choice.MBSFN_Area_ID; -// -// -// -// //ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,list); -// ASN_SEQUENCE_ADD(&ie->value.choice.MBSFN_Area_Configuration_List,m2ap_mbsfn_area_configuration_list); -// -// LOG_D(M2AP,"Morgade\n"); -// xer_fprint(stdout,&asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List); -// -// /* encode */ -// if (m2ap_encode_pdu(&pdu2,&buffer,&len) < 0){ -// return -1; -// } -// -// //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_mce->assoid,buffer,len,0); -// m2ap_MCE_itti_send_sctp_data_req(instance,assoc_id,buffer,len,0); -// return 0; -// -// } @@ -1290,89 +968,9 @@ int MCE_send_M2_SETUP_RESPONSE(instance_t instance, /*uint32_t assoc_id,*/ } } - - //config_per_mbsfn_area_item->cellInformationList = ;//(M2AP_Cell_Information_List*)calloc(1,sizeof(M2AP_Cell_Information_List)); - - - //config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused = 4; - - //ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,config_per_mbsfn_area_item); - //config_per_mbsfn_area_item = &ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea; - //{ - - //} + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_t */ - //... - -// int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate; -// LOG_D(M2AP, "num_cells_to_activate = %d \n", num_cells_to_activate); -// for (i=0; -// iid = M2AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; -// cells_to_be_activated_list_item_ies->criticality = M2AP_Criticality_reject; -// cells_to_be_activated_list_item_ies->value.present = M2AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; -// -// /* 3.1 cells to be Activated list item */ -// M2AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item; -// memset((void *)&cells_to_be_activated_list_item, 0, sizeof(M2AP_Cells_to_be_Activated_List_Item_t)); -// -// /* - nRCGI */ -// M2AP_NRCGI_t nRCGI; -// MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i], -// &nRCGI.pLMN_Identity); -// NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity); -// cells_to_be_activated_list_item.nRCGI = nRCGI; -// -// /* optional */ -// /* - nRPCI */ -// if (1) { -// cells_to_be_activated_list_item.nRPCI = (M2AP_NRPCI_t *)calloc(1, sizeof(M2AP_NRPCI_t)); -// *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i]; // int 0..1007 -// } -// -// /* optional */ -// /* - gNB-MCE System Information */ -// if (1) { -// /* 3.1.2 gNB-MCESystem Information */ -// M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs; -// cells_to_be_activated_list_itemExtIEs = (M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemExtIEs_t)); -// cells_to_be_activated_list_itemExtIEs->id = M2AP_ProtocolIE_ID_id_gNB_MCESystemInformation; -// cells_to_be_activated_list_itemExtIEs->criticality = M2AP_Criticality_reject; -// cells_to_be_activated_list_itemExtIEs->extensionValue.present = M2AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_MCESystemInformation; -// -// M2AP_GNB_MCESystemInformation_t *gNB_MCESystemInformation = (M2AP_GNB_MCESystemInformation_t *)calloc(1, sizeof(M2AP_GNB_MCESystemInformation_t)); -// //LOG_I(M2AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]); -// //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++) -// // printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]); -// //printf("\n"); -// OCTET_STRING_fromBuf(&gNB_MCESystemInformation->sImessage, -// (const char*)f1ap_setup_resp->SI_container[i][0], -// f1ap_setup_resp->SI_container_length[i][0]); -// -// LOG_D(M2AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]); -// cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_MCESystemInformation = *gNB_MCESystemInformation; -// -// -// M2AP_ProtocolExtensionContainer_160P9_t p_160P9_t; -// memset((void *)&p_160P9_t, 0, sizeof(M2AP_ProtocolExtensionContainer_160P9_t)); -// -// ASN_SEQUENCE_ADD(&p_160P9_t.list, -// cells_to_be_activated_list_itemExtIEs); -// cells_to_be_activated_list_item.iE_Extensions = (struct M2AP_ProtocolExtensionContainer*)&p_160P9_t; -// -// } -// /* ADD */ -// cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item; -// ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, -// cells_to_be_activated_list_item_ies); -// } -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* encode */ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -1380,10 +978,6 @@ int MCE_send_M2_SETUP_RESPONSE(instance_t instance, /*uint32_t assoc_id,*/ return -1; } - //MCE_m2ap_itti_send_sctp_data_req(instance, m2ap_mce_data_from_du->assoc_id, buffer, len, 0); - //printf(",m2ap_mce_data_from_enb->assoc_id %d\n",m2ap_mce_data_from_enb->assoc_id); - - m2ap_MCE_itti_send_sctp_data_req(instance,m2ap_mce_data_from_enb->assoc_id,buffer,len,0); return 0; @@ -1561,88 +1155,8 @@ int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_id ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,mcch_related_bcch_config_per_mbsfn_area_item_ies); } - //config_per_mbsfn_area_item->cellInformationList = ;//(M2AP_Cell_Information_List*)calloc(1,sizeof(M2AP_Cell_Information_List)); - - - //config_per_mbsfn_area_item->subframeAllocationInfo.bits_unused = 4; - - //ASN_SEQUENCE_ADD(&ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea.list,config_per_mbsfn_area_item); - //config_per_mbsfn_area_item = &ie->value.choice.MCCHrelatedBCCH_ConfigPerMBSFNArea; - //{ - - //} ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* M2AP_MCCHrelatedBCCH_ConfigPerMBSFNArea_t */ - //... - -// int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate; -// LOG_D(M2AP, "num_cells_to_activate = %d \n", num_cells_to_activate); -// for (i=0; -// iid = M2AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; -// cells_to_be_activated_list_item_ies->criticality = M2AP_Criticality_reject; -// cells_to_be_activated_list_item_ies->value.present = M2AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; -// -// /* 3.1 cells to be Activated list item */ -// M2AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item; -// memset((void *)&cells_to_be_activated_list_item, 0, sizeof(M2AP_Cells_to_be_Activated_List_Item_t)); -// -// /* - nRCGI */ -// M2AP_NRCGI_t nRCGI; -// MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i], -// &nRCGI.pLMN_Identity); -// NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity); -// cells_to_be_activated_list_item.nRCGI = nRCGI; -// -// /* optional */ -// /* - nRPCI */ -// if (1) { -// cells_to_be_activated_list_item.nRPCI = (M2AP_NRPCI_t *)calloc(1, sizeof(M2AP_NRPCI_t)); -// *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i]; // int 0..1007 -// } -// -// /* optional */ -// /* - gNB-MCE System Information */ -// if (1) { -// /* 3.1.2 gNB-MCESystem Information */ -// M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs; -// cells_to_be_activated_list_itemExtIEs = (M2AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(M2AP_Cells_to_be_Activated_List_ItemExtIEs_t)); -// cells_to_be_activated_list_itemExtIEs->id = M2AP_ProtocolIE_ID_id_gNB_MCESystemInformation; -// cells_to_be_activated_list_itemExtIEs->criticality = M2AP_Criticality_reject; -// cells_to_be_activated_list_itemExtIEs->extensionValue.present = M2AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_MCESystemInformation; -// -// M2AP_GNB_MCESystemInformation_t *gNB_MCESystemInformation = (M2AP_GNB_MCESystemInformation_t *)calloc(1, sizeof(M2AP_GNB_MCESystemInformation_t)); -// //LOG_I(M2AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]); -// //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++) -// // printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]); -// //printf("\n"); -// OCTET_STRING_fromBuf(&gNB_MCESystemInformation->sImessage, -// (const char*)f1ap_setup_resp->SI_container[i][0], -// f1ap_setup_resp->SI_container_length[i][0]); -// -// LOG_D(M2AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]); -// cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_MCESystemInformation = *gNB_MCESystemInformation; -// -// -// M2AP_ProtocolExtensionContainer_160P9_t p_160P9_t; -// memset((void *)&p_160P9_t, 0, sizeof(M2AP_ProtocolExtensionContainer_160P9_t)); -// -// ASN_SEQUENCE_ADD(&p_160P9_t.list, -// cells_to_be_activated_list_itemExtIEs); -// cells_to_be_activated_list_item.iE_Extensions = (struct M2AP_ProtocolExtensionContainer*)&p_160P9_t; -// -// } -// /* ADD */ -// cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item; -// ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, -// cells_to_be_activated_list_item_ies); -// } -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* encode */ if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { diff --git a/openair2/M2AP/m2ap_eNB_interface_management.c b/openair2/M2AP/m2ap_eNB_interface_management.c index c2659da59d..95b8372025 100644 --- a/openair2/M2AP/m2ap_eNB_interface_management.c +++ b/openair2/M2AP/m2ap_eNB_interface_management.c @@ -193,74 +193,8 @@ int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance, //xer_fprint(stdout, &asn_DEF_M2AP_MBSFN_Area_Configuration_List, &ie->value.choice.MBSFN_Area_Configuration_List); } - //asn_DEF_M2AP_MBSFN_Area_Configuration_List - - // void * sptr = (void*)&ie->value.choice.MBSFN_Area_Configuration_List; - // asn_TYPE_descriptor_t * td = &asn_DEF_M2AP_MBSFN_Area_Configuration_List; - // asn_enc_rval_t er; - // const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; - // const asn_TYPE_member_t *elm = td->elements; - // const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr); - // const char *mname = specs->as_XMLValueList - // ? 0 - // : ((*elm->name) ? elm->name : elm->type->xml_tag); - // size_t mlen = mname ? strlen(mname) : 0; - // //int xcan = (flags & XER_F_CANONICAL); - // //int i; - - // if(!sptr) ASN__ENCODE_FAILED; - - // er.encoded = 0; - - // for(i = 0; i < list->count; i++) { - // asn_enc_rval_t tmper; - // void *memb_ptr = list->array[i]; - // if(!memb_ptr) continue; - - // if(mname) { - // //if(!xcan) ASN__TEXT_INDENT(1, ilevel); - // //ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); - // } - - // tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1, - // flags, cb, app_key); - // if(tmper.encoded == -1) return tmper; - // er.encoded += tmper.encoded; - // if(tmper.encoded == 0 && specs->as_XMLValueList) { - // const char *name = elm->type->xml_tag; - // size_t len = strlen(name); - // //if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1); - // //ASN__CALLBACK3("<", 1, name, len, "/>", 2); - // } - - // if(mname) { - // ASN__CALLBACK3("", 1); - // } - // } - - - - - - - //M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_MBSFN_Area_Configuration_Item_t, &ie->value.choice.MBSFN_Area_Configuration_List.list, container2,M2AP_ProtocolIE_ID_id_PMCH_Configuration_List ,true); - - //printf("count %d\n",((M2AP_MBSFN_Area_Configuration_Item_t*)ie->value.choice.MBSFN_Area_Configuration_List.list.array[0])->value.choice.PMCH_Configuration_List.list.count); - - -// M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, -// M2AP_ProtocolIE_ID_id_GlobalEND_ID, true); - - - //itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p2); itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); - -// if(1){ -// printf("m2ap_enb_data_g->assoc_id %d %d\n",m2ap_enb_data_g->assoc_id,assoc_id); -// eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance,NULL); -// }else -// //eNB_send_MBMS_SESSION_START_FAILURE(instance,assoc_id); return 0; } diff --git a/openair3/M3AP/m3ap_eNB_decoder.c b/openair3/M3AP/m3ap_eNB_decoder.c deleted file mode 100644 index ee0aaca388..0000000000 --- a/openair3/M3AP/m3ap_eNB_decoder.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_decoder.c - * \brief m3ap decoder procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#include - -#include "assertions.h" -#include "intertask_interface.h" -#include "m3ap_common.h" -#include "m3ap_eNB_decoder.h" - -static int m3ap_eNB_decode_initiating_message(M3AP_M3AP_PDU_t *pdu) -{ - DevAssert(pdu != NULL); - - switch(pdu->choice.initiatingMessage.procedureCode) { - - case M3AP_ProcedureCode_id_m3Setup: - //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); - M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); - break; - -// case M3AP_ProcedureCode_id_handoverPreparation: -// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); -// M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); -// break; -// -// case M3AP_ProcedureCode_id_uEContextRelease: -// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); -// M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); -// break; -// -// case M3AP_ProcedureCode_id_handoverCancel: -// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); -// M3AP_INFO("m3ap_eNB_decode_initiating_message!\n"); -// break; -// - default: - M3AP_ERROR("Unknown procedure ID (%d) for initiating message\n", - (int)pdu->choice.initiatingMessage.procedureCode); - AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", - (int)pdu->choice.initiatingMessage.procedureCode); - return -1; - } - - return 0; -} - -static int m3ap_eNB_decode_successful_outcome(M3AP_M3AP_PDU_t *pdu) -{ - DevAssert(pdu != NULL); - - switch(pdu->choice.successfulOutcome.procedureCode) { - case M3AP_ProcedureCode_id_m3Setup: - //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); - M3AP_INFO("m3ap_eNB_decode_successfuloutcome_message!\n"); - break; - -// case M3AP_ProcedureCode_id_handoverPreparation: -// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); -// M3AP_INFO("m3ap_eNB_decode_successfuloutcome_message!\n"); -// break; -// - default: - M3AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", - (int)pdu->choice.successfulOutcome.procedureCode); - return -1; - } - - return 0; -} - -static int m3ap_eNB_decode_unsuccessful_outcome(M3AP_M3AP_PDU_t *pdu) -{ - DevAssert(pdu != NULL); - - switch(pdu->choice.unsuccessfulOutcome.procedureCode) { - case M3AP_ProcedureCode_id_m3Setup: - //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M3AP_M3AP_PDU, pdu); - M3AP_INFO("m3ap_eNB_decode_unsuccessfuloutcome_message!\n"); - break; - - default: - M3AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", - (int)pdu->choice.unsuccessfulOutcome.procedureCode); - return -1; - } - - return 0; -} - -int m3ap_eNB_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) -{ - asn_dec_rval_t dec_ret; - - DevAssert(buffer != NULL); - - dec_ret = aper_decode(NULL, - &asn_DEF_M3AP_M3AP_PDU, - (void **)&pdu, - buffer, - length, - 0, - 0); - if (asn1_xer_print) { - xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, pdu); - } - - if (dec_ret.code != RC_OK) { - M3AP_ERROR("Failed to decode pdu\n"); - return -1; - } - - switch(pdu->present) { - case M3AP_M3AP_PDU_PR_initiatingMessage: - return m3ap_eNB_decode_initiating_message(pdu); - - case M3AP_M3AP_PDU_PR_successfulOutcome: - return m3ap_eNB_decode_successful_outcome(pdu); - - case M3AP_M3AP_PDU_PR_unsuccessfulOutcome: - return m3ap_eNB_decode_unsuccessful_outcome(pdu); - - default: - M3AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present); - break; - } - - - return -1; -} diff --git a/openair3/M3AP/m3ap_eNB_decoder.h b/openair3/M3AP/m3ap_eNB_decoder.h deleted file mode 100644 index eddf10781e..0000000000 --- a/openair3/M3AP/m3ap_eNB_decoder.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_decoder.h - * \brief m3ap decoder procedures for eNB - * \author Konstantinos Alexandris , Cedric Roux , Navid Nikaein - * \date 2018 - * \version 1.0 - */ - -#ifndef M3AP_ENB_DECODER_H_ -#define M3AP_ENB_DECODER_H_ - -int m3ap_eNB_decode_pdu(M3AP_M3AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) -__attribute__ ((warn_unused_result)); - -#endif /* M3AP_ENB_DECODER_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_encoder.c b/openair3/M3AP/m3ap_eNB_encoder.c deleted file mode 100644 index 0f0d3c3188..0000000000 --- a/openair3/M3AP/m3ap_eNB_encoder.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_encoder.c - * \brief m3ap encoder procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#include -#include -#include - -#include "assertions.h" -#include "conversions.h" -#include "intertask_interface.h" -#include "m3ap_common.h" -#include "m3ap_eNB_encoder.h" - -int m3ap_eNB_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) -{ - ssize_t encoded; - - DevAssert(pdu != NULL); - DevAssert(buffer != NULL); - DevAssert(len != NULL); - - if (asn1_xer_print) { - xer_fprint(stdout, &asn_DEF_M3AP_M3AP_PDU, (void *)pdu); - } - - encoded = aper_encode_to_new_buffer(&asn_DEF_M3AP_M3AP_PDU, 0, pdu, (void **)buffer); - - if (encoded < 0) { - return -1; - } - - *len = encoded; - - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, pdu); - return encoded; -} diff --git a/openair3/M3AP/m3ap_eNB_encoder.h b/openair3/M3AP/m3ap_eNB_encoder.h deleted file mode 100644 index 1e22b59391..0000000000 --- a/openair3/M3AP/m3ap_eNB_encoder.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_encoder.h - * \brief m3ap encoder procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#ifndef M3AP_ENB_ENCODER_H_ -#define M3AP_ENB_ENCODER_H_ - -int m3ap_eNB_encode_pdu(M3AP_M3AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) -__attribute__ ((warn_unused_result)); - -#endif /* M3AP_ENB_ENCODER_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_generate_messages.c b/openair3/M3AP/m3ap_eNB_generate_messages.c deleted file mode 100644 index 157146ee0f..0000000000 --- a/openair3/M3AP/m3ap_eNB_generate_messages.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_generate_messages.c - * \brief m3ap procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#include "intertask_interface.h" - -//#include "M3AP_LastVisitedCell-Item.h" - -#include "m3ap_common.h" -#include "m3ap_eNB.h" -#include "m3ap_eNB_generate_messages.h" -#include "m3ap_eNB_encoder.h" -#include "m3ap_eNB_decoder.h" -#include "m3ap_ids.h" - -#include "m3ap_eNB_itti_messaging.h" - -#include "msc.h" -#include "assertions.h" -#include "conversions.h" - -int m3ap_eNB_generate_m3_setup_request( - m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p) -{ - M3AP_M3AP_PDU_t pdu; - M3AP_M3SetupRequest_t *out; - M3AP_M3SetupRequestIEs_t *ie; - //M3AP_PLMN_Identity_t *plmn; - //ServedCells__Member *servedCellMember; - //M3AP_GU_Group_ID_t *gu; - - uint8_t *buffer; - uint32_t len; - int ret = 0; - - DevAssert(instance_p != NULL); - DevAssert(m3ap_eNB_data_p != NULL); - - m3ap_eNB_data_p->state = M3AP_ENB_STATE_WAITING; - - /* Prepare the M3AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_m3Setup; - pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; - pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_M3SetupRequest; - out = &pdu.choice.initiatingMessage.value.choice.M3SetupRequest; - - /* mandatory */ - ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_GlobalENB_ID; - //ie->criticality = M3AP_Criticality_reject; - //ie->value.present = M3AP_M2SetupRequest_IEs__value_PR_GlobalENB_ID; - //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - // &ie->value.choice.GlobalENB_ID.pLMN_Identity); - //ie->value.choice.GlobalENB_ID.eNB_ID.present = M3AP_ENB_ID_PR_macro_eNB_ID; - //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, - // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); - //M3AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, - // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], - // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], - // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_ServedCells; - //ie->criticality = M3AP_Criticality_reject; - //ie->value.present = M3AP_M2SetupRequest_IEs__value_PR_ServedCells; - //{ - // for (int i = 0; inum_cc; i++){ - // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); - // { - // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; - - // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); - // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, - // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); - - // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); - // plmn = (M3AP_PLMN_Identity_t *)calloc(1,sizeof(M3AP_PLMN_Identity_t)); - // { - // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); - // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); - // } - - // if (instance_p->frame_type[i] == FDD) { - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M3AP_EUTRA_Mode_Info_PR_fDD; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; - // switch (instance_p->N_RB_DL[i]) { - // case 6: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; - // break; - // case 15: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; - // break; - // case 25: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; - // break; - // case 50: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; - // break; - // case 75: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; - // break; - // case 100: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; - // break; - // default: - // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); - // break; - // } - // } - // else { - // AssertFatal(0,"M2Setuprequest not supported for TDD!"); - // } - // } - // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); - // } - //} - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (M3AP_M3SetupRequestIEs_t *)calloc(1, sizeof(M3AP_M3SetupRequestIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_GUGroupIDList; - //ie->criticality = M3AP_Criticality_reject; - //ie->value.present = M3AP_M2SetupRequest_IEs__value_PR_GUGroupIDList; - //{ - // gu = (M3AP_GU_Group_ID_t *)calloc(1, sizeof(M3AP_GU_Group_ID_t)); - // { - // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - // &gu->pLMN_Identity); - // //@TODO: consider to update this value - // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); - // } - // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); - //} - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { - M3AP_ERROR("Failed to encode M3 setup request\n"); - return -1; - } - - //MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 M3Setup/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); - - m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 0); - - return ret; -} - -int m3ap_eNB_generate_m3_setup_response(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p) -{ - M3AP_M3AP_PDU_t pdu; - M3AP_M3SetupResponse_t *out; - M3AP_M3SetupResponseIEs_t *ie; - //M3AP_PLMN_Identity_t *plmn; - //ServedCells__Member *servedCellMember; - //M3AP_GU_Group_ID_t *gu; - - uint8_t *buffer; - uint32_t len; - int ret = 0; - - DevAssert(instance_p != NULL); - DevAssert(m3ap_eNB_data_p != NULL); - - /* Prepare the M3AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_m3Setup; - pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_M3SetupResponse; - out = &pdu.choice.successfulOutcome.value.choice.M3SetupResponse; - - /* mandatory */ - ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_GlobalENB_ID; - //ie->criticality = M3AP_Criticality_reject; - //ie->value.present = M3AP_M3SetupResponse_IEs__value_PR_GlobalENB_ID; - //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - // &ie->value.choice.GlobalENB_ID.pLMN_Identity); - //ie->value.choice.GlobalENB_ID.eNB_ID.present = M3AP_ENB_ID_PR_macro_eNB_ID; - //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, - // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); - //M3AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, - // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], - // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], - // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_ServedCells; - //ie->criticality = M3AP_Criticality_reject; - //ie->value.present = M3AP_M3SetupResponse_IEs__value_PR_ServedCells; - //{ - // for (int i = 0; inum_cc; i++){ - // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member)); - // { - // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i]; - - // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - // &servedCellMember->servedCellInfo.cellId.pLMN_Identity); - // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, - // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); - - // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); - // plmn = (M3AP_PLMN_Identity_t *)calloc(1,sizeof(M3AP_PLMN_Identity_t)); - // { - // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); - // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn); - // } - - // if (instance_p->frame_type[i] == FDD) { - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M3AP_EUTRA_Mode_Info_PR_fDD; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; - // switch (instance_p->N_RB_DL[i]) { - // case 6: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw6; - // break; - // case 15: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw15; - // break; - // case 25: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw25; - // break; - // case 50: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw50; - // break; - // case 75: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw75; - // break; - // case 100: - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; - // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M3AP_Transmission_Bandwidth_bw100; - // break; - // default: - // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); - // break; - // } - // } - // else { - // AssertFatal(0,"M3Setupresponse not supported for TDD!"); - // } - // } - // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); - // } - //} - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (M3AP_M3SetupResponseIEs_t *)calloc(1, sizeof(M3AP_M3SetupResponseIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_GUGroupIDList; - //ie->criticality = M3AP_Criticality_reject; - //ie->value.present = M3AP_M3SetupResponse_IEs__value_PR_GUGroupIDList; - //{ - // gu = (M3AP_GU_Group_ID_t *)calloc(1, sizeof(M3AP_GU_Group_ID_t)); - // { - // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - // &gu->pLMN_Identity); - // //@TODO: consider to update this value - // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID); - // } - // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu); - //} - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { - M3AP_ERROR("Failed to encode M3 setup response\n"); - return -1; - } - - m3ap_eNB_data_p->state = M3AP_ENB_STATE_READY; - - //MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 M3Setup/successfulOutcome assoc_id %u", m3ap_eNB_data_p->assoc_id); - - m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 0); - - return ret; -} - -int m3ap_eNB_generate_m3_setup_failure(instance_t instance, - uint32_t assoc_id, - M3AP_Cause_PR cause_type, - long cause_value, - long time_to_wait) -{ - M3AP_M3AP_PDU_t pdu; - M3AP_M3SetupFailure_t *out; - M3AP_M3SetupFailureIEs_t *ie; - - uint8_t *buffer; - uint32_t len; - int ret = 0; - - /* Prepare the M3AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = M3AP_M3AP_PDU_PR_unsuccessfulOutcome; - pdu.choice.unsuccessfulOutcome.procedureCode = M3AP_ProcedureCode_id_m3Setup; - pdu.choice.unsuccessfulOutcome.criticality = M3AP_Criticality_reject; - pdu.choice.unsuccessfulOutcome.value.present = M3AP_UnsuccessfulOutcome__value_PR_M3SetupFailure; - out = &pdu.choice.unsuccessfulOutcome.value.choice.M3SetupFailure; - - /* mandatory */ - ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_Cause; - //ie->criticality = M3AP_Criticality_ignore; - //ie->value.present = M3AP_M3SetupFailure_IEs__value_PR_Cause; - - //m3ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value); - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* optional: consider to handle this later */ - ie = (M3AP_M3SetupFailureIEs_t *)calloc(1, sizeof(M3AP_M3SetupFailureIEs_t)); - //ie->id = M3AP_ProtocolIE_ID_id_TimeToWait; - //ie->criticality = M3AP_Criticality_ignore; - //ie->value.present = M3AP_M3SetupFailure_IEs__value_PR_TimeToWait; - - //if (time_to_wait > -1) { - // ie->value.choice.TimeToWait = time_to_wait; - //} - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { - M3AP_ERROR("Failed to encode M3 setup failure\n"); - return -1; - } - - //MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, - // MSC_M3AP_TARGET_ENB, NULL, 0, - // "0 M3Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", - // assoc_id, cause_type, cause_value); - - m3ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); - - return ret; -} - -int m3ap_eNB_set_cause (M3AP_Cause_t * cause_p, - M3AP_Cause_PR cause_type, - long cause_value) -{ - - DevAssert (cause_p != NULL); - cause_p->present = cause_type; - - switch (cause_type) { - case M3AP_Cause_PR_radioNetwork: - cause_p->choice.misc = cause_value; - break; - - case M3AP_Cause_PR_transport: - cause_p->choice.misc = cause_value; - break; - - case M3AP_Cause_PR_protocol: - cause_p->choice.misc = cause_value; - break; - - case M3AP_Cause_PR_misc: - cause_p->choice.misc = cause_value; - break; - - default: - return -1; - } - - return 0; -} - -//int m3ap_eNB_generate_m2_handover_request (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// m3ap_handover_req_t *m3ap_handover_req, int ue_id) -//{ -// -// M3AP_M3AP_PDU_t pdu; -// M3AP_HandoverRequest_t *out; -// M3AP_HandoverRequest_IEs_t *ie; -// M3AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; -// M3AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; -// M3AP_LastVisitedCell_Item_t *lastVisitedCell_Item; -// -// uint8_t *buffer; -// uint32_t len; -// int ret = 0; -// -// DevAssert(instance_p != NULL); -// DevAssert(m3ap_eNB_data_p != NULL); -// -// /* Prepare the M3AP handover message to encode */ -// memset(&pdu, 0, sizeof(pdu)); -// pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; -// pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_handoverPreparation; -// pdu.choice.initiatingMessage.criticality = M3AP_Criticality_reject; -// pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_HandoverRequest; -// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; -// -// /* mandatory */ -// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_UE_M3AP_ID; -// ie->value.choice.UE_M3AP_ID = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_Cause; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_Cause; -// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; -// ie->value.choice.Cause.choice.radioNetwork = M3AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_TargetCell_ID; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_ECGI; -// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, -// &ie->value.choice.ECGI.pLMN_Identity); -// MACRO_ENB_ID_TO_CELL_IDENTITY(m3ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_GUMMEI_ID; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_GUMMEI; -// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, -// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); -// //@TODO: consider to update these values -// INT16_TO_OCTET_STRING(m3ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); -// MME_CODE_TO_OCTET_STRING(m3ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_UE_ContextInformation; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; -// //@TODO: consider to update this value -// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m3ap_handover_req->mme_ue_s1ap_id; -// -// KENB_STAR_TO_BIT_STRING(m3ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); -// -// if (m3ap_handover_req->kenb_ncc >=0) { // Check this condition -// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m3ap_handover_req->kenb_ncc; -// } -// else { -// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; -// } -// -// ENCRALG_TO_BIT_STRING(m3ap_handover_req->security_capabilities.encryption_algorithms, -// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); -// -// INTPROTALG_TO_BIT_STRING(m3ap_handover_req->security_capabilities.integrity_algorithms, -// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); -// -// //@TODO: update with proper UEAMPR -// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); -// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); -// { -// for (int i=0;inb_e_rabs_tobesetup;i++) { -// e_RABS_ToBeSetup_ItemIEs = (M3AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M3AP_E_RABs_ToBeSetup_ItemIEs_t)); -// e_RABS_ToBeSetup_ItemIEs->id = M3AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; -// e_RABS_ToBeSetup_ItemIEs->criticality = M3AP_Criticality_ignore; -// e_RABS_ToBeSetup_ItemIEs->value.present = M3AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; -// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; -// { -// e_RABs_ToBeSetup_Item->e_RAB_ID = m3ap_handover_req->e_rabs_tobesetup[i].e_rab_id; -// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m3ap_handover_req->e_rab_param[i].qos.qci; -// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m3ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; -// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m3ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; -// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m3ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m3ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8); -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m3ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8; -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = -// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); -// -// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, -// m3ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer, -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); -// -// INT32_TO_OCTET_STRING(m3ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); -// } -// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); -// } -// } -// -// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m3ap_handover_req->rrc_buffer, m3ap_handover_req->rrc_buffer_size); -// -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequest_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_UE_HistoryInformation; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; -// //@TODO: consider to update this value -// { -// lastVisitedCell_Item = (M3AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M3AP_LastVisitedCell_Item_t)); -// lastVisitedCell_Item->present = M3AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; -// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, -// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); -// MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); -// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M3AP_Cell_Size_small; -// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; -// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); -// } -// -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { -// M3AP_ERROR("Failed to encode X2 handover request\n"); -// abort(); -// return -1; -// } -// -// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); -// -// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); -// -// return ret; -//} -// -//int m3ap_eNB_generate_m2_handover_request_ack (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// m3ap_handover_req_ack_t *m3ap_handover_req_ack) -//{ -// -// M3AP_M3AP_PDU_t pdu; -// M3AP_HandoverRequestAcknowledge_t *out; -// M3AP_HandoverRequestAcknowledge_IEs_t *ie; -// M3AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; -// M3AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; -// int ue_id; -// int id_source; -// int id_target; -// -// uint8_t *buffer; -// uint32_t len; -// int ret = 0; -// -// DevAssert(instance_p != NULL); -// DevAssert(m3ap_eNB_data_p != NULL); -// -// ue_id = m3ap_handover_req_ack->m2_id_target; -// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); -// id_target = ue_id; -// -// /* Prepare the M3AP handover message to encode */ -// memset(&pdu, 0, sizeof(pdu)); -// pdu.present = M3AP_M3AP_PDU_PR_successfulOutcome; -// pdu.choice.successfulOutcome.procedureCode = M3AP_ProcedureCode_id_handoverPreparation; -// pdu.choice.successfulOutcome.criticality = M3AP_Criticality_reject; -// pdu.choice.successfulOutcome.value.present = M3AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; -// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; -// -// /* mandatory */ -// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M3AP_ID; -// ie->value.choice.UE_M3AP_ID = id_source; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M3AP_ID_1; -// ie->value.choice.UE_M3AP_ID_1 = id_target; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_E_RABs_Admitted_List; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; -// -// { -// for (int i=0;inb_e_rabs_tobesetup;i++) { -// e_RABS_Admitted_ItemIEs = (M3AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M3AP_E_RABs_Admitted_ItemIEs_t)); -// e_RABS_Admitted_ItemIEs->id = M3AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; -// e_RABS_Admitted_ItemIEs->criticality = M3AP_Criticality_ignore; -// e_RABS_Admitted_ItemIEs->value.present = M3AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; -// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; -// { -// e_RABs_Admitted_Item->e_RAB_ID = m3ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; -// } -// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); -// } -// } -// -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M3AP_HandoverRequestAcknowledge_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer; -// -// OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m3ap_handover_req_ack->rrc_buffer, m3ap_handover_req_ack->rrc_buffer_size); -// -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { -// M3AP_ERROR("Failed to encode X2 handover response\n"); -// abort(); -// return -1; -// } -// -// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m3ap_eNB_data_p->assoc_id); -// -// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); -// -// return ret; -//} -// -//int m3ap_eNB_generate_m2_ue_context_release (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, m3ap_ue_context_release_t *m3ap_ue_context_release) -//{ -// -// M3AP_M3AP_PDU_t pdu; -// M3AP_UEContextRelease_t *out; -// M3AP_UEContextRelease_IEs_t *ie; -// int ue_id; -// int id_source; -// int id_target; -// -// uint8_t *buffer; -// uint32_t len; -// int ret = 0; -// -// DevAssert(instance_p != NULL); -// DevAssert(m3ap_eNB_data_p != NULL); -// -// ue_id = m3ap_find_id_from_rnti(&instance_p->id_manager, m3ap_ue_context_release->rnti); -// if (ue_id == -1) { -// M3AP_ERROR("could not find UE %x\n", m3ap_ue_context_release->rnti); -// exit(1); -// } -// id_source = m3ap_id_get_id_source(&instance_p->id_manager, ue_id); -// id_target = ue_id; -// -// /* Prepare the M3AP ue context relase message to encode */ -// memset(&pdu, 0, sizeof(pdu)); -// pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; -// pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_uEContextRelease; -// pdu.choice.initiatingMessage.criticality = M3AP_Criticality_ignore; -// pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_UEContextRelease; -// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; -// -// /* mandatory */ -// ie = (M3AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M3AP_UEContextRelease_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_UEContextRelease_IEs__value_PR_UE_M3AP_ID; -// ie->value.choice.UE_M3AP_ID = id_source; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* mandatory */ -// ie = (M3AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M3AP_UEContextRelease_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_UEContextRelease_IEs__value_PR_UE_M3AP_ID_1; -// ie->value.choice.UE_M3AP_ID_1 = id_target; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { -// M3AP_ERROR("Failed to encode X2 UE Context Release\n"); -// abort(); -// return -1; -// } -// -// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); -// -// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); -// -// return ret; -//} -// -//int m3ap_eNB_generate_m2_handover_cancel (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// int m2_ue_id, -// m3ap_handover_cancel_cause_t cause) -//{ -// M3AP_M3AP_PDU_t pdu; -// M3AP_HandoverCancel_t *out; -// M3AP_HandoverCancel_IEs_t *ie; -// int ue_id; -// int id_source; -// int id_target; -// -// uint8_t *buffer; -// uint32_t len; -// int ret = 0; -// -// DevAssert(instance_p != NULL); -// DevAssert(m3ap_eNB_data_p != NULL); -// -// ue_id = m2_ue_id; -// id_source = ue_id; -// id_target = m3ap_id_get_id_target(&instance_p->id_manager, ue_id); -// -// /* Prepare the M3AP handover cancel message to encode */ -// memset(&pdu, 0, sizeof(pdu)); -// pdu.present = M3AP_M3AP_PDU_PR_initiatingMessage; -// pdu.choice.initiatingMessage.procedureCode = M3AP_ProcedureCode_id_handoverCancel; -// pdu.choice.initiatingMessage.criticality = M3AP_Criticality_ignore; -// pdu.choice.initiatingMessage.value.present = M3AP_InitiatingMessage__value_PR_HandoverCancel; -// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; -// -// /* mandatory */ -// ie = (M3AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M3AP_HandoverCancel_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_reject; -// ie->value.present = M3AP_HandoverCancel_IEs__value_PR_UE_M3AP_ID; -// ie->value.choice.UE_M3AP_ID = id_source; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// /* optional */ -// if (id_target != -1) { -// ie = (M3AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M3AP_HandoverCancel_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverCancel_IEs__value_PR_UE_M3AP_ID_1; -// ie->value.choice.UE_M3AP_ID_1 = id_target; -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// } -// -// /* mandatory */ -// ie = (M3AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M3AP_HandoverCancel_IEs_t)); -// ie->id = M3AP_ProtocolIE_ID_id_Cause; -// ie->criticality = M3AP_Criticality_ignore; -// ie->value.present = M3AP_HandoverCancel_IEs__value_PR_Cause; -// switch (cause) { -// case M3AP_T_RELOC_PREP_TIMEOUT: -// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; -// ie->value.choice.Cause.choice.radioNetwork = -// M3AP_CauseRadioNetwork_trelocprep_expiry; -// break; -// case M3AP_TX2_RELOC_OVERALL_TIMEOUT: -// ie->value.choice.Cause.present = M3AP_Cause_PR_radioNetwork; -// ie->value.choice.Cause.choice.radioNetwork = -// M3AP_CauseRadioNetwork_tx2relocoverall_expiry; -// break; -// default: -// /* we can't come here */ -// M3AP_ERROR("unhandled cancel cause\n"); -// exit(1); -// } -// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -// -// if (m3ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { -// M3AP_ERROR("Failed to encode X2 Handover Cancel\n"); -// abort(); -// return -1; -// } -// -// MSC_LOG_TX_MESSAGE (MSC_M3AP_SRC_ENB, MSC_M3AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m3ap_eNB_data_p->assoc_id); -// -// m3ap_eNB_itti_send_sctp_data_req(instance_p->instance, m3ap_eNB_data_p->assoc_id, buffer, len, 1); -// -// return ret; -//} diff --git a/openair3/M3AP/m3ap_eNB_generate_messages.h b/openair3/M3AP/m3ap_eNB_generate_messages.h deleted file mode 100644 index ab6c7ca615..0000000000 --- a/openair3/M3AP/m3ap_eNB_generate_messages.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_generate_messages.h - * \brief m3ap procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#ifndef M3AP_ENB_GENERATE_MESSAGES_H_ -#define M3AP_ENB_GENERATE_MESSAGES_H_ - -#include "m3ap_eNB_defs.h" -#include "m3ap_common.h" - -int m3ap_eNB_generate_m3_setup_request(m3ap_eNB_instance_t *instance_p, - m3ap_eNB_data_t *m3ap_eNB_data_p); - -int m3ap_eNB_generate_m3_setup_response(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p); - -int m3ap_eNB_generate_m3_setup_failure(instance_t instance, - uint32_t assoc_id, - M3AP_Cause_PR cause_type, - long cause_value, - long time_to_wait); - -int m3ap_eNB_set_cause (M3AP_Cause_t * cause_p, - M3AP_Cause_PR cause_type, - long cause_value); - -//int m3ap_eNB_generate_m2_handover_request (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// m3ap_handover_req_t *m3ap_handover_req, int ue_id); -// -//int m3ap_eNB_generate_m2_handover_request_ack (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// m3ap_handover_req_ack_t *m3ap_handover_req_ack); -// -//int m3ap_eNB_generate_m2_ue_context_release (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// m3ap_ue_context_release_t *m3ap_ue_context_release); -// -//int m3ap_eNB_generate_m2_handover_cancel (m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *m3ap_eNB_data_p, -// int m2_ue_id, -// m3ap_handover_cancel_cause_t cause); - -#endif /* M3AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_handler.c b/openair3/M3AP/m3ap_eNB_handler.c deleted file mode 100644 index 4fda97142d..0000000000 --- a/openair3/M3AP/m3ap_eNB_handler.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_handler.c - * \brief m3ap handler procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#include - -#include "intertask_interface.h" - -#include "asn1_conversions.h" - -#include "m3ap_common.h" -#include "m3ap_eNB_defs.h" -#include "m3ap_eNB_handler.h" -#include "m3ap_eNB_decoder.h" -#include "m3ap_ids.h" - -#include "m3ap_eNB_management_procedures.h" -#include "m3ap_eNB_generate_messages.h" - -#include "msc.h" -#include "assertions.h" -#include "conversions.h" - -static -int m3ap_eNB_handle_m3_setup_request (instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M3AP_M3AP_PDU_t *pdu); -static -int m3ap_eNB_handle_m3_setup_response (instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M3AP_M3AP_PDU_t *pdu); -static -int m3ap_eNB_handle_m3_setup_failure (instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M3AP_M3AP_PDU_t *pdu); -// -//static -//int m3ap_eNB_handle_handover_preparation (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu); -//static -//int m3ap_eNB_handle_handover_response (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu); -// -//static -//int m3ap_eNB_handle_ue_context_release (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu); -// -//static -//int m3ap_eNB_handle_handover_cancel (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu); - -/* Handlers matrix. Only eNB related procedure present here */ -m3ap_message_decoded_callback m3ap_messages_callback[][3] = { - { 0, 0, 0 }, /* MBMSSessionStart */ - { 0, 0, 0 }, /* MBMSSessionStop */ - { 0, 0, 0 }, /* MBMSSessionUpdate */ - { 0, 0, 0 }, /* MBMSSchedulingInformation */ - { 0, 0, 0 }, /* reset */ - { m3ap_eNB_handle_m3_setup_request, m3ap_eNB_handle_m3_setup_response, m3ap_eNB_handle_m3_setup_failure }, /* M3 Setup */ - { 0, 0, 0 }, /* eNBConfigurationUpdate */ - { 0, 0, 0 }, /* MCEConfigurationUpdate */ - { 0, 0, 0 }, /* MBMSServiceCounting */ -}; - -char *m3ap_direction2String(int m3ap_dir) { -static char *m3ap_direction_String[] = { - "", /* Nothing */ - "Originating message", /* originating message */ - "Successfull outcome", /* successfull outcome */ - "UnSuccessfull outcome", /* successfull outcome */ -}; -return(m3ap_direction_String[m3ap_dir]); -} - -void m3ap_handle_m3_setup_message(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *enb_desc_p, int sctp_shutdown) -{ - if (sctp_shutdown) { - /* A previously connected eNB has been shutdown */ - - /* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated eNB */ - if (enb_desc_p->state == M3AP_ENB_STATE_CONNECTED) { - enb_desc_p->state = M3AP_ENB_STATE_DISCONNECTED; - - if (instance_p-> m3_target_enb_associated_nb > 0) { - /* Decrease associated eNB number */ - instance_p-> m3_target_enb_associated_nb --; - } - - /* If there are no more associated eNB, inform eNB app */ - if (instance_p->m3_target_enb_associated_nb == 0) { - MessageDef *message_p; - - message_p = itti_alloc_new_message(TASK_M3AP, M3AP_DEREGISTERED_MCE_IND); - M3AP_DEREGISTERED_MCE_IND(message_p).nb_mme = 0; - itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); - } - } - } else { - /* Check that at least one setup message is pending */ - DevCheck(instance_p->m3_target_enb_pending_nb > 0, - instance_p->instance, - instance_p->m3_target_enb_pending_nb, 0); - - if (instance_p->m3_target_enb_pending_nb > 0) { - /* Decrease pending messages number */ - instance_p->m3_target_enb_pending_nb --; - } - - /* If there are no more pending messages, inform eNB app */ - if (instance_p->m3_target_enb_pending_nb == 0) { - MessageDef *message_p; - - message_p = itti_alloc_new_message(TASK_M3AP, M3AP_REGISTER_MCE_CNF); - M3AP_REGISTER_MCE_CNF(message_p).nb_mme = instance_p->m3_target_enb_associated_nb; - itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); - } - } -} - - -int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, - const uint8_t *const data, const uint32_t data_length) -{ - M3AP_M3AP_PDU_t pdu; - int ret = 0; - - DevAssert(data != NULL); - - memset(&pdu, 0, sizeof(pdu)); - - //printf("Data length received: %d\n", data_length); - - if (m3ap_eNB_decode_pdu(&pdu, data, data_length) < 0) { - M3AP_ERROR("Failed to decode PDU\n"); - return -1; - } - - switch (pdu.present) { - - case M3AP_M3AP_PDU_PR_initiatingMessage: - /* Checking procedure Code and direction of message */ - if (pdu.choice.initiatingMessage.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( - m3ap_message_decoded_callback))) { - //|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { - M3AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", - assoc_id, pdu.choice.initiatingMessage.procedureCode); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return -1; - } - - /* No handler present. - * This can mean not implemented or no procedure for eNB (wrong direction). - */ - if (m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { - M3AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", - assoc_id, pdu.choice.initiatingMessage.procedureCode, - m3ap_direction2String(pdu.present - 1)); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return -1; - } - /* Calling the right handler */ - ret = (*m3ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) - (instance, assoc_id, stream, &pdu); - break; - - case M3AP_M3AP_PDU_PR_successfulOutcome: - /* Checking procedure Code and direction of message */ - if (pdu.choice.successfulOutcome.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( - m3ap_message_decoded_callback))) { - //|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { - M3AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", - assoc_id, pdu.choice.successfulOutcome.procedureCode); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return -1; - } - - /* No handler present. - * This can mean not implemented or no procedure for eNB (wrong direction). - */ - if (m3ap_messages_callback[pdu.choice.successfulOutcome.procedureCode][pdu.present - 1] == NULL) { - M3AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", - assoc_id, pdu.choice.successfulOutcome.procedureCode, - m3ap_direction2String(pdu.present - 1)); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return -1; - } - /* Calling the right handler */ - ret = (*m3ap_messages_callback[pdu.choice.successfulOutcome.procedureCode][pdu.present - 1]) - (instance, assoc_id, stream, &pdu); - break; - - case M3AP_M3AP_PDU_PR_unsuccessfulOutcome: - /* Checking procedure Code and direction of message */ - if (pdu.choice.unsuccessfulOutcome.procedureCode > sizeof(m3ap_messages_callback) / (3 * sizeof( - m3ap_message_decoded_callback))) { - //|| (pdu.present > M3AP_M3AP_PDU_PR_unsuccessfulOutcome)) { - M3AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", - assoc_id, pdu.choice.unsuccessfulOutcome.procedureCode); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return -1; - } - - /* No handler present. - * This can mean not implemented or no procedure for eNB (wrong direction). - */ - if (m3ap_messages_callback[pdu.choice.unsuccessfulOutcome.procedureCode][pdu.present - 1] == NULL) { - M3AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", - assoc_id, pdu.choice.unsuccessfulOutcome.procedureCode, - m3ap_direction2String(pdu.present - 1)); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return -1; - } - /* Calling the right handler */ - ret = (*m3ap_messages_callback[pdu.choice.unsuccessfulOutcome.procedureCode][pdu.present - 1]) - (instance, assoc_id, stream, &pdu); - break; - - default: - M3AP_ERROR("[SCTP %d] Direction %d exceed expected\n", - assoc_id, pdu.present); - break; - } - - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); - return ret; -} - -int -m3ap_eNB_handle_m3_setup_request(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M3AP_M3AP_PDU_t *pdu) -{ - - M3AP_M3SetupRequest_t *m3SetupRequest; - //M3AP_M3SetupRequestIEs_t *ie; - //ServedCells__Member *servedCellMember; - - m3ap_eNB_instance_t *instance_p; - m3ap_eNB_data_t *m3ap_eNB_data; - uint32_t eNB_id = 0; - - DevAssert (pdu != NULL); - m3SetupRequest = &pdu->choice.initiatingMessage.value.choice.M3SetupRequest; - - /* - * We received a new valid M3 Setup Request on a stream != 0. - * * * * This should not happen -> reject eNB m3 setup request. - */ - - if (stream != 0) { - M3AP_ERROR("Received new m3 setup request on stream != 0\n"); - /* - * Send a m3 setup failure with protocol cause unspecified - */ - return m3ap_eNB_generate_m3_setup_failure (instance, - assoc_id, - M3AP_Cause_PR_protocol, - M3AP_CauseProtocol_unspecified, - -1); - } - - M3AP_DEBUG("Received a new M3 setup request\n"); - - //M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequestIEs_t, ie, m3SetupRequest, - // M3AP_ProtocolIE_ID_id_GlobalENB_ID, true); - //if (ie == NULL ) { - // M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - // return -1; - //} else { - // if (ie->value.choice.GlobalENB_ID.eNB_ID.present == M3AP_ENB_ID_PR_macro_eNB_ID) { - // // Home eNB ID = 28 bits - // uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; - - // if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { - // //TODO: handle case were size != 28 -> notify ? reject ? - // } - - // eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); - // M3AP_DEBUG("Home eNB id: %07x\n", eNB_id); - // } else { - // // Macro eNB = 20 bits - // uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; - - // if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { - // //TODO: handle case were size != 20 -> notify ? reject ? - // } - - // eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); - // M3AP_DEBUG("macro eNB id: %05x\n", eNB_id); - // } - //} - - M3AP_DEBUG("Adding eNB to the list of associated eNBs\n"); - - if ((m3ap_eNB_data = m3ap_is_eNB_id_in_list (eNB_id)) == NULL) { - /* - * eNB has not been found in list of associated eNB, - * * * * Add it to the tail of list and initialize data - */ - if ((m3ap_eNB_data = m3ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { - /* - * ?? - */ - return -1; - } else { - m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; - m3ap_eNB_data->eNB_id = eNB_id; - } - } else { - m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; - /* - * eNB has been found in list, consider the m3 setup request as a reset connection, - * * * * reseting any previous UE state if sctp association is != than the previous one - */ - if (m3ap_eNB_data->assoc_id != assoc_id) { - /* - * ??: Send an overload cause... - */ - M3AP_ERROR("Rejecting m3 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, m3ap_eNB_data->assoc_id, assoc_id); - - m3ap_eNB_generate_m3_setup_failure (instance, - assoc_id, - M3AP_Cause_PR_protocol, - M3AP_CauseProtocol_unspecified, - -1); - return -1; - } - /* - * TODO: call the reset procedure - */ - } - - /* Set proper pci */ -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupRequest_IEs_t, ie, m2SetupRequest, -// M3AP_ProtocolIE_ID_id_ServedCells, true); -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// if (ie->value.choice.ServedCells.list.count > 0) { -// m3ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; -// for (int i=0; ivalue.choice.ServedCells.list.count;i++) { -// servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; -// m3ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; -// } -// } -// - instance_p = m3ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - - return m3ap_eNB_generate_m3_setup_response(instance_p, m3ap_eNB_data); -} - -static -int m3ap_eNB_handle_m3_setup_response(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M3AP_M3AP_PDU_t *pdu) -{ - - M3AP_M3SetupResponse_t *m3SetupResponse; - //M3AP_M3SetupResponseIEs_t *ie; - //ServedCells__Member *servedCellMember; - - m3ap_eNB_instance_t *instance_p; - m3ap_eNB_data_t *m3ap_eNB_data; - //uint32_t eNB_id = 0; - - DevAssert (pdu != NULL); - m3SetupResponse = &pdu->choice.successfulOutcome.value.choice.M3SetupResponse; - - /* - * We received a new valid M3 Setup Response on a stream != 0. - * * * * This should not happen -> reject eNB m3 setup response. - */ - - if (stream != 0) { - M3AP_ERROR("Received new m3 setup response on stream != 0\n"); - } - - if ((m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0)) == NULL) { - M3AP_ERROR("[SCTP %d] Received M3 setup response for non existing " - "eNB context\n", assoc_id); - return -1; - } - - M3AP_DEBUG("Received a new M3 setup response\n"); - - // M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupResponseIEs_t, ie, m3SetupResponse, - // M3AP_ProtocolIE_ID_id_GlobalENB_ID, true); - - // if (ie == NULL ) { - // M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - // return -1; - // } -// if (ie->value.choice.GlobalENB_ID.eNB_ID.present == M3AP_ENB_ID_PR_macro_eNB_ID) { -// // Home eNB ID = 28 bits -// uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; -// -// if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { -// //TODO: handle case were size != 28 -> notify ? reject ? -// } -// -// eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); -// M3AP_DEBUG("Home eNB id: %07x\n", eNB_id); -// } else { -// // Macro eNB = 20 bits -// uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; -// -// if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { -// //TODO: handle case were size != 20 -> notify ? reject ? -// } -// -// eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); -// M3AP_DEBUG("macro eNB id: %05x\n", eNB_id); -// } -// - M3AP_DEBUG("Adding eNB to the list of associated eNBs\n"); - -// if ((m3ap_eNB_data = m3ap_is_eNB_id_in_list (eNB_id)) == NULL) { -// /* -// * eNB has not been found in list of associated eNB, -// * * * * Add it to the tail of list and initialize data -// */ -// if ((m3ap_eNB_data = m3ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { -// /* -// * ??: Send an overload cause... -// */ -// return -1; -// } else { -// m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; -// m3ap_eNB_data->eNB_id = eNB_id; -// } -// } else { -// m3ap_eNB_data->state = M3AP_ENB_STATE_RESETTING; -// /* -// * TODO: call the reset procedure -// */ -// } -// - /* Set proper pci */ -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupResponse_IEs_t, ie, m2SetupResponse, -// M3AP_ProtocolIE_ID_id_ServedCells, true); -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// if (ie->value.choice.ServedCells.list.count > 0) { -// m3ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; -// for (int i=0; ivalue.choice.ServedCells.list.count;i++) { -// servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; -// m3ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; -// } -// } -// - /* Optionaly set the target eNB name */ - - /* The association is now ready as source and target eNBs know parameters of each other. - * Mark the association as connected. - */ - m3ap_eNB_data->state = M3AP_ENB_STATE_READY; - - instance_p = m3ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - - instance_p->m3_target_enb_associated_nb ++; - m3ap_handle_m3_setup_message(instance_p, m3ap_eNB_data, 0); - - return 0; -} - -static -int m3ap_eNB_handle_m3_setup_failure(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M3AP_M3AP_PDU_t *pdu) -{ - - M3AP_M3SetupFailure_t *m3SetupFailure; - M3AP_M3SetupFailureIEs_t *ie; - - m3ap_eNB_instance_t *instance_p; - m3ap_eNB_data_t *m3ap_eNB_data; - - DevAssert(pdu != NULL); - - m3SetupFailure = &pdu->choice.unsuccessfulOutcome.value.choice.M3SetupFailure; - - /* - * We received a new valid M3 Setup Failure on a stream != 0. - * * * * This should not happen -> reject eNB m3 setup failure. - */ - - if (stream != 0) { - M3AP_WARN("[SCTP %d] Received m3 setup failure on stream != 0 (%d)\n", - assoc_id, stream); - } - - if ((m3ap_eNB_data = m3ap_get_eNB (NULL, assoc_id, 0)) == NULL) { - M3AP_ERROR("[SCTP %d] Received M3 setup failure for non existing " - "eNB context\n", assoc_id); - return -1; - } - - M3AP_DEBUG("Received a new M3 setup failure\n"); - - M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_M3SetupFailureIEs_t, ie, m3SetupFailure, - M3AP_ProtocolIE_ID_id_Cause, true); - - if (ie == NULL ) { - M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } - // need a FSM to handle all cases - if ((ie->value.choice.Cause.present == M3AP_Cause_PR_misc) && - (ie->value.choice.Cause.choice.misc == M3AP_CauseMisc_unspecified)) { - M3AP_WARN("Received M3 setup failure for eNB ... eNB is not ready\n"); - } else { - M3AP_ERROR("Received m3 setup failure for eNB... please check your parameters\n"); - } - - m3ap_eNB_data->state = M3AP_ENB_STATE_WAITING; - - instance_p = m3ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - - m3ap_handle_m3_setup_message(instance_p, m3ap_eNB_data, 0); - - return 0; -} - -//static -//int m3ap_eNB_handle_handover_preparation (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu) -//{ -// -// M3AP_HandoverRequest_t *x2HandoverRequest; -// M3AP_HandoverRequest_IEs_t *ie; -// -// M3AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; -// M3AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; -// -// m3ap_eNB_instance_t *instance_p; -// m3ap_eNB_data_t *m3ap_eNB_data; -// MessageDef *msg; -// int ue_id; -// -// DevAssert (pdu != NULL); -// x2HandoverRequest = &pdu->choice.initiatingMessage.value.choice.HandoverRequest; -// -// if (stream == 0) { -// M3AP_ERROR ("Received new x2 handover request on stream == 0\n"); -// /* TODO: send a x2 failure response */ -// return 0; -// } -// -// M3AP_DEBUG ("Received a new X2 handover request\n"); -// -// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); -// DevAssert(m3ap_eNB_data != NULL); -// -// instance_p = m3ap_eNB_get_instance(instance); -// DevAssert(instance_p != NULL); -// -// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_REQ); -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, -// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// /* allocate a new M3AP UE ID */ -// ue_id = m3ap_allocate_new_id(&instance_p->id_manager); -// if (ue_id == -1) { -// M3AP_ERROR("could not allocate a new M3AP UE ID\n"); -// /* TODO: cancel handover: send HO preparation failure to source eNB */ -// exit(1); -// } -// /* rnti is unknown yet, must not be set to -1, 0 is fine */ -// m3ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_M3AP_ID, ue_id); -// m3ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET); -// -// M3AP_HANDOVER_REQ(msg).m2_id = ue_id; -// -// //M3AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. -// //measResultListEUTRA.list.array[ncell_index]->physCellId; -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, -// M3AP_ProtocolIE_ID_id_GUMMEI_ID, true); -// -// TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, M3AP_HANDOVER_REQ(msg).ue_gummei.mcc, -// M3AP_HANDOVER_REQ(msg).ue_gummei.mnc, M3AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); -// OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, M3AP_HANDOVER_REQ(msg).ue_gummei.mme_code); -// OCTET_STRING_TO_INT16(&ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID, M3AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id); -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, -// M3AP_ProtocolIE_ID_id_UE_ContextInformation, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// M3AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID; -// -// /* TODO: properly store Target Cell ID */ -// -// M3AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; -// -// M3AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = -// BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); -// M3AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms = -// BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); -// -// //M3AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr; -// -// if ((ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf) && -// (ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.size == 32)) { -// memcpy(M3AP_HANDOVER_REQ(msg).kenb, ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf, 32); -// M3AP_HANDOVER_REQ(msg).kenb_ncc = ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount; -// } else { -// M3AP_WARN ("Size of eNB key star does not match the expected value\n"); -// } -// -// if (ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count > 0) { -// -// M3AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count; -// -// for (int i=0;ivalue.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count;i++) { -// e_RABS_ToBeSetup_ItemIEs = (M3AP_E_RABs_ToBeSetup_ItemIEs_t *) ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.array[i]; -// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; -// -// M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_ToBeSetup_Item->e_RAB_ID ; -// -// memcpy(M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.buffer, -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); -// -// M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.length = -// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; -// -// OCTET_STRING_TO_INT32(&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID, -// M3AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid); -// -// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI; -// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; -// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; -// M3AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability; -// } -// -// } -// else { -// M3AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n"); -// } -// -// M3AP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context; -// -// if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct m3ap_handover_req_ack_s*/) -// { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } -// -// memcpy(M3AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); -// M3AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; -// -// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); -// -// return 0; -//} -// -//static -//int m3ap_eNB_handle_handover_response (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu) -//{ -// M3AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck; -// M3AP_HandoverRequestAcknowledge_IEs_t *ie; -// -// m3ap_eNB_instance_t *instance_p; -// m3ap_eNB_data_t *m3ap_eNB_data; -// MessageDef *msg; -// int ue_id; -// int id_source; -// int id_target; -// int rnti; -// -// DevAssert (pdu != NULL); -// x2HandoverRequestAck = &pdu->choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; -// -// if (stream == 0) { -// M3AP_ERROR ("Received new x2 handover response on stream == 0\n"); -// /* TODO: send a x2 failure response */ -// return 0; -// } -// -// M3AP_DEBUG ("Received a new X2 handover response\n"); -// -// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); -// DevAssert(m3ap_eNB_data != NULL); -// -// instance_p = m3ap_eNB_get_instance(instance); -// DevAssert(instance_p != NULL); -// -// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_REQ_ACK); -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, -// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// id_source = ie->value.choice.UE_M3AP_ID; -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, -// M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// id_target = ie->value.choice.UE_M3AP_ID_1; -// -// ue_id = id_source; -// -// if (ue_id != m3ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { -// M3AP_WARN("incorrect/unknown M3AP IDs for UE (old ID %d new ID %d), ignoring handover response\n", -// id_source, id_target); -// return 0; -// } -// -// rnti = m3ap_id_get_rnti(&instance_p->id_manager, ue_id); -// -// /* id_target is a new information, store it */ -// m3ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target); -// m3ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_SOURCE_OVERALL); -// m3ap_set_reloc_overall_timer(&instance_p->id_manager, ue_id, -// m3ap_timer_get_tti(&instance_p->timers)); -// -// M3AP_HANDOVER_REQ_ACK(msg).rnti = rnti; -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, -// M3AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); -// -// M3AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer; -// -// if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct m3ap_handover_req_ack_s*/) -// { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } -// -// memcpy(M3AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); -// M3AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; -// -// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); -// return 0; -//} -// -// -//static -//int m3ap_eNB_handle_ue_context_release (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu) -//{ -// M3AP_UEContextRelease_t *x2UEContextRelease; -// M3AP_UEContextRelease_IEs_t *ie; -// -// m3ap_eNB_instance_t *instance_p; -// m3ap_eNB_data_t *m3ap_eNB_data; -// MessageDef *msg; -// int ue_id; -// int id_source; -// int id_target; -// -// DevAssert (pdu != NULL); -// x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease; -// -// if (stream == 0) { -// M3AP_ERROR ("Received new x2 ue context release on stream == 0\n"); -// /* TODO: send a x2 failure response */ -// return 0; -// } -// -// M3AP_DEBUG ("Received a new X2 ue context release\n"); -// -// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); -// DevAssert(m3ap_eNB_data != NULL); -// -// instance_p = m3ap_eNB_get_instance(instance); -// DevAssert(instance_p != NULL); -// -// msg = itti_alloc_new_message(TASK_M3AP, M3AP_UE_CONTEXT_RELEASE); -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, -// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// id_source = ie->value.choice.UE_M3AP_ID; -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, -// M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// id_target = ie->value.choice.UE_M3AP_ID_1; -// -// ue_id = id_source; -// if (ue_id != m3ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { -// M3AP_WARN("incorrect/unknown M3AP IDs for UE (old ID %d new ID %d), ignoring UE context release\n", -// id_source, id_target); -// return 0; -// } -// -// if (id_target != m3ap_id_get_id_target(&instance_p->id_manager, ue_id)) { -// M3AP_ERROR("UE context release: bad id_target for UE %x (id_source %d) expected %d got %d, ignoring message\n", -// m3ap_id_get_rnti(&instance_p->id_manager, ue_id), -// id_source, -// m3ap_id_get_id_target(&instance_p->id_manager, ue_id), -// id_target); -// return 0; -// } -// -// M3AP_UE_CONTEXT_RELEASE(msg).rnti = m3ap_id_get_rnti(&instance_p->id_manager, ue_id); -// -// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); -// -// m3ap_release_id(&instance_p->id_manager, ue_id); -// -// return 0; -//} -// -//static -//int m3ap_eNB_handle_handover_cancel (instance_t instance, -// uint32_t assoc_id, -// uint32_t stream, -// M3AP_M3AP_PDU_t *pdu) -//{ -// M3AP_HandoverCancel_t *x2HandoverCancel; -// M3AP_HandoverCancel_IEs_t *ie; -// -// m3ap_eNB_instance_t *instance_p; -// m3ap_eNB_data_t *m3ap_eNB_data; -// MessageDef *msg; -// int ue_id; -// int id_source; -// int id_target; -// m3ap_handover_cancel_cause_t cause; -// -// DevAssert (pdu != NULL); -// x2HandoverCancel = &pdu->choice.initiatingMessage.value.choice.HandoverCancel; -// -// if (stream == 0) { -// M3AP_ERROR ("Received new x2 handover cancel on stream == 0\n"); -// return 0; -// } -// -// M3AP_DEBUG ("Received a new X2 handover cancel\n"); -// -// m3ap_eNB_data = m3ap_get_eNB(NULL, assoc_id, 0); -// DevAssert(m3ap_eNB_data != NULL); -// -// instance_p = m3ap_eNB_get_instance(instance); -// DevAssert(instance_p != NULL); -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, -// M3AP_ProtocolIE_ID_id_Old_eNB_UE_M3AP_ID, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// id_source = ie->value.choice.UE_M3AP_ID; -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, -// M3AP_ProtocolIE_ID_id_New_eNB_UE_M3AP_ID, false); -// -// if (ie == NULL ) { -// M3AP_INFO("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// id_target = -1; -// } else -// id_target = ie->value.choice.UE_M3AP_ID_1; -// -// M3AP_FIND_PROTOCOLIE_BY_ID(M3AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, -// M3AP_ProtocolIE_ID_id_Cause, true); -// -// if (ie == NULL ) { -// M3AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); -// return -1; -// } -// -// if (ie->value.present != M3AP_HandoverCancel_IEs__value_PR_Cause || -// ie->value.choice.Cause.present != M3AP_Cause_PR_radioNetwork || -// !(ie->value.choice.Cause.choice.radioNetwork == -// M3AP_CauseRadioNetwork_trelocprep_expiry || -// ie->value.choice.Cause.choice.radioNetwork == -// M3AP_CauseRadioNetwork_tx2relocoverall_expiry)) { -// M3AP_ERROR("%s %d: Cause not supported (only T_reloc_prep and TX2_reloc_overall handled)\n",__FILE__,__LINE__); -// return -1; -// } -// -// switch (ie->value.choice.Cause.choice.radioNetwork) { -// case M3AP_CauseRadioNetwork_trelocprep_expiry: -// cause = M3AP_T_RELOC_PREP_TIMEOUT; -// break; -// case M3AP_CauseRadioNetwork_tx2relocoverall_expiry: -// cause = M3AP_TX2_RELOC_OVERALL_TIMEOUT; -// break; -// default: /* can't come here */ exit(1); -// } -// -// ue_id = m3ap_find_id_from_id_source(&instance_p->id_manager, id_source); -// if (ue_id == -1) { -// M3AP_WARN("Handover cancel: UE not found (id_source = %d), ignoring message\n", id_source); -// return 0; -// } -// -// if (id_target != -1 && -// id_target != m3ap_id_get_id_target(&instance_p->id_manager, ue_id)) { -// M3AP_ERROR("Handover cancel: bad id_target for UE %x (id_source %d) expected %d got %d\n", -// m3ap_id_get_rnti(&instance_p->id_manager, ue_id), -// id_source, -// m3ap_id_get_id_target(&instance_p->id_manager, ue_id), -// id_target); -// exit(1); -// } -// -// msg = itti_alloc_new_message(TASK_M3AP, M3AP_HANDOVER_CANCEL); -// -// M3AP_HANDOVER_CANCEL(msg).rnti = m3ap_id_get_rnti(&instance_p->id_manager, ue_id); -// M3AP_HANDOVER_CANCEL(msg).cause = cause; -// -// itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); -// -// m3ap_release_id(&instance_p->id_manager, ue_id); -// -// return 0; -//} diff --git a/openair3/M3AP/m3ap_eNB_handler.h b/openair3/M3AP/m3ap_eNB_handler.h deleted file mode 100644 index d0c97ac532..0000000000 --- a/openair3/M3AP/m3ap_eNB_handler.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_handler.h - * \brief m3ap handler procedures for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#ifndef M3AP_ENB_HANDLERS_H_ -#define M3AP_ENB_HANDLERS_H_ - -#include "m3ap_eNB_defs.h" - -void m3ap_handle_m3_setup_message(m3ap_eNB_instance_t *instance_p, m3ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); - -int m3ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, - const uint8_t * const data, const uint32_t data_length); - -#endif /* M3AP_ENB_HANDLERS_H_ */ diff --git a/openair3/M3AP/m3ap_eNB_itti_messaging.c b/openair3/M3AP/m3ap_eNB_itti_messaging.c deleted file mode 100644 index 834b429ccb..0000000000 --- a/openair3/M3AP/m3ap_eNB_itti_messaging.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_itti_messaging.c - * \brief m3ap tasks for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#include "intertask_interface.h" - -#include "m3ap_eNB_itti_messaging.h" - -void m3ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, - uint32_t buffer_length, uint16_t stream) -{ - MessageDef *message_p; - sctp_data_req_t *sctp_data_req; - - message_p = itti_alloc_new_message(TASK_M3AP, SCTP_DATA_REQ); - - sctp_data_req = &message_p->ittiMsg.sctp_data_req; - - sctp_data_req->assoc_id = assoc_id; - sctp_data_req->buffer = buffer; - sctp_data_req->buffer_length = buffer_length; - sctp_data_req->stream = stream; - - itti_send_msg_to_task(TASK_SCTP, instance, message_p); -} - - -void m3ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) -{ - MessageDef *message_p = NULL; - sctp_close_association_t *sctp_close_association_p = NULL; - - message_p = itti_alloc_new_message(TASK_M3AP, SCTP_CLOSE_ASSOCIATION); - sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; - sctp_close_association_p->assoc_id = assoc_id; - - itti_send_msg_to_task(TASK_SCTP, instance, message_p); -} diff --git a/openair3/M3AP/m3ap_eNB_itti_messaging.h b/openair3/M3AP/m3ap_eNB_itti_messaging.h deleted file mode 100644 index 134b00e4a9..0000000000 --- a/openair3/M3AP/m3ap_eNB_itti_messaging.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file m3ap_eNB_itti_messaging.h - * \brief m3ap tasks for eNB - * \author Javier Morgade - * \date 2019 - * \version 0.1 - */ - -#ifndef M3AP_ENB_ITTI_MESSAGING_H_ -#define M3AP_ENB_ITTI_MESSAGING_H_ - -void m3ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, - uint32_t buffer_length, uint16_t stream); - - -void m3ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); - - -#endif /* M3AP_ENB_ITTI_MESSAGING_H_ */ From 143214e7b44e99dfabb428b4e43a879a6055d788 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 17 Sep 2019 13:15:08 +0200 Subject: [PATCH 029/134] Remove few Cpp Warnings ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair2/M2AP/m2ap_MCE_interface_management.c | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c index cb8f48bf34..1bef834179 100644 --- a/openair2/M2AP/m2ap_MCE_interface_management.c +++ b/openair2/M2AP/m2ap_MCE_interface_management.c @@ -453,7 +453,7 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i pmch_configuration_item_ies->criticality = M2AP_Criticality_reject; pmch_configuration_item_ies->value.present = M2AP_PMCH_Configuration_ItemIEs__value_PR_PMCH_Configuration_Item; - M2AP_PMCH_Configuration_Item_t * pmch_configuration_item = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t)); + M2AP_PMCH_Configuration_Item_t * pmch_configuration_item;/* = (M2AP_PMCH_Configuration_Item_t*)calloc(1,sizeof(M2AP_PMCH_Configuration_Item_t));*/ pmch_configuration_item = &pmch_configuration_item_ies->value.choice.PMCH_Configuration_Item; { pmch_configuration_item->pmch_Configuration.dataMCS = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].data_mcs; @@ -515,7 +515,7 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i mbsfn_subframe_configuration_item_ies->criticality = M2AP_Criticality_reject; mbsfn_subframe_configuration_item_ies->value.present = M2AP_MBSFN_Subframe_ConfigurationItem__value_PR_MBSFN_Subframe_Configuration; - M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t)); + M2AP_MBSFN_Subframe_Configuration_t * mbsfn_subframe_configuration; /* = (M2AP_MBSFN_Subframe_Configuration_t*)calloc(1,sizeof(M2AP_MBSFN_Subframe_Configuration_t));*/ mbsfn_subframe_configuration = &mbsfn_subframe_configuration_item_ies->value.choice.MBSFN_Subframe_Configuration; { mbsfn_subframe_configuration->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period; @@ -705,7 +705,8 @@ int MCE_handle_M2_SETUP_REQUEST(instance_t instance, MessageDef *message_p; M2AP_M2SetupRequest_t *container; M2AP_M2SetupRequest_Ies_t *ie; - int i = 0,j=0; + int i = 0/*,j=0*/; + int num_mbms_available=0; DevAssert(pdu != NULL); @@ -727,10 +728,12 @@ int MCE_handle_M2_SETUP_REQUEST(instance_t instance, M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, M2AP_ProtocolIE_ID_id_GlobalENB_ID, true); //asn_INTEGER2ulong(&ie->value.choice.GlobalENB_ID.eNB_ID, &M2AP_SETUP_REQ(message_p).GlobalENB_ID); + if(ie!=NULL){ if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_macro_eNB_ID){ }else if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_short_Macro_eNB_ID){ }else if(ie->value.choice.GlobalENB_ID.eNB_ID.present == M2AP_ENB_ID_PR_long_Macro_eNB_ID){ } + } LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).GlobalENB_ID %lu \n", M2AP_SETUP_REQ(message_p).GlobalENB_ID); @@ -751,29 +754,28 @@ int MCE_handle_M2_SETUP_REQUEST(instance_t instance, M2AP_FIND_PROTOCOLIE_BY_ID(M2AP_M2SetupRequest_Ies_t, ie, container, M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List, true); - M2AP_SETUP_REQ(message_p).num_mbms_available = ie->value.choice.ENB_MBMS_Configuration_data_List.list.count; - LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).num_mbms_available %d \n", - M2AP_SETUP_REQ(message_p).num_mbms_available); - int num_mbms_available = M2AP_SETUP_REQ(message_p).num_mbms_available; - for (i=0; ivalue.choice.ENB_MBMS_Configuration_data_List.list.array[i])->value.choice.ENB_MBMS_Configuration_data_Item); - /* eCGI */ - //mbms_configuration_item_p->eCGI ... (M2AP_ECGI_t) - OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.pLMN_Identity),M2AP_SETUP_REQ(message_p).plmn_identity[i]); - //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.eUTRANcellIdentifier),M2AP_SETUP_REQ(message_p).eutran_cell_identifier[i]); - /* mbsfnSynchronisationArea */ - //mbms_configuration_item_p->mbsfnSynchronisationArea ... (M2AP_MBSFN_SynchronisationArea_ID_t) + if(ie!=NULL){ + M2AP_SETUP_REQ(message_p).num_mbms_available = ie->value.choice.ENB_MBMS_Configuration_data_List.list.count; + LOG_D(M2AP, "M2AP_SETUP_REQ(message_p).num_mbms_available %d \n", + M2AP_SETUP_REQ(message_p).num_mbms_available); + num_mbms_available = M2AP_SETUP_REQ(message_p).num_mbms_available; + for (i=0; ivalue.choice.ENB_MBMS_Configuration_data_List.list.array[i])->value.choice.ENB_MBMS_Configuration_data_Item); + /* eCGI */ + //mbms_configuration_item_p->eCGI ... (M2AP_ECGI_t) - M2AP_SETUP_REQ(message_p).mbsfn_synchronization_area[i]=mbms_configuration_item_p->mbsfnSynchronisationArea; - /* mbmsServiceAreaList */ - //mbms_configuration_item_p->mbmsServiceAreaList ... (M2AP_MBMS_Service_Area_ID_List_t) - for(j=0;j<1;j++){ - //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->mbmsServiceAreaList.list.array[j]), M2AP_SETUP_REQ(message_p).service_area_id[i][j]); - } + OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.pLMN_Identity),M2AP_SETUP_REQ(message_p).plmn_identity[i]); + //OCTET_STRING_TO_INT16(&(mbms_configuration_item_p->eCGI.eUTRANcellIdentifier),M2AP_SETUP_REQ(message_p).eutran_cell_identifier[i]); + /* mbsfnSynchronisationArea */ + //mbms_configuration_item_p->mbsfnSynchronisationArea ... (M2AP_MBSFN_SynchronisationArea_ID_t) - } + M2AP_SETUP_REQ(message_p).mbsfn_synchronization_area[i]=mbms_configuration_item_p->mbsfnSynchronisationArea; + /* mbmsServiceAreaList */ + //mbms_configuration_item_p->mbmsServiceAreaList ... (M2AP_MBMS_Service_Area_ID_List_t) + } + } // /* tac */ // OCTET_STRING_TO_INT16(&(served_celles_item_p->served_Cell_Information.fiveGS_TAC), M2AP_SETUP_REQ(message_p).tac[i]); From 189393f655a9619981e8b12eb5eb99f66dd321c7 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 17 Sep 2019 16:15:58 +0200 Subject: [PATCH 030/134] message-transfer-update --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 47 ++++++++++++++++++-- openair2/RRC/LTE/rrc_eNB.c | 9 ++-- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 19e06c8600..046d0011fc 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -47,6 +47,7 @@ #include "common/ran_context.h" #include "rrc_eNB_UE_context.h" +#include "asn1_msg.h" // undefine C_RNTI from // openair1/PHY/LTE_TRANSPORT/transport_common.h which @@ -401,8 +402,38 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, for (i = 0; i< 8; i++){ DRB2LCHAN[i] = 0; } - if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + int UE_id = find_UE_id(ctxt.module_id, ctxt.rnti); + if (UE_id != -1) { + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt.module_id]; + uint8_t cc_id = ue_context_p->ue_context.primaryCC_id; + eNB_MAC_INST *mac = RC.mac[ctxt.module_id]; + UE_list_t *UE_list = &(mac->UE_list); + + if (rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL && + UE_list->UE_template[cc_id][UE_id].rach_resource_type == 0) { + if (cc_id < MAX_NUM_CCs) { + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_p->ue_context.UE_Capability; + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, + &rrc_inst->configuration, + UEcap); + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); + LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } + } else { + LOG_E(F1AP, "Invalid CC_id for DRX configuration\n"); + } + } + } else { // UE_id invalid + LOG_E(F1AP, "Invalid UE_id found!\n"); + } + } + LTE_MeasGapConfig_t *measGapConfig = NULL; struct LTE_PhysicalConfigDedicated* physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated; rrc_rlc_config_asn1_req( @@ -602,7 +633,9 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } -int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) { +int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + const f1ap_ul_rrc_message_t *msg) +{ const rnti_t rnti = msg->rnti; F1AP_F1AP_PDU_t pdu; @@ -703,6 +736,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -715,9 +749,16 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa }else { LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti); ue_context_p->ue_context.Status = RRC_CONNECTED; - } + + int UE_id_mac = find_UE_id(instance, rnti); + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + } + } break; + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: LOG_I(F1AP, "[MSG] RRC securityModeComplete \n"); break; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 41c5cb9212..eaceddfc2a 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3202,11 +3202,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB mac_MainConfig->drx_Config = NULL; + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE - rnti_t rnti = ue_context_pP->ue_id_rnti; - module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); if (UE_id != -1) { @@ -6490,7 +6490,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; LTE_DRB_Identity_t *drb_id_p = NULL; - + ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer @@ -6498,7 +6498,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( /* CDRX: activated if ack was expected */ int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); if (UE_id_mac == -1){ - LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n",PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ue_context_pP->ue_context.rnti); + LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti); return; } UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); From f8c25858f21bbe1338025749ba57d8eefa178645 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 14:17:58 +0200 Subject: [PATCH 031/134] asn1_msg.do_DrxConfig --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 61 ++++++++++++++-------------- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 3 +- openair2/RRC/LTE/rrc_eNB.c | 4 +- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9303fb79f1..375281057f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -625,10 +625,9 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, /* * Generate the configuration structure for CDRX feature */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, - int CC_id, - RrcConfigurationReq *configuration, - LTE_UE_EUTRA_Capability_t *UEcap) +LTE_DRX_Config_t *do_DrxConfig(int CC_id, + RrcConfigurationReq *configuration, + LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { LTE_DRX_Config_t *drxConfig = NULL; @@ -666,58 +665,60 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, if (drxConfig->present == LTE_DRX_Config_PR_release) { drxConfig->choice.release = (NULL_t) 0; } else { - drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - drxConfig->choice.setup.drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; - drxConfig->choice.setup.drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; - drxConfig->choice.setup.longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; - switch (drxConfig->choice.setup.longDRX_CycleStartOffset.present) { + struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; + choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + // drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; + choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; + choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; default: break; @@ -725,12 +726,12 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, /* Short DRX cycle configuration */ if (!ueSupportCdrxShortFlag || configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer == 0) { - drxConfig->choice.setup.shortDRX = NULL; + choiceSetup->shortDRX = NULL; } else { - drxConfig->choice.setup.shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); - memset(drxConfig->choice.setup.shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); - drxConfig->choice.setup.shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; - drxConfig->choice.setup.shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; + choiceSetup->shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); + memset(choiceSetup->shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); + choiceSetup->shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; + choiceSetup->shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 7ddf939e6d..29e2e8e389 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -81,12 +81,11 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFNSubframes, uint32_t frame); /** \brief Generate configuration structure for DRX_Config -@param Mod_id Instance of eNB @param CC_id Id of component to configure @param configuration Pointer Configuration Request structure @param UEcap Pointer Configuration UE capablities @return DRX_Config structure pointer or NULL => error */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); +LTE_DRX_Config_t *do_DrxConfig(int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); /** \brief Generate configuration for SIB1 (eNB). diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d93510ac5d..73a6ea1381 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3219,7 +3219,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } @@ -3951,7 +3951,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } From 28a4d4f501bf56bae4388facd710693577008efc Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 15:42:45 +0200 Subject: [PATCH 032/134] cdrx_configured update --- openair2/LAYER2/MAC/config.c | 61 ++++++++++++++-------------- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 1 - openair2/RRC/LTE/rrc_eNB.c | 4 +- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ec2497d6ad..621dafe603 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1002,7 +1002,7 @@ void eNB_Config_Local_DRX( UE_list_t *UE_list_mac = NULL; int UE_id = -1; UE_sched_ctrl_t *UE_scheduling_control = NULL; - + UE_list_mac = &(RC.mac[Mod_id]->UE_list); UE_id = find_UE_id(Mod_id, rnti); @@ -1018,31 +1018,30 @@ void eNB_Config_Local_DRX( /* Get struct to modify */ UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]); + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; return; } - /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when ACK is received - UE_scheduling_control->cdrx_waiting_ack = TRUE; // set to true first, waiting for the UE to configure CDRX on its side + /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ + LOG_I(MAC, "Initial cdrx_waiting_ack state: %s\n", UE_scheduling_control->cdrx_waiting_ack ? "TRUE" : "FALSE"); + UE_scheduling_control->cdrx_configured = TRUE; // will be set to true + UE_scheduling_control->cdrx_waiting_ack = TRUE; // For debugging only UE_scheduling_control->in_active_time = FALSE; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; - switch (drx_Configuration->choice.setup.onDurationTimer) { + struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; + switch (choiceSetup->onDurationTimer) { case 0: UE_scheduling_control->on_duration_timer_thres = 1; break; @@ -1097,7 +1096,7 @@ void eNB_Config_Local_DRX( } UE_scheduling_control->drx_inactivity_timer = 0; - switch (drx_Configuration->choice.setup.drx_InactivityTimer) { + switch (choiceSetup->drx_InactivityTimer) { case 0: UE_scheduling_control->drx_inactivity_timer_thres = 1; break; @@ -1172,7 +1171,7 @@ void eNB_Config_Local_DRX( break; } - if (drx_Configuration->choice.setup.shortDRX == NULL) { + if (choiceSetup->shortDRX == NULL) { UE_scheduling_control->in_short_drx_cycle = FALSE; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; @@ -1180,8 +1179,8 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { UE_scheduling_control->in_short_drx_cycle = FALSE; - UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) drx_Configuration->choice.setup.shortDRX->drxShortCycleTimer; - switch (drx_Configuration->choice.setup.shortDRX->shortDRX_Cycle) { + UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; + switch (choiceSetup->shortDRX->shortDRX_Cycle) { case 0: UE_scheduling_control->short_drx_cycle_duration = 2; break; @@ -1241,70 +1240,70 @@ void eNB_Config_Local_DRX( UE_scheduling_control->in_long_drx_cycle = FALSE; UE_scheduling_control->drx_longCycle_timer = 0; - switch (drx_Configuration->choice.setup.longDRX_CycleStartOffset.present) { + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: UE_scheduling_control->drx_longCycle_timer_thres = 10; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf10; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf10; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: UE_scheduling_control->drx_longCycle_timer_thres = 20; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf20; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf20; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: UE_scheduling_control->drx_longCycle_timer_thres = 32; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf32; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf32; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: UE_scheduling_control->drx_longCycle_timer_thres = 40; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf40; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf40; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: UE_scheduling_control->drx_longCycle_timer_thres = 64; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf64; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf64; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: UE_scheduling_control->drx_longCycle_timer_thres = 80; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf80; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf80; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: UE_scheduling_control->drx_longCycle_timer_thres = 128; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf128; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf128; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: UE_scheduling_control->drx_longCycle_timer_thres = 160; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf160; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf160; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: UE_scheduling_control->drx_longCycle_timer_thres = 256; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf256; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf256; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: UE_scheduling_control->drx_longCycle_timer_thres = 320; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf320; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf320; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: UE_scheduling_control->drx_longCycle_timer_thres = 512; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf512; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf512; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: UE_scheduling_control->drx_longCycle_timer_thres = 640; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf640; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf640; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: UE_scheduling_control->drx_longCycle_timer_thres = 1024; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1024; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1024; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: UE_scheduling_control->drx_longCycle_timer_thres = 1280; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1280; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1280; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: UE_scheduling_control->drx_longCycle_timer_thres = 2048; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2048; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2048; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: UE_scheduling_control->drx_longCycle_timer_thres = 2560; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2560; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560; break; default: LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n"); @@ -1312,7 +1311,7 @@ void eNB_Config_Local_DRX( } memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer)); - switch (drx_Configuration->choice.setup.drx_RetransmissionTimer) { + switch (choiceSetup->drx_RetransmissionTimer) { case 0: memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 375281057f..f38720f56c 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -667,7 +667,6 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } else { struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - // drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 73a6ea1381..068f24d5ab 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6503,8 +6503,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; - LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + // UE_scheduling_control->cdrx_configured = TRUE; + LOG_I(RRC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); } } // No CDRX with the CU/DU split in this version of the code From 73a90bf637895f48d9b461828498a2df8495db33 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Thu, 5 Sep 2019 15:27:26 +0200 Subject: [PATCH 033/134] Status RRC-RECONFIGURED update --- openair2/RRC/LTE/L2_interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 219c905c42..522f42d5fd 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -312,10 +312,8 @@ mac_rrc_data_ind( if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) { LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status); return (-1); - } else { - rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - } + } + rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); } } From cd6b19fa53aed121a35a15b8e872223cec65cbe7 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 10 Sep 2019 15:46:25 +0200 Subject: [PATCH 034/134] rrc_eNB update 10/09 --- openair2/RRC/LTE/rrc_eNB.c | 84 +++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 068f24d5ab..41c5cb9212 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3201,45 +3201,47 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB + mac_MainConfig->drx_Config = NULL; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); if (UE_id != -1) { + eNB_MAC_INST *mac = RC.mac[module_id]; + UE_list_t *UE_list = &(mac->UE_list); + if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); - - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + // CDRX can be only configured in case of FDD and non BR UE (09/04/19) + + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + /* Process the IE drx_Config */ + if (cc_id < MAX_NUM_CCs) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } + } else { + LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); + } } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - mac_MainConfig->drx_Config = NULL; + LOG_D(RRC, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); - mac_MainConfig->drx_Config = NULL; } } else { // No CDRX with the CU/DU split in this version LOG_E(RRC, "CU/DU split activated\n"); - mac_MainConfig->drx_Config = NULL; } + if (mac_MainConfig->drx_Config != NULL) { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -6691,16 +6693,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif - ); - } + ); + } } else { // remove LCHAN from MAC/PHY if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB @@ -6709,11 +6711,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_req(ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - DRB2LCHAN[i], - Rlc_info_um); + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + DRB2LCHAN[i], + Rlc_info_um); } } @@ -6765,13 +6767,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); } From 7e088701e1745555fdc595b1793d93457cd19a87 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 17 Sep 2019 16:15:58 +0200 Subject: [PATCH 035/134] message-transfer-update --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 47 ++++++++++++++++++-- openair2/RRC/LTE/rrc_eNB.c | 9 ++-- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 19e06c8600..046d0011fc 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -47,6 +47,7 @@ #include "common/ran_context.h" #include "rrc_eNB_UE_context.h" +#include "asn1_msg.h" // undefine C_RNTI from // openair1/PHY/LTE_TRANSPORT/transport_common.h which @@ -401,8 +402,38 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, for (i = 0; i< 8; i++){ DRB2LCHAN[i] = 0; } - if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + int UE_id = find_UE_id(ctxt.module_id, ctxt.rnti); + if (UE_id != -1) { + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt.module_id]; + uint8_t cc_id = ue_context_p->ue_context.primaryCC_id; + eNB_MAC_INST *mac = RC.mac[ctxt.module_id]; + UE_list_t *UE_list = &(mac->UE_list); + + if (rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL && + UE_list->UE_template[cc_id][UE_id].rach_resource_type == 0) { + if (cc_id < MAX_NUM_CCs) { + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_p->ue_context.UE_Capability; + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, + &rrc_inst->configuration, + UEcap); + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); + LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } + } else { + LOG_E(F1AP, "Invalid CC_id for DRX configuration\n"); + } + } + } else { // UE_id invalid + LOG_E(F1AP, "Invalid UE_id found!\n"); + } + } + LTE_MeasGapConfig_t *measGapConfig = NULL; struct LTE_PhysicalConfigDedicated* physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated; rrc_rlc_config_asn1_req( @@ -602,7 +633,9 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } -int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) { +int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + const f1ap_ul_rrc_message_t *msg) +{ const rnti_t rnti = msg->rnti; F1AP_F1AP_PDU_t pdu; @@ -703,6 +736,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -715,9 +749,16 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa }else { LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti); ue_context_p->ue_context.Status = RRC_CONNECTED; - } + + int UE_id_mac = find_UE_id(instance, rnti); + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + } + } break; + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: LOG_I(F1AP, "[MSG] RRC securityModeComplete \n"); break; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 41c5cb9212..eaceddfc2a 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3202,11 +3202,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB mac_MainConfig->drx_Config = NULL; + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE - rnti_t rnti = ue_context_pP->ue_id_rnti; - module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); if (UE_id != -1) { @@ -6490,7 +6490,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; LTE_DRB_Identity_t *drb_id_p = NULL; - + ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer @@ -6498,7 +6498,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( /* CDRX: activated if ack was expected */ int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); if (UE_id_mac == -1){ - LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n",PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ue_context_pP->ue_context.rnti); + LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti); return; } UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); From 0bc7cf7c2fa1e762f33f089d189efe34277374e4 Mon Sep 17 00:00:00 2001 From: LouisAdrien Date: Wed, 18 Sep 2019 10:46:28 +0200 Subject: [PATCH 036/134] comment cdrx --- openair2/RRC/LTE/rrc_eNB.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index eaceddfc2a..06e0ae4444 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3202,10 +3202,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB mac_MainConfig->drx_Config = NULL; + /* rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX Configuration */ + // CDRX Configuration // Need to check if UE is a BR UE int UE_id = find_UE_id(module_id, rnti); @@ -3219,7 +3220,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - /* Process the IE drx_Config */ + // Process the IE drx_Config if (cc_id < MAX_NUM_CCs) { mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE if (mac_MainConfig->drx_Config == NULL) { @@ -3238,11 +3239,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t LOG_E(RRC, "CU/DU split activated\n"); } if (mac_MainConfig->drx_Config != NULL) { - /* Set timers and thresholds values in local MAC context of UE */ + // Set timers and thresholds values in local MAC context of UE eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - } - + } +*/ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2 = 2*SR @@ -6493,9 +6494,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer - +/* if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX: activated if ack was expected */ + // CDRX: activated if ack was expected int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); if (UE_id_mac == -1){ LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n", @@ -6510,7 +6511,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LOG_I(RRC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); } } // No CDRX with the CU/DU split in this version of the code - +*/ T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), From 3fbaf01eb31a1ef140838e54e1a6d14416314449 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Wed, 18 Sep 2019 12:57:22 +0200 Subject: [PATCH 037/134] Minor changes to also nable MBMS TUN interfaces with S1 ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- ...cc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf | 378 ++++++++++++++++++ openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 22 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 1 + openair2/RRC/NAS/nas_config.c | 42 ++ openair2/RRC/NAS/nas_config.h | 14 + targets/RT/USER/lte-softmodem.c | 2 + 6 files changed, 454 insertions(+), 5 deletions(-) create mode 100644 ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf new file mode 100644 index 0000000000..b61e5e05b1 --- /dev/null +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf @@ -0,0 +1,378 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 600; + + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 2; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -104; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "DISABLE" + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.15.130"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + + ////////// MCE parameters: + target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///M2 + enable_enb_m2 = "yes"; + + + mbms_configuration_data_list = ( + { + mbsfn_sync_area = 0x0001; + mbms_service_area_list=( + { + mbms_service_area=0x0001; + } + ); + } + + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "enp2s0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.10.15/24"; + ENB_INTERFACE_NAME_FOR_S1U = "enp2s0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.10.15/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; + ENB_PORT_FOR_M2C = 36443; # Spec 36443 + }; + } +); + +MCEs = ( + { + MCE_ID = 0xe00; + + MCE_name = "MCE-Vicomtech-LTEBox"; + + //M2 + enable_mce_m2 = "yes"; + + //M3 + enable_mce_m3 = "yes"; + + target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + + NETWORK_INTERFACES : + { + MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; + MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; + MCE_PORT_FOR_M2C = 36443; # Spec 36443 + + MCE_INTERFACE_NAME_FOR_M3_MME = "lo"; + MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; + MCE_PORT_FOR_M3C = 36444; # Spec 36444 + }; + + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + }; + + mbms_sched_info : + { + mcch_update_time = 10; + mbms_area_config_list = ( + { + common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6) + mbms_area_id = 0; + pmch_config_list = ( + { + allocated_sf_end=32; + data_mcs=14; + mch_scheduling_period = 0; #rf8(0) + mbms_session_list = ( + { + #plnm + service_id ->tmgi + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + } + service_id=0; #keep this allways as 0 (workaround for TUN if) + lcid=6; #this must be properly defined lcid:6+service:0 -> rab_id:6 + } + ); + } + ); + + mbms_sf_config_list = ( + { + radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) + radioframe_alloocation_offset=0; + num_frame="oneFrame"; + subframe_allocation=57; #xx111001 + //num_frame="fourFrame"; + //subframe_allocation=14548987; # + } + ); + + } + ); + }; + + + mcch_config_per_mbsfn_area = ( + { + mbsfn_area = 0; + pdcch_length = 1; #s1(0), s2(1) + repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3) + offset = 0; + modification_period = 0; #rf512(0; rf1024(1) + subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000 + mcs = 1; #n2(0), n7(1), n13(2), n19(3) + } + ); + + #); #end mbms_scheduling_info + + } +); +MMEs = ( + { + MME_ID = 0xe00; + + MME_name = "MME-MBMS-Vicomtech-LTEBox"; + + //M3 + enable_mme_m3 = "yes"; + NETWORK_INTERFACES : + { + MME_INTERFACE_NAME_FOR_M3_MCE = "lo"; + MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24"; + MME_PORT_FOR_M3C = 36444; # Spec 36444 + + }; + } +); + + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "no" + tr_preference = "udp_if4p5" + nb_tx = 2 + nb_rx = 2 + att_tx = 0 + att_rx = 0; + eNB_instances = [0]; + is_slave = "no"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; +}; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 8db23e4e4e..d531132117 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -1344,9 +1344,10 @@ pdcp_mbms_run ( // // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer // if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { - if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { + //if (EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { + pdcp_fifo_read_input_mbms_sdus_fromtun(ctxt_pP); - } + //} // PDCP -> NAS/IP traffic: RX // if (ctxt_pP->enb_flag) { @@ -2300,14 +2301,25 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { } else if(ENB_NAS_USE_TUN) { netlink_init_tun("enb",1); nas_config(1, 1, 1, "enb"); - netlink_init_mbms_tun("enm",1); - nas_config_mbms(1, 2, 1, "enm"); + if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){ + netlink_init_mbms_tun("enm",1); + nas_config_mbms(1, 2, 1, "enm"); + LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n"); + } LOG_I(PDCP, "ENB pdcp will use tun interface\n"); } else { LOG_I(PDCP, "pdcp will use kernel modules\n"); netlink_init(); } - } + }else{ + if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){ + LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n"); + netlink_init_mbms_tun("enm",1); + nas_config_mbms_s1(1, 2, 1, "enm"); + }else + LOG_E(PDCP, "ENB pdcp will not use tun interface\n"); + } + return pdcp_params.optmask ; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index d0cf1ad98c..2ba96810e6 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -62,6 +62,7 @@ typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_fl /* UEs beyond that will be multiplexed on the same tun */ #define MAX_NUMBER_NETIF 16 +#define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10) #define PDCP_USE_NETLINK_BIT (1<< 11) #define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13) #define LINK_ENB_PDCP_TO_GTPV1U_BIT (1<< 14) diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index fa9799c177..242f1c0c97 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -269,6 +269,48 @@ int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifn return returnValue; } +int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { + //char buf[5]; + char ipAddress[20]; + char broadcastAddress[20]; + char interfaceName[20]; + int returnValue; + //if(strcmp(ifname,"ue") == 0) + //sprintf(ipAddress, "%s.%d.%d", "20.0",thirdOctet,fourthOctet); + ////else + sprintf(ipAddress, "%s.%d.%d","10.0",thirdOctet,fourthOctet); + + sprintf(broadcastAddress, "%s.%d.255","10.0", thirdOctet); + sprintf(interfaceName, "%s%s%d", "oaitun_",ifname,interface_id); + bringInterfaceUp(interfaceName, 0); + // sets the machine address + returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR); + + // sets the machine network mask + if(!returnValue) + returnValue= setInterfaceParameter(interfaceName, "255.255.255.0",SIOCSIFNETMASK); + printf("returnValue %d\n",returnValue); + + // sets the machine broadcast address + if(!returnValue) + returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR); + printf("returnValue %d\n",returnValue); + + if(!returnValue) + bringInterfaceUp(interfaceName, 1); + printf("returnValue %d\n",returnValue); + + if(!returnValue) + LOG_I(OIP,"Interface %s successfuly configured, ip address %s, mask %s broadcast address %s\n", + interfaceName, ipAddress, "255.255.255.0", broadcastAddress); + else + LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n", + interfaceName, ipAddress, "255.255.255.0", broadcastAddress); + + return returnValue; +} + + // non blocking full configuration of the interface (address, and the two lest octets of the address) int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { //char buf[5]; diff --git a/openair2/RRC/NAS/nas_config.h b/openair2/RRC/NAS/nas_config.h index 9c7945107d..de84a854ca 100644 --- a/openair2/RRC/NAS/nas_config.h +++ b/openair2/RRC/NAS/nas_config.h @@ -76,6 +76,20 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix */ int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix); +/*! \fn int nas_config_mbms_s1(char*, int, int) + * \brief This function initializes the nasmesh interface using the basic values, + * basic address, network mask and broadcast address, as the default configured + * ones + * \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1 + * \param[in] third octet of the ip address e.g. for the 10.1.2.3 address would be 2 + * \param[in] fourth octet of the ip address e.g. for the 10.1.2.3 address would be 3 + * \return 0 on success, otherwise 1, if couldn't open a socket and 2 if the ioctl fails + * \note + * @ingroup ????? + */ +int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix); + + /*! \fn int blocking_NAS_config(char*, char*, char*, char*) * \brief This function initializes the nasmesh interface, in a blocking way, diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 1bc02f358c..a7bed02f51 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -496,6 +496,8 @@ void init_pdcp(void) { if (IS_SOFTMODEM_NOS1) pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT; + pdcp_module_init(pdcp_initmask); if (NODE_IS_CU(RC.rrc[0]->node_type)) { From c86f8d6539e652fd7f77f15a72936971d564abb3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 3 Sep 2019 14:31:16 +0200 Subject: [PATCH 038/134] CI: first scripts for Inria R2LAB deployment -- Adding the python framework of build and test to inria r2lab pipeline -- R2LAB pipeline has logCollections and artifacts storing -- Python framework should support latest Rel14 OAI openair-cn/cn-cups EPC -- Pipeline uses the latest version of booking-lease script (by duration) -- Support for distributed smartphone adb servers -- Initial scenarios: ** Build on one OAI 4G eNB and one OAI 4G UE ** Test in FDD band7 / 5MHz / TM1 in noS1 configuration ** Test in FDD band7 / 5MHz / TM1 with latest OpenAir-CN-CUPS --> just attachment Signed-off-by: Raphael Defosseux --- ci-scripts/.gitignore | 7 + ci-scripts/Jenkinsfile-inria-r2lab | 408 ++++++++++++++++++ ci-scripts/main.py | 383 ++++++++++++---- .../inria/enb_ue_usrp210_band7_epc_start.xml | 53 +++ .../inria/enb_ue_usrp210_band7_epc_stop.xml | 47 ++ .../inria/enb_ue_usrp210_band7_terminate.xml | 42 ++ .../enb_ue_usrp210_band7_test_05mhz_tm1.xml | 68 +++ ...b_ue_usrp210_band7_test_05mhz_tm1_nos1.xml | 118 +++++ .../inria/enb_usrp210_band7_build.xml | 58 +++ ci-scripts/xml_files/inria/ue_band7_build.xml | 38 ++ 10 files changed, 1129 insertions(+), 93 deletions(-) create mode 100644 ci-scripts/.gitignore create mode 100644 ci-scripts/Jenkinsfile-inria-r2lab create mode 100644 ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml create mode 100644 ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_stop.xml create mode 100644 ci-scripts/xml_files/inria/enb_ue_usrp210_band7_terminate.xml create mode 100644 ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml create mode 100644 ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml create mode 100644 ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml create mode 100644 ci-scripts/xml_files/inria/ue_band7_build.xml diff --git a/ci-scripts/.gitignore b/ci-scripts/.gitignore new file mode 100644 index 0000000000..d77a672c0c --- /dev/null +++ b/ci-scripts/.gitignore @@ -0,0 +1,7 @@ +enb_*.log +ue_*.log +ping_*.* +iperf_*.* +phones_list.txt +modules_list.txt +test_results*.html diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab new file mode 100644 index 0000000000..6fe2e3bb2a --- /dev/null +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -0,0 +1,408 @@ +#!/bin/groovy +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// Abstraction function to send social media messages: +// like on Slack or Mattermost +def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { + if (params.pipelineUsesSlack != null) { + if (params.pipelineUsesSlack) { + slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage + } + } +} + +// Location of the test XML file to be run +def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true + +// Name of the test stage +def testStageName = params.pipelineTestStageName + +// Name of the branch to work on +def ranRepoBranch = params.pythonWorkingBranch + +// Lease booking parameters +def r2labStartTime = params.R2LAB_LeaseBookStartTime +def r2labDuration = params.R2LAB_LeaseBookDuration + + +// Fixed deployment +def r2labBaseIpAddr = '192.168.3.' +def r2labPythonExeIdx = '14' +def r2labPythonExe = 'fit' + r2labPythonExeIdx +def r2labENB0Idx = '23' +def r2labENB0 = 'fit' + r2labENB0Idx +def r2labENB0IpAddr = r2labBaseIpAddr + r2labENB0Idx +def r2labEPC0Idx = '17' +def r2labEPC0 = 'fit' + r2labEPC0Idx +def r2labEPC0IpAddr = r2labBaseIpAddr + r2labEPC0Idx +def r2labUE0Idx = '6' +def r2labUE0 = 'fit0' + r2labUE0Idx +def r2labUE0IpAddr = r2labBaseIpAddr + r2labUE0Idx + +pipeline { + agent { + label 'master' + } + + options { + disableConcurrentBuilds() + timestamps() + ansiColor('xterm') + } + + stages { + stage ("Book session") { + steps { + script { + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' + + def allParametersPresent = true + if (params.R2LAB_Credentials == null) { + allParametersPresent = false + } + if (params.R2LAB_FitNode_Credentials == null) { + allParametersPresent = false + } + if (params.R2LAB_LeaseBookStartTime == null) { + allParametersPresent = false + } + if (params.R2LAB_LeaseBookDuration == null) { + allParametersPresent = false + } + + // If not present picking a default Stage Name + if (params.pipelineTestStageName == null) { + // picking default + testStageName = 'Tests at Inria R2LAB' + } + // If not present picking a default branch name + if (params.pythonWorkingBranch == null) { + ranRepoBranch = 'develop' + } + + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/inria/enb_usrp210_band7_build.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + + if (!allParametersPresent) { + currentBuild.result = 'ABORTED' + error('Stopping early because no R2LAB credentials') + } + + JOB_TIMESTAMP = sh returnStdout: true, script: 'date --rfc-3339=seconds | sed -e "s#+00:00##"' + JOB_TIMESTAMP = JOB_TIMESTAMP.trim() + + echo '\u2705 \u001B[32mBook a Session\u001B[0m' + + BOOK_TIMESTAMP = sh returnStdout: true, script: 'date --rfc-3339=date' + BOOK_TIMESTAMP = BOOK_TIMESTAMP.trim() + + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_Credentials}", usernameVariable: 'r2labuser', passwordVariable: 'r2labpassword'] + ]) { + sh "python3 /home/eurecom/inria-scripts/booking-lease.py --book-lease --from ${BOOK_TIMESTAMP}T${r2labStartTime} --duration ${r2labDuration} --slice inria_oaici ${r2labuser} ${r2labpassword}" + sh "python3 /home/eurecom/inria-scripts/booking-lease.py --get-leases ${r2labuser} ${r2labpassword}" + } + } + } + } + stage ("Load Images") { + steps { + script { + echo '\u2705 \u001B[32mLoad Image for Python Executor\u001B[0m' + sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labPythonExeIdx} > /dev/null 2>&1'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labPythonExeIdx}'" + + echo '\u2705 \u001B[32mLoad Image for one eNB\u001B[0m' + sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx} > /dev/null 2>&1'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx}'" + sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx}'" + + echo '\u2705 \u001B[32mLoad Image for one OAI UE\u001B[0m' + sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labUE0Idx} > /dev/null 2>&1'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labUE0Idx}'" + sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labUE0Idx}'" + + echo '\u2705 \u001B[32mLoad Image for one EPC\u001B[0m' + sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-epc ${r2labEPC0Idx} > /dev/null 2>&1'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labEPC0Idx}'" + + sh "ssh -t inria_oaici@faraday.inria.fr 'nodes ${r2labUE0Idx},${r2labPythonExeIdx},${r2labEPC0Idx},${r2labENB0Idx} && st'" + } + } + } + stage ("Prepare Python Executor") { + steps { + script { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g && git fetch --all --prune --quiet\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g && git checkout --quiet ${ranRepoBranch}\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g && git pull --quiet origin ${ranRepoBranch}\"'" + GIT_COMMIT_TO_RUN = sh returnStdout: true, script: "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g && git log -n1 --pretty=format:%H\"' | grep -v fit" + GIT_COMMIT_TO_RUN = GIT_COMMIT_TO_RUN.trim() + echo "Latest commit to use is ${GIT_COMMIT_TO_RUN}" + + // Putting the adaptation parameters for the OAI UE + sh "ssh -t inria_oaici@faraday.inria.fr 'scp /home/inria_oaici/for-ci/adapt_usim_parameters_${r2labUE0}.sed ${fituser}@${r2labUE0}:/tmp'" + + // Out of rload, the sub-network-interfaces are not up + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:m11 172.16.1.102 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:m10 192.168.10.110 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:sxu 172.55.55.102 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:s1u 192.168.248.159 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:sxc 172.55.55.101 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:s5c 172.58.58.102 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:p5c 172.58.58.101 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:s11 172.16.1.104 up\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"ifconfig\"'" + } + } + } + } + stage ("Build and Test") { + steps { + script { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=InitiateHtml --ranRepository=https://gitlab.eurecom.fr/oai/openairinterface5g --ranBranch=${ranRepoBranch} --ranCommitID=${GIT_COMMIT_TO_RUN} --ranAllowMerge=false --ADBIPAddress=${r2labEPC0IpAddr} --ADBUserName=${fituser} --ADBPassword=${fitpasswd} --ADBType=distributed ${mainPythonAllXmlFiles}\"'" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + try { + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=TesteNB --ranRepository=https://gitlab.eurecom.fr/oai/openairinterface5g --ranBranch=${ranRepoBranch} --ranCommitID=${GIT_COMMIT_TO_RUN} --ranAllowMerge=false --eNBIPAddress=${r2labENB0IpAddr} --eNBUserName=${fituser} --eNBPassword=${fitpasswd} --eNBSourceCodePath=/home/${fituser}/openairinterface5g --UEIPAddress=${r2labUE0IpAddr} --UEUserName=${fituser} --UEPassword=${fitpasswd} --UESourceCodePath=/home/${fituser}/openairinterface5g --EPCIPAddress=${r2labEPC0IpAddr} --EPCType=OAI-Rel14-CUPS --EPCUserName=${fituser} --EPCPassword=${fitpasswd} --EPCSourceCodePath=/home/${fituser}/openair-cn --ADBIPAddress=${r2labEPC0IpAddr} --ADBUserName=${fituser} --ADBPassword=${fitpasswd} --ADBType=distributed --XMLTestFile=${xmlFile}\"'" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${r2labENB0IpAddr} --eNBUserName=${fituser} --eNBPassword=${fitpasswd}\"'" + } + } + } + } + stage ("Prepare Log Collection") { + steps { + sh "ssh -t inria_oaici@faraday.inria.fr 'mkdir -p /home/inria_oaici/archives'" + sh "ssh -t inria_oaici@faraday.inria.fr 'touch /home/inria_oaici/archives/no_error.txt'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rm -f /home/inria_oaici/archives/*.*'" + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labPythonExe}:/home/${fituser}/openairinterface5g/ci-scripts/test_results.html /home/inria_oaici/archives'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/test_results.html ." + script { + if(fileExists("./test_results.html")) { + sh "mv ./test_results.html test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-${JOB_NAME}.html" + archiveArtifacts "test_results-${JOB_NAME}.html" + } + } + } + } + stage ("Log Collection") { + parallel { + stage('Log Collection (OAI eNB - Build)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (OAI eNB - Build)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectBuild --eNBIPAddress=${r2labENB0IpAddr} --eNBUserName=${fituser} --eNBPassword=${fitpasswd} --eNBSourceCodePath=/home/${fituser}/openairinterface5g\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labENB0}:/home/${fituser}/openairinterface5g/cmake_targets/build.log.zip /home/inria_oaici/archives/enb.build.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/enb.build.log.zip enb.build.log.${env.BUILD_ID}.zip" + script { + if(fileExists("enb.build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "enb.build.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (OAI UE - Build)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Build)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectBuild --UEIPAddress=${r2labUE0IpAddr} --UEUserName=${fituser} --UEPassword=${fitpasswd} --UESourceCodePath=/home/${fituser}/openairinterface5g\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labUE0}:/home/${fituser}/openairinterface5g/cmake_targets/build.log.zip /home/inria_oaici/archives/ue.build.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/ue.build.log.zip ue.build.log.${env.BUILD_ID}.zip" + script { + if(fileExists("ue.build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ue.build.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (OAI eNB - Runs)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (OAI eNB - Runs)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollecteNB --eNBIPAddress=${r2labENB0IpAddr} --eNBUserName=${fituser} --eNBPassword=${fitpasswd} --eNBSourceCodePath=/home/${fituser}/openairinterface5g\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labENB0}:/home/${fituser}/openairinterface5g/cmake_targets/enb.log.zip /home/inria_oaici/archives/enb.run.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/enb.run.log.zip enb.run.log.${env.BUILD_ID}.zip" + script { + if(fileExists("enb.run.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "enb.run.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (OAI UE - Runs)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Runs)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectOAIUE --UEIPAddress=${r2labUE0IpAddr} --UEUserName=${fituser} --UEPassword=${fitpasswd} --UESourceCodePath=/home/${fituser}/openairinterface5g\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labUE0}:/home/${fituser}/openairinterface5g/cmake_targets/ue.log.zip /home/inria_oaici/archives/ue.run.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/ue.run.log.zip ue.run.log.${env.BUILD_ID}.zip" + script { + if(fileExists("ue.run.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ue.run.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (MME)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectMME --EPCIPAddress=${r2labEPC0IpAddr} --EPCUserName=${fituser} --EPCPassword=${fitpasswd} --EPCSourceCodePath=/home/${fituser}/openair-cn --EPCType=OAI-Rel14-CUPS\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labEPC0}:/home/${fituser}/openair-cn/scripts/mme.log.zip /home/inria_oaici/archives/mme.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/mme.log.zip mme.log.${env.BUILD_ID}.zip" + script { + if(fileExists("mme.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "mme.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (HSS)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectHSS --EPCIPAddress=${r2labEPC0IpAddr} --EPCUserName=${fituser} --EPCPassword=${fitpasswd} --EPCSourceCodePath=/home/${fituser}/openair-cn --EPCType=OAI-Rel14-CUPS\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labEPC0}:/home/${fituser}/openair-cn/scripts/hss.log.zip /home/inria_oaici/archives/hss.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/hss.log.zip hss.log.${env.BUILD_ID}.zip" + script { + if(fileExists("hss.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "hss.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (SPGW)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectSPGW --EPCIPAddress=${r2labEPC0IpAddr} --EPCUserName=${fituser} --EPCPassword=${fitpasswd} --EPCSourceCodePath=/home/${fituser}/openair-cn --EPCType=OAI-Rel14-CUPS\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labEPC0}:/home/${fituser}/openair-cn/scripts/spgw.log.zip /home/inria_oaici/archives/spgw.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/spgw.log.zip spgw.log.${env.BUILD_ID}.zip" + script { + if(fileExists("spgw.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "spgw.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Ping)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectPing --EPCIPAddress=${r2labEPC0IpAddr} --EPCUserName=${fituser} --EPCPassword=${fitpasswd} --EPCSourceCodePath=/home/${fituser}/openair-cn --EPCType=OAI-Rel14-CUPS\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labEPC0}:/home/${fituser}/openair-cn/scripts/ping.log.zip /home/inria_oaici/archives/ping.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/ping.log.zip ping.log.${env.BUILD_ID}.zip" + script { + if(fileExists("ping.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ping.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Iperf)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.R2LAB_FitNode_Credentials}", usernameVariable: 'fituser', passwordVariable: 'fitpasswd'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m' + sh "ssh -t -t inria_oaici@faraday.inria.fr 'ssh -t -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"cd openairinterface5g/ci-scripts && python3 main.py --mode=LogCollectIperf --EPCIPAddress=${r2labEPC0IpAddr} --EPCUserName=${fituser} --EPCPassword=${fitpasswd} --EPCSourceCodePath=/home/${fituser}/openair-cn --EPCType=OAI-Rel14-CUPS\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp ${fituser}@${r2labEPC0}:/home/${fituser}/openair-cn/scripts/iperf.log.zip /home/inria_oaici/archives/iperf.log.zip'" + } + sh "scp inria_oaici@faraday.inria.fr:/home/inria_oaici/archives/iperf.log.zip iperf.log.${env.BUILD_ID}.zip" + script { + if(fileExists("iperf.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "iperf.log.${env.BUILD_ID}.zip" + } + } + } + } + } + } + stage ("Clean-up Log Collection") { + steps { + sh "ssh -t inria_oaici@faraday.inria.fr 'rm -Rf /home/inria_oaici/archives'" + } + } + } + + post { + always { + script { + echo '\u2705 \u001B[32mShutdown every node\u001B[0m' + sh 'ssh -t inria_oaici@faraday.inria.fr "all-off"' + sh 'ssh -t inria_oaici@faraday.inria.fr "all-off"' + } + } + } +} diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 3c79e6387a..34628fc4f9 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -120,6 +120,7 @@ class SSHConnection(): self.ADBIPAddress = '' self.ADBUserName = '' self.ADBPassword = '' + self.ADBCentralized = True self.testCase_id = '' self.testXMLfiles = [] self.nbTestXMLfiles = 0 @@ -140,6 +141,10 @@ class SSHConnection(): self.nbMaxUEtoAttach = -1 self.UEDevices = [] self.UEDevicesStatus = [] + self.UEDevicesRemoteServer = [] + self.UEDevicesRemoteUser = [] + self.UEDevicesOffCmd = [] + self.UEDevicesOnCmd = [] self.CatMDevices = [] self.UEIPAddresses = [] self.htmlFile = '' @@ -204,7 +209,7 @@ class SSHConnection(): logging.debug('self.sshresponse = ' + str(self.sshresponse)) elif self.sshresponse == 2: # Checking if we are really on the remote client defined by its IP address - self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:"', '\$', 5) + self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5) result = re.search(str(ipaddress), str(self.ssh.before)) if result is None: self.close() @@ -604,19 +609,29 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log logs/hss*.*', '\$', 5) + self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) + self.command('chmod 755 ./my-hss.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss.log ./my-hss.sh', '\$', 5) + elif re.match('OAI', self.EPCType, re.IGNORECASE): logging.debug('Using the OAI EPC HSS') self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd scripts', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + self.testCase_id + '.log &', 'Core state: 2 -> 3', 35) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): logging.debug('Using the ltebox simulated HSS') self.command('if [ -d ' + self.EPCSourceCodePath + '/scripts ]; then echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) self.command('mkdir -p ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('cd /opt/hss_sim0609', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log daemon.log', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S echo "Starting sudo session" && sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real ', '\$', 5) + else: + logging.error('This option should not occur!') self.close() self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) @@ -625,7 +640,14 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + logging.debug('Using the OAI EPC Release 14 MME') + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f mme.log', '\$', 5) + self.command('echo "./run_mme --config-file /usr/local/etc/oai/mme.conf --set-virt-if" > ./my-mme.sh', '\$', 5) + self.command('chmod 755 ./my-mme.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/mme.log ./my-mme.sh', '\$', 5) + elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd scripts', '\$', 5) @@ -636,9 +658,11 @@ class SSHConnection(): sys.exit(1) host_name = result.group('host_name') self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + self.testCase_id + '.log &', 'MME app initialization complete', 100) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_mme', '\$', 5) + else: + logging.error('This option should not occur!') self.close() self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) @@ -647,14 +671,27 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + logging.debug('Using the OAI EPC Release 14 SPGW-CUPS') + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f spgwc.log spgwu.log', '\$', 5) + self.command('echo "spgwc -c /usr/local/etc/oai/spgw_c.conf" > ./my-spgwc.sh', '\$', 5) + self.command('chmod 755 ./my-spgwc.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwc.log ./my-spgwc.sh', '\$', 5) + time.sleep(5) + self.command('echo "spgwu -c /usr/local/etc/oai/spgw_u.conf" > ./my-spgwu.sh', '\$', 5) + self.command('chmod 755 ./my-spgwu.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwu.log ./my-spgwu.sh', '\$', 5) + elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd scripts', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + self.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_xGw', '\$', 5) + else: + logging.error('This option should not occur!') self.close() self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) @@ -831,12 +868,18 @@ class SSHConnection(): self.close() - def InitializeUE_common(self, device_id): - logging.debug('send adb commands') + def InitializeUE_common(self, device_id, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if not self.ADBCentralized: + # enable data service + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) + # airplane mode on // radio off + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) + self.close() + return # enable data service - self.command('stdbuf -o0 adb -s ' + device_id + ' shell svc data enable', '\$', 60) + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) # The following commands are deprecated since we no longer work on Android 7+ # self.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10) @@ -858,11 +901,13 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') multi_jobs = [] + i = 0 for device_id in self.UEDevices: - p = Process(target = self.InitializeUE_common, args = (device_id,)) + p = Process(target = self.InitializeUE_common, args = (device_id,i,)) p.daemon = True p.start() multi_jobs.append(p) + i += 1 for job in multi_jobs: job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -897,7 +942,12 @@ class SSHConnection(): result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) # We may have to regenerate the .u* files if result is None: - self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) + self.command('ls /tmp/*.sed', '\$', 5) + result = re.search('adapt_usim_parameters', str(self.ssh.before)) + if result is not None: + self.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) + else: + self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) # Launch UE with the modified config file @@ -975,11 +1025,13 @@ class SSHConnection(): result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: self.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr', str(self.ssh.before)) + # ifconfig output is different between ubuntu 16 and ubuntu 18 + result = re.search('inet addr 1|inet 1', str(self.ssh.before)) if result is not None: logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') tunnelInterfaceStatus = True else: + logging.debug(str(self.ssh.before)) logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') tunnelInterfaceStatus = False else: @@ -1234,18 +1286,25 @@ class SSHConnection(): except: os.kill(os.getppid(),signal.SIGUSR1) - def AttachUE_common(self, device_id, statusQueue, lock): + def AttachUE_common(self, device_id, statusQueue, lock, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + if self.ADBCentralized: + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + # airplane mode off // radio on + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) time.sleep(2) max_count = 45 count = max_count while count > 0: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep mDataConnectionState', '\$', 15) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep mDataConnectionState', '\$', 60) result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') @@ -1267,15 +1326,21 @@ class SSHConnection(): count = count - 1 if count == 15 or count == 30: logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + if self.ADBCentralized: + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) time.sleep(0.5) - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + if self.ADBCentralized: + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) time.sleep(0.5) logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') time.sleep(1) @@ -1308,7 +1373,7 @@ class SSHConnection(): for device_id in self.UEDevices: if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): self.UEDevicesStatus[nb_ue_to_connect] = UE_STATUS_ATTACHING - p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,)) + p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,)) p.daemon = True p.start() multi_jobs.append(p) @@ -1349,13 +1414,16 @@ class SSHConnection(): self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() - def DetachUE_common(self, device_id): + def DetachUE_common(self, device_id, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + if self.ADBCentralized: + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') self.close() except: @@ -1376,7 +1444,7 @@ class SSHConnection(): cnt = 0 for device_id in self.UEDevices: self.UEDevicesStatus[cnt] = UE_STATUS_DETACHING - p = Process(target = self.DetachUE_common, args = (device_id,)) + p = Process(target = self.DetachUE_common, args = (device_id,cnt,)) p.daemon = True p.start() multi_jobs.append(p) @@ -1453,11 +1521,14 @@ class SSHConnection(): job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - def DataDisableUE_common(self, device_id): + def DataDisableUE_common(self, device_id, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # enable data service - self.command('stdbuf -o0 adb -s ' + device_id + ' shell svc data disable', '\$', 60) + # disable data service + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60) logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m') self.close() except: @@ -1468,20 +1539,25 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') multi_jobs = [] + i = 0 for device_id in self.UEDevices: - p = Process(target = self.DataDisableUE_common, args = (device_id,)) + p = Process(target = self.DataDisableUE_common, args = (device_id,i,)) p.daemon = True p.start() multi_jobs.append(p) + i += 1 for job in multi_jobs: job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - def DataEnableUE_common(self, device_id): + def DataEnableUE_common(self, device_id, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) # enable data service - self.command('stdbuf -o0 adb -s ' + device_id + ' shell svc data enable', '\$', 60) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m') self.close() except: @@ -1492,11 +1568,13 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') multi_jobs = [] + i = 0 for device_id in self.UEDevices: - p = Process(target = self.DataEnableUE_common, args = (device_id,)) + p = Process(target = self.DataEnableUE_common, args = (device_id,i,)) p.daemon = True p.start() multi_jobs.append(p) + i += 1 for job in multi_jobs: job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -1506,8 +1584,33 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('adb devices', '\$', 15) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",str(self.ssh.before)) + if self.ADBCentralized: + self.command('adb devices', '\$', 15) + self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",str(self.ssh.before)) + self.close() + else: + if (os.path.isfile('./phones_list.txt')): + os.remove('./phones_list.txt') + self.command('ls /etc/*/phones*.txt', '\$', 5) + result = re.search('/etc/ci/phones_list.txt', str(self.ssh.before)) + self.close() + if (result is not None) and (len(self.UEDevices) == 0): + self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.') + if (os.path.isfile('./phones_list.txt')): + phone_list_file = open('./phones_list.txt', 'r') + for line in phone_list_file.readlines(): + line = line.strip() + result = re.search('^#', line) + if result is not None: + continue + comma_split = line.split(",") + self.UEDevices.append(comma_split[0]) + self.UEDevicesRemoteServer.append(comma_split[1]) + self.UEDevicesRemoteUser.append(comma_split[2]) + self.UEDevicesOffCmd.append(comma_split[3]) + self.UEDevicesOnCmd.append(comma_split[4]) + phone_list_file.close() + if terminate_ue_flag == False: if len(self.UEDevices) == 0: logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') @@ -1517,25 +1620,36 @@ class SSHConnection(): while cnt < len(self.UEDevices): self.UEDevicesStatus.append(UE_STATUS_DETACHED) cnt += 1 - self.close() def GetAllCatMDevices(self, terminate_ue_flag): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",str(self.ssh.before)) + if self.ADBCentralized: + self.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) + self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",str(self.ssh.before)) + else: + if (os.path.isfile('./modules_list.txt')): + os.remove('./modules_list.txt') + self.command('ls /etc/*/modules*.txt', '\$', 5) + result = re.search('/etc/ci/modules_list.txt', str(self.ssh.before)) + self.close() + if result is not None: + logging.debug('Found a module list file on ADB server') if terminate_ue_flag == False: if len(self.CatMDevices) == 0: logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') sys.exit(1) self.close() - def CheckUEStatus_common(self, lock, device_id, statusQueue): + def CheckUEStatus_common(self, lock, device_id, statusQueue, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry', '\$', 15) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60) result = re.search('mServiceState=(?P[0-9]+)', str(self.ssh.before)) serviceState = 'Service State: UNKNOWN' if result is not None: @@ -1592,11 +1706,13 @@ class SSHConnection(): multi_jobs = [] lock = Lock() status_queue = SimpleQueue() + i = 0 for device_id in self.UEDevices: - p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,)) + p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,i,)) p.daemon = True p.start() multi_jobs.append(p) + i += 1 for job in multi_jobs: job.join() if self.flexranCtrlInstalled and self.flexranCtrlStarted: @@ -1652,7 +1768,7 @@ class SSHConnection(): sys.exit('Insufficient Parameter') self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) self.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) + result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) if result is not None: UE_IPAddress = result.group('ueipaddress') logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') @@ -1670,7 +1786,10 @@ class SSHConnection(): continue count = 0 while count < 4: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ip addr show | grep rmnet', '\$', 15) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60) result = re.search('inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') @@ -2288,7 +2407,10 @@ class SSHConnection(): self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) # Checking if iperf / iperf3 are installed - self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) + if self.ADBCentralized: + self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) result = re.search('iperf3', str(self.ssh.before)) if result is None: result = re.search('iperf', str(self.ssh.before)) @@ -2673,10 +2795,14 @@ class SSHConnection(): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + result = re.search('oai_hss -j', str(self.ssh.before)) + elif re.match('OAI', self.EPCType, re.IGNORECASE): result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): result = re.search('hss_sim s6as diam_hss', str(self.ssh.before)) + else: + logging.error('This should not happen!') if result is None: logging.debug('\u001B[1;37;41m HSS Process Not Found! \u001B[0m') status_queue.put(HSS_PROCESS_FAILED) @@ -2690,10 +2816,14 @@ class SSHConnection(): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + result = re.search('mme -c', str(self.ssh.before)) + elif re.match('OAI', self.EPCType, re.IGNORECASE): result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): result = re.search('mme', str(self.ssh.before)) + else: + logging.error('This should not happen!') if result is None: logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m') status_queue.put(MME_PROCESS_FAILED) @@ -2706,12 +2836,17 @@ class SSHConnection(): def CheckSPGWProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) + result = re.search('spgwu -c ', str(self.ssh.before)) + elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5) result = re.search('xGw', str(self.ssh.before)) + else: + logging.error('This should not happen!') if result is None: logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m') status_queue.put(SPGW_PROCESS_FAILED) @@ -3153,12 +3288,12 @@ class SSHConnection(): if result is not None: self.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) - time.sleep(5) + time.sleep(10) self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) result = re.search('lte-softmodem', str(self.ssh.before)) if result is not None: self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) - time.sleep(2) + time.sleep(5) self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.close() # If tracer options is on, stopping tshark on EPC side @@ -3218,49 +3353,72 @@ class SSHConnection(): def TerminateHSS(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT oai_hss || true', '\$', 5) + time.sleep(2) + self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) + result = re.search('oai_hss -j', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL oai_hss || true', '\$', 5) + self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-hss.sh', '\$', 5) + elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5) time.sleep(2) self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('cd scripts', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5) time.sleep(1) self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5) + else: + logging.error('This should not happen!') self.close() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateMME(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5) time.sleep(2) self.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) + result = re.search('mme -c', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5) - else: + self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-mme.sh', '\$', 5) + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_mme', '\$', 5) + else: + logging.error('This should not happen!') self.close() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateSPGW(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT spgwc spgwu || true', '\$', 5) + time.sleep(2) + self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) + result = re.search('spgwc -c |spgwu -c ', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL spgwc spgwu || true', '\$', 5) + self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-spgw*.sh', '\$', 5) + elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5) time.sleep(2) self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_xGw', '\$', 5) + else: + logging.error('This should not happen!') self.close() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -3279,18 +3437,30 @@ class SSHConnection(): self.flexranCtrlStarted = False self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - def TerminateUE_common(self, device_id): + def TerminateUE_common(self, device_id, idx): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) # back in airplane mode on (ie radio off) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + if self.ADBCentralized: + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60) result = re.search('shell +(?P\d+)', str(self.ssh.before)) if result is not None: pid_iperf = result.group('pid') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) self.close() except: os.kill(os.getppid(),signal.SIGUSR1) @@ -3299,11 +3469,13 @@ class SSHConnection(): terminate_ue_flag = True self.GetAllUEDevices(terminate_ue_flag) multi_jobs = [] + i = 0 for device_id in self.UEDevices: - p = Process(target= SSH.TerminateUE_common, args = (device_id,)) + p = Process(target= SSH.TerminateUE_common, args = (device_id,i,)) p.daemon = True p.start() multi_jobs.append(p) + i += 1 for job in multi_jobs: job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -3316,12 +3488,12 @@ class SSHConnection(): if result is not None: self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5) self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT lte-uesoftmodem || true', '\$', 5) - time.sleep(5) + time.sleep(10) self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) result = re.search('lte-uesoftmodem', str(self.ssh.before)) if result is not None: self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL lte-uesoftmodem || true', '\$', 5) - time.sleep(2) + time.sleep(5) self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) self.close() result = re.search('ue_', str(self.UELogFile)) @@ -3544,41 +3716,47 @@ class SSHConnection(): def LogCollectHSS(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('rm -f hss.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip hss.log.zip hss*.log', '\$', 60) self.command('rm hss*.log', '\$', 5) - else: + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + self.command('zip hss.log.zip logs/hss*.*', '\$', 60) + self.command('rm logs/hss*.*', '\$', 5) + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/hss_sim0609/hss.log .', '\$', 60) self.command('zip hss.log.zip hss.log', '\$', 60) + else: + logging.error('This option should not occur!') self.close() def LogCollectMME(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('rm -f mme.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip mme.log.zip mme*.log', '\$', 60) self.command('rm mme*.log', '\$', 5) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5) self.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60) + else: + logging.error('This option should not occur!') self.close() def LogCollectSPGW(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('rm -f spgw.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): + if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip spgw.log.zip spgw*.log', '\$', 60) self.command('rm spgw*.log', '\$', 5) - else: + elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) self.command('zip spgw.log.zip xGwLog.0', '\$', 60) + else: + logging.error('This option should not occur!') self.close() def LogCollectOAIUE(self): @@ -3977,9 +4155,9 @@ class SSHConnection(): # Usage() #----------------------------------------------------------- def Usage(): - print('------------------------------------------------------------') + print('----------------------------------------------------------------------------------------------------------------------') print('main.py Ver:' + Version) - print('------------------------------------------------------------') + print('----------------------------------------------------------------------------------------------------------------------') print('Usage: python main.py [options]') print(' --help Show this help.') print(' --mode=[Mode]') @@ -3987,25 +4165,35 @@ def Usage(): print(' InitiateHtml, FinalizeHtml') print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW') print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf') - print(' --eNBRepository=[eNB\'s Repository URL] or --ranRepository=[OAI RAN Repository URL]') - print(' --eNBBranch=[eNB\'s Branch Name] or --ranBranch=[OAI RAN Repository Branch') - print(' --eNBCommitID=[eNB\'s Commit Number] or --ranCommitID=[OAI RAN Repository Commit SHA-1') - print(' --eNB_AllowMerge=[eNB\'s Allow Merge Request (with target branch)] or --ranAllowMerge=true/false') - print(' --eNBTargetBranch=[eNB\'s Target Branch in case of a Merge Request] or --ranTargetBranch=[Target Branch]') + print('---------------------------------------------------------------------------------------------------- Git Options --') + print(' --ranRepository=[OAI RAN Repository URL]') + print(' --ranBranch=[OAI RAN Repository Branch]') + print(' --ranCommitID=[OAI RAN Repository Commit SHA-1]') + print(' --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)]') + print(' --ranTargetBranch=[Target Branch in case of a Merge Request]') + print('--------------------------------------------------------------------------------------------- eNB Server Options --') print(' --eNBIPAddress=[eNB\'s IP Address]') print(' --eNBUserName=[eNB\'s Login User Name]') print(' --eNBPassword=[eNB\'s Login Password]') print(' --eNBSourceCodePath=[eNB\'s Source Code Path]') + print('------------------------------------------------------------------------------------------ OAI UE Server Options --') + print(' --UEIPAddress=[UE\'s IP Address]') + print(' --UEUserName=[UE\'s Login User Name]') + print(' --UEPassword=[UE\'s Login Password]') + print(' --UESourceCodePath=[UE\'s Source Code Path]') + print('--------------------------------------------------------------------------------------------- EPC Server Options --') print(' --EPCIPAddress=[EPC\'s IP Address]') print(' --EPCUserName=[EPC\'s Login User Name]') print(' --EPCPassword=[EPC\'s Login Password]') print(' --EPCSourceCodePath=[EPC\'s Source Code Path]') - print(' --EPCType=[EPC\'s Type: OAI or ltebox]') + print(' --EPCType=[EPC\'s Type: OAI or ltebox or OAI-Rel14-CUPS]') + print('--------------------------------------------------------------------------------------------- ABD Server Options --') print(' --ADBIPAddress=[ADB\'s IP Address]') print(' --ADBUserName=[ADB\'s Login User Name]') print(' --ADBPassword=[ADB\'s Login Password]') + print('----------------------------------------------------------------------------------------------------------------------') print(' --XMLTestFile=[XML Test File to be run]') - print('------------------------------------------------------------') + print('----------------------------------------------------------------------------------------------------------------------') def CheckClassValidity(action,id): if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': @@ -4238,16 +4426,25 @@ while len(argvs) > 1: SSH.EPCSourceCodePath = matchReg.group(1) elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) - if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE): + if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE): SSH.EPCType = matchReg.group(1) else: - sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox)') + sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS)') elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) SSH.ADBIPAddress = matchReg.group(1) elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) SSH.ADBUserName = matchReg.group(1) + elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) + if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): + if re.match('distributed', matchReg.group(1), re.IGNORECASE): + SSH.ADBCentralized = False + else: + SSH.ADBCentralized = True + else: + sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) SSH.ADBPassword = matchReg.group(1) diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml new file mode 100644 index 0000000000..ed41e8b977 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml @@ -0,0 +1,53 @@ + + + build-tab + Build + log-in + + 050101 000001 060101 000001 070101 + + + + + IdleSleep + Sleep + 20 + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_stop.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_stop.xml new file mode 100644 index 0000000000..07fb6951f8 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_stop.xml @@ -0,0 +1,47 @@ + + + epc-closure + EPC-Closure + log-out + + 050201 060201 070201 + + + + + Terminate_HSS + Terminate HSS + + + + Terminate_MME + Terminate MME + + + + Terminate_SPGW + Terminate SPGW + + + diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_terminate.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_terminate.xml new file mode 100644 index 0000000000..962aec4129 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_terminate.xml @@ -0,0 +1,42 @@ + + + terminate-enb-oai-ue + Terminate-all-eNBs-OAI-UEs + tasks + + 030201 090109 + + + + + Terminate_eNB + Terminate eNB + + + + Terminate_OAI_UE + Terminate OAI UE + + + diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000..24cc94a810 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,68 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + 4 + + 030201 090109 + 030102 000001 090102 000002 090109 000001 030201 + + + + + IdleSleep + Sleep for 10 sec + 10 + + + + IdleSleep + Sleep for 30 sec + 30 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT + + + + Terminate_eNB + Terminate eNB + + + + Initialize_OAI_UE + Initialize OAI UE (FDD/Band7/5MHz) + -C 2680000000 -r 25 --ue-rxgain 130 --ue-txgain 1 --ue-max-power -6 --ue-scan-carrier --nokrnmod 1 + + + + Terminate_OAI_UE + Terminate OAI UE + + + diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml new file mode 100644 index 0000000000..dff0761bd3 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml @@ -0,0 +1,118 @@ + + + test-05-tm1-nos1-tunnel + Test-05MHz-TM1-noS1-tunnel + tasks + 2 + + 030201 090109 + 030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201 + + + + + IdleSleep + Sleep + 10 + + + + IdleSleep + Sleep + 5 + + + + IdleSleep + Sleep + 60 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT + + + + Terminate_eNB + Terminate eNB + + + + Initialize_OAI_UE + Initialize OAI UE (FDD/Band7/5MHz) + -C 2680000000 -r 25 --ue-rxgain 130 --ue-txgain 1 --ue-max-power -6 --ue-scan-carrier --nokrnmod 1 --noS1 + + + + Terminate_OAI_UE + Terminate OAI UE + + + + Ping + ping (5MHz - 20 sec)(from eNB to OAI UE) + -I oaitun_enb1 -c 20 10.0.1.2 + 5 + + + + Ping + ping (5MHz - 20 sec)(from OAI UE to eNB) + -I oaitun_ue1 -c 20 10.0.1.1 + 5 + + + + Iperf + iperf (5MHz - DL/1Mbps/UDP)(30 sec) + -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 + 50 + + + + Iperf + iperf (5MHz - DL/10Mbps/UDP)(30 sec) + -c 10.0.1.2 -u -b 10M -t 30 -i 1 -fm -B 10.0.1.1 + 50 + + + + Iperf + iperf (5MHz - UL/1Mbps/UDP)(30 sec) + -c 10.0.1.1 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.2 -R + 50 + balanced + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec) + -c 10.0.1.1 -u -b 2M -t 30 -i 1 -fm -B 10.0.1.2 -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml new file mode 100644 index 0000000000..c1ba7359b3 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml @@ -0,0 +1,58 @@ + + + build-tab-enb0 + Build eNB0 + wrench + + 010101 040101 + + + + + Build_eNB + Build eNB (USRP) + -w USRP -c --eNB + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + + Initialize_UE + Initialize UE + + + diff --git a/ci-scripts/xml_files/inria/ue_band7_build.xml b/ci-scripts/xml_files/inria/ue_band7_build.xml new file mode 100644 index 0000000000..7d7ae6e0df --- /dev/null +++ b/ci-scripts/xml_files/inria/ue_band7_build.xml @@ -0,0 +1,38 @@ + + + build-tab-ue0 + Build UE0 + wrench + +090101 + + + + + Build_OAI_UE + Build OAI UE + -w USRP --UE + + + From ddc336e2d8ba2d38f0f665cc5328a8bb5305515e Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 14:17:58 +0200 Subject: [PATCH 039/134] asn1_msg.do_DrxConfig --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 61 ++++++++++++++-------------- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 3 +- openair2/RRC/LTE/rrc_eNB.c | 4 +- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9303fb79f1..375281057f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -625,10 +625,9 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, /* * Generate the configuration structure for CDRX feature */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, - int CC_id, - RrcConfigurationReq *configuration, - LTE_UE_EUTRA_Capability_t *UEcap) +LTE_DRX_Config_t *do_DrxConfig(int CC_id, + RrcConfigurationReq *configuration, + LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { LTE_DRX_Config_t *drxConfig = NULL; @@ -666,58 +665,60 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, if (drxConfig->present == LTE_DRX_Config_PR_release) { drxConfig->choice.release = (NULL_t) 0; } else { - drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - drxConfig->choice.setup.drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; - drxConfig->choice.setup.drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; - drxConfig->choice.setup.longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; - switch (drxConfig->choice.setup.longDRX_CycleStartOffset.present) { + struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; + choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + // drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; + choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; + choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: - drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + choiceSetup->longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; break; default: break; @@ -725,12 +726,12 @@ LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, /* Short DRX cycle configuration */ if (!ueSupportCdrxShortFlag || configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer == 0) { - drxConfig->choice.setup.shortDRX = NULL; + choiceSetup->shortDRX = NULL; } else { - drxConfig->choice.setup.shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); - memset(drxConfig->choice.setup.shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); - drxConfig->choice.setup.shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; - drxConfig->choice.setup.shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; + choiceSetup->shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); + memset(choiceSetup->shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); + choiceSetup->shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; + choiceSetup->shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 7ddf939e6d..29e2e8e389 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -81,12 +81,11 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFNSubframes, uint32_t frame); /** \brief Generate configuration structure for DRX_Config -@param Mod_id Instance of eNB @param CC_id Id of component to configure @param configuration Pointer Configuration Request structure @param UEcap Pointer Configuration UE capablities @return DRX_Config structure pointer or NULL => error */ -LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); +LTE_DRX_Config_t *do_DrxConfig(int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); /** \brief Generate configuration for SIB1 (eNB). diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d93510ac5d..73a6ea1381 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3219,7 +3219,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } @@ -3951,7 +3951,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } From 020f0ef9e93a20f922083a6e1df1888adce616b6 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 15:42:45 +0200 Subject: [PATCH 040/134] cdrx_configured update --- openair2/LAYER2/MAC/config.c | 61 ++++++++++++++-------------- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 1 - openair2/RRC/LTE/rrc_eNB.c | 4 +- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ec2497d6ad..621dafe603 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1002,7 +1002,7 @@ void eNB_Config_Local_DRX( UE_list_t *UE_list_mac = NULL; int UE_id = -1; UE_sched_ctrl_t *UE_scheduling_control = NULL; - + UE_list_mac = &(RC.mac[Mod_id]->UE_list); UE_id = find_UE_id(Mod_id, rnti); @@ -1018,31 +1018,30 @@ void eNB_Config_Local_DRX( /* Get struct to modify */ UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]); + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n"); - - UE_scheduling_control->cdrx_configured = FALSE; return; } - /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when ACK is received - UE_scheduling_control->cdrx_waiting_ack = TRUE; // set to true first, waiting for the UE to configure CDRX on its side + /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ + LOG_I(MAC, "Initial cdrx_waiting_ack state: %s\n", UE_scheduling_control->cdrx_waiting_ack ? "TRUE" : "FALSE"); + UE_scheduling_control->cdrx_configured = TRUE; // will be set to true + UE_scheduling_control->cdrx_waiting_ack = TRUE; // For debugging only UE_scheduling_control->in_active_time = FALSE; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; - switch (drx_Configuration->choice.setup.onDurationTimer) { + struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; + switch (choiceSetup->onDurationTimer) { case 0: UE_scheduling_control->on_duration_timer_thres = 1; break; @@ -1097,7 +1096,7 @@ void eNB_Config_Local_DRX( } UE_scheduling_control->drx_inactivity_timer = 0; - switch (drx_Configuration->choice.setup.drx_InactivityTimer) { + switch (choiceSetup->drx_InactivityTimer) { case 0: UE_scheduling_control->drx_inactivity_timer_thres = 1; break; @@ -1172,7 +1171,7 @@ void eNB_Config_Local_DRX( break; } - if (drx_Configuration->choice.setup.shortDRX == NULL) { + if (choiceSetup->shortDRX == NULL) { UE_scheduling_control->in_short_drx_cycle = FALSE; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; @@ -1180,8 +1179,8 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { UE_scheduling_control->in_short_drx_cycle = FALSE; - UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) drx_Configuration->choice.setup.shortDRX->drxShortCycleTimer; - switch (drx_Configuration->choice.setup.shortDRX->shortDRX_Cycle) { + UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; + switch (choiceSetup->shortDRX->shortDRX_Cycle) { case 0: UE_scheduling_control->short_drx_cycle_duration = 2; break; @@ -1241,70 +1240,70 @@ void eNB_Config_Local_DRX( UE_scheduling_control->in_long_drx_cycle = FALSE; UE_scheduling_control->drx_longCycle_timer = 0; - switch (drx_Configuration->choice.setup.longDRX_CycleStartOffset.present) { + switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: UE_scheduling_control->drx_longCycle_timer_thres = 10; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf10; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf10; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: UE_scheduling_control->drx_longCycle_timer_thres = 20; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf20; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf20; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: UE_scheduling_control->drx_longCycle_timer_thres = 32; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf32; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf32; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: UE_scheduling_control->drx_longCycle_timer_thres = 40; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf40; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf40; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: UE_scheduling_control->drx_longCycle_timer_thres = 64; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf64; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf64; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: UE_scheduling_control->drx_longCycle_timer_thres = 80; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf80; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf80; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: UE_scheduling_control->drx_longCycle_timer_thres = 128; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf128; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf128; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: UE_scheduling_control->drx_longCycle_timer_thres = 160; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf160; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf160; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: UE_scheduling_control->drx_longCycle_timer_thres = 256; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf256; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf256; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: UE_scheduling_control->drx_longCycle_timer_thres = 320; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf320; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf320; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: UE_scheduling_control->drx_longCycle_timer_thres = 512; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf512; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf512; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: UE_scheduling_control->drx_longCycle_timer_thres = 640; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf640; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf640; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: UE_scheduling_control->drx_longCycle_timer_thres = 1024; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1024; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1024; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: UE_scheduling_control->drx_longCycle_timer_thres = 1280; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1280; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1280; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: UE_scheduling_control->drx_longCycle_timer_thres = 2048; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2048; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2048; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: UE_scheduling_control->drx_longCycle_timer_thres = 2560; - UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2560; + UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560; break; default: LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n"); @@ -1312,7 +1311,7 @@ void eNB_Config_Local_DRX( } memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer)); - switch (drx_Configuration->choice.setup.drx_RetransmissionTimer) { + switch (choiceSetup->drx_RetransmissionTimer) { case 0: memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 375281057f..f38720f56c 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -667,7 +667,6 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } else { struct LTE_DRX_Config__setup *choiceSetup = &drxConfig->choice.setup; choiceSetup->onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; - // drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; choiceSetup->drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; choiceSetup->drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; choiceSetup->longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 73a6ea1381..068f24d5ab 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6503,8 +6503,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; - LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + // UE_scheduling_control->cdrx_configured = TRUE; + LOG_I(RRC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); } } // No CDRX with the CU/DU split in this version of the code From 1740153fae89fe28438aad3964566cae7a8716aa Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Thu, 5 Sep 2019 15:27:26 +0200 Subject: [PATCH 041/134] Status RRC-RECONFIGURED update --- openair2/RRC/LTE/L2_interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 219c905c42..522f42d5fd 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -312,10 +312,8 @@ mac_rrc_data_ind( if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) { LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status); return (-1); - } else { - rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - } + } + rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); } } From e0b3e4fb892d5dbbc13e9058fc03b7a12488b65b Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 10 Sep 2019 15:46:25 +0200 Subject: [PATCH 042/134] rrc_eNB update 10/09 --- openair2/RRC/LTE/rrc_eNB.c | 84 +++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 068f24d5ab..41c5cb9212 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3201,45 +3201,47 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB + mac_MainConfig->drx_Config = NULL; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); if (UE_id != -1) { + eNB_MAC_INST *mac = RC.mac[module_id]; + UE_list_t *UE_list = &(mac->UE_list); + if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); - - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + // CDRX can be only configured in case of FDD and non BR UE (09/04/19) + + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + /* Process the IE drx_Config */ + if (cc_id < MAX_NUM_CCs) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } + } else { + LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); + } } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - mac_MainConfig->drx_Config = NULL; + LOG_D(RRC, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); - mac_MainConfig->drx_Config = NULL; } } else { // No CDRX with the CU/DU split in this version LOG_E(RRC, "CU/DU split activated\n"); - mac_MainConfig->drx_Config = NULL; } + if (mac_MainConfig->drx_Config != NULL) { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -6691,16 +6693,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif - ); - } + ); + } } else { // remove LCHAN from MAC/PHY if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB @@ -6709,11 +6711,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_req(ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - DRB2LCHAN[i], - Rlc_info_um); + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + DRB2LCHAN[i], + Rlc_info_um); } } @@ -6765,13 +6767,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - 0, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, - (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); } From 108aa728783be6987cc4e06410b7d1678ae67e41 Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 17 Sep 2019 16:15:58 +0200 Subject: [PATCH 043/134] message-transfer-update --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 47 ++++++++++++++++++-- openair2/RRC/LTE/rrc_eNB.c | 9 ++-- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 19e06c8600..046d0011fc 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -47,6 +47,7 @@ #include "common/ran_context.h" #include "rrc_eNB_UE_context.h" +#include "asn1_msg.h" // undefine C_RNTI from // openair1/PHY/LTE_TRANSPORT/transport_common.h which @@ -401,8 +402,38 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, for (i = 0; i< 8; i++){ DRB2LCHAN[i] = 0; } - if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + int UE_id = find_UE_id(ctxt.module_id, ctxt.rnti); + if (UE_id != -1) { + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt.module_id]; + uint8_t cc_id = ue_context_p->ue_context.primaryCC_id; + eNB_MAC_INST *mac = RC.mac[ctxt.module_id]; + UE_list_t *UE_list = &(mac->UE_list); + + if (rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL && + UE_list->UE_template[cc_id][UE_id].rach_resource_type == 0) { + if (cc_id < MAX_NUM_CCs) { + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_p->ue_context.UE_Capability; + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, + &rrc_inst->configuration, + UEcap); + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); + LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } + } else { + LOG_E(F1AP, "Invalid CC_id for DRX configuration\n"); + } + } + } else { // UE_id invalid + LOG_E(F1AP, "Invalid UE_id found!\n"); + } + } + LTE_MeasGapConfig_t *measGapConfig = NULL; struct LTE_PhysicalConfigDedicated* physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated; rrc_rlc_config_asn1_req( @@ -602,7 +633,9 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } -int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) { +int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + const f1ap_ul_rrc_message_t *msg) +{ const rnti_t rnti = msg->rnti; F1AP_F1AP_PDU_t pdu; @@ -703,6 +736,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -715,9 +749,16 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_messa }else { LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti); ue_context_p->ue_context.Status = RRC_CONNECTED; - } + + int UE_id_mac = find_UE_id(instance, rnti); + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + } + } break; + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: LOG_I(F1AP, "[MSG] RRC securityModeComplete \n"); break; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 41c5cb9212..eaceddfc2a 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3202,11 +3202,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB mac_MainConfig->drx_Config = NULL; + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE - rnti_t rnti = ue_context_pP->ue_id_rnti; - module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); if (UE_id != -1) { @@ -6490,7 +6490,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; LTE_DRB_Identity_t *drb_id_p = NULL; - + ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer @@ -6498,7 +6498,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( /* CDRX: activated if ack was expected */ int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); if (UE_id_mac == -1){ - LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n",PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ue_context_pP->ue_context.rnti); + LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti); return; } UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); From 2ca45bb3d79c430e974ed1ad0dcf7dda7654c2f5 Mon Sep 17 00:00:00 2001 From: DUFRENE Louis Adrien TGI/OLS Date: Mon, 23 Sep 2019 11:43:38 +0200 Subject: [PATCH 044/134] [unbuilt] RRC Reconnection Complete for CU/DU done. Not done for monolithique --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 31 ++++++++++++++------ openair2/RRC/LTE/rrc_eNB.c | 17 ----------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 046d0011fc..9d332b168c 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -736,7 +736,25 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + LOG_I(F1AP, "[MSG] RRC UL rrcConnectionReconfigurationComplete\n"); + int UE_id_mac = find_UE_id(instance, rnti); + + if (UE_id_mac == -1) { + LOG_E(MAC, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); + break; + } + + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); + + if (UE_scheduling_control == NULL) { + LOG_E(MAC, "Can't get UE scheduling control structure of UE rnti %x\n", rnti); + break; + } else if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + // UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is sent (under test) + LOG_I(MAC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); + } break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -744,18 +762,13 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: LOG_I(F1AP, "[MSG] RRC UL rrcConnectionSetupComplete \n"); - if(!ue_context_p){ + + if(!ue_context_p){ LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti); - }else { + + } else { LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti); ue_context_p->ue_context.Status = RRC_CONNECTED; - - int UE_id_mac = find_UE_id(instance, rnti); - UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - } - } break; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index eaceddfc2a..89d3960e89 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6494,23 +6494,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX: activated if ack was expected */ - int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); - if (UE_id_mac == -1){ - LOG_E(RRC,PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_RRCConnectionReconfigurationComplete without UE_id(MAC) rnti %x, let's return\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti); - return; - } - UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); - - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - // UE_scheduling_control->cdrx_configured = TRUE; - LOG_I(RRC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); - } - } // No CDRX with the CU/DU split in this version of the code - T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), From 8e17a35cef037da489190eb4c869cab1bdc3d189 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 24 Sep 2019 16:13:07 +0200 Subject: [PATCH 045/134] CI: fixing minor bugs Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-inria-r2lab | 2 +- ci-scripts/main.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab index 6fe2e3bb2a..790b10a0e2 100644 --- a/ci-scripts/Jenkinsfile-inria-r2lab +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -175,7 +175,7 @@ pipeline { echo "Latest commit to use is ${GIT_COMMIT_TO_RUN}" // Putting the adaptation parameters for the OAI UE - sh "ssh -t inria_oaici@faraday.inria.fr 'scp /home/inria_oaici/for-ci/adapt_usim_parameters_${r2labUE0}.sed ${fituser}@${r2labUE0}:/tmp'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp /home/inria_oaici/for-ci/adapt_usim_parameters_${r2labUE0}.sed ${fituser}@${r2labUE0}:/tmp/adapt_usim_parameters.sed'" // Out of rload, the sub-network-interfaces are not up sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:m11 172.16.1.102 up\"'" diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 34628fc4f9..23999bc567 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3720,10 +3720,10 @@ class SSHConnection(): self.command('rm -f hss.log.zip', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip hss.log.zip hss*.log', '\$', 60) - self.command('rm hss*.log', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm hss*.log', '\$', 5) if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip hss.log.zip logs/hss*.*', '\$', 60) - self.command('rm logs/hss*.*', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm logs/hss*.*', '\$', 5) elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/hss_sim0609/hss.log .', '\$', 60) self.command('zip hss.log.zip hss.log', '\$', 60) @@ -3737,7 +3737,7 @@ class SSHConnection(): self.command('rm -f mme.log.zip', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip mme.log.zip mme*.log', '\$', 60) - self.command('rm mme*.log', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm mme*.log', '\$', 5) elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5) self.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60) @@ -3751,7 +3751,7 @@ class SSHConnection(): self.command('rm -f spgw.log.zip', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): self.command('zip spgw.log.zip spgw*.log', '\$', 60) - self.command('rm spgw*.log', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm spgw*.log', '\$', 5) elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) self.command('zip spgw.log.zip xGwLog.0', '\$', 60) From c71e7639197622e662f2a08db2f4d5c5f8a5326e Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 25 Sep 2019 15:56:54 +0200 Subject: [PATCH 046/134] CI: improvements on R2LAB deployment - Add more IP routes / rules - OAI UE should be pingable! - Relative time column added to HTML report Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-inria-r2lab | 11 +++++++++ ci-scripts/main.py | 23 +++++++++++++++---- .../enb_ue_usrp210_band7_test_05mhz_tm1.xml | 13 ++++++++--- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab index 790b10a0e2..7a51666ffe 100644 --- a/ci-scripts/Jenkinsfile-inria-r2lab +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -187,6 +187,17 @@ pipeline { sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:p5c 172.58.58.101 up\"'" sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:s11 172.16.1.104 up\"'" sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"ifconfig\"'" + + // Adding routes on the EPC + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ip route add default via 192.168.3.100 dev control table lte\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ip rule add from 12.0.0.0/8 table lte\"'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ip rule add from 12.1.1.0/8 table lte\"'" + + // Adding a route on the eNB for the S1U interface + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labENB0} \"echo ${fitpasswd} | sudo -S ip route add 192.168.248.0/24 via ${r2labEPC0IpAddr} dev control\"'" + + // For the moment, simple way to route traffic from python executor to any UEs + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labPythonExe} \"echo ${fitpasswd} | sudo -S ip route add 12.1.1.0/24 via ${r2labEPC0IpAddr} dev control\"'" } } } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 23999bc567..d167907c5f 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -182,6 +182,7 @@ class SSHConnection(): self.flexranCtrlInstalled = False self.flexranCtrlStarted = False self.expectedNbOfConnectedUEs = 0 + self.startTime = 0 def open(self, ipaddress, username, password): count = 0 @@ -1026,7 +1027,7 @@ class SSHConnection(): if result is None: self.command('ifconfig oaitun_ue1', '\$', 4) # ifconfig output is different between ubuntu 16 and ubuntu 18 - result = re.search('inet addr 1|inet 1', str(self.ssh.before)) + result = re.search('inet addr:1|inet 1', str(self.ssh.before)) if result is not None: logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') tunnelInterfaceStatus = True @@ -1041,6 +1042,11 @@ class SSHConnection(): if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') + if (self.ADBIPAddress != 'none'): + self.UEDevices = [] + self.UEDevices.append('OAI-UE') + self.UEDevicesStatus = [] + self.UEDevicesStatus.append(UE_STATUS_DETACHED) else: self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') @@ -1768,9 +1774,12 @@ class SSHConnection(): sys.exit('Insufficient Parameter') self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) self.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) + result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) if result is not None: - UE_IPAddress = result.group('ueipaddress') + if result.group('ueipaddress') is not None: + UE_IPAddress = result.group('ueipaddress') + else: + UE_IPAddress = result.group('ueipaddress2') logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') self.UEIPAddresses.append(UE_IPAddress) else: @@ -3951,6 +3960,7 @@ class SSHConnection(): self.htmlFile.write('
\n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -3974,7 +3984,7 @@ class SSHConnection(): def CreateHtmlTabFooter(self, passStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') if passStatus: self.htmlFile.write(' \n') else: @@ -4047,7 +4057,9 @@ class SSHConnection(): def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): + currentTime = int(round(time.time() * 1000)) - self.startTime self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -4115,8 +4127,10 @@ class SSHConnection(): def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): + currentTime = int(round(time.time() * 1000)) - self.startTime addOrangeBK = False self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -4644,6 +4658,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re cnt = 0 SSH.prematureExit = True + SSH.startTime = int(round(time.time() * 1000)) while cnt < SSH.repeatCounts[0] and SSH.prematureExit: SSH.prematureExit = False for test_case_id in todo_tests: diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml index 24cc94a810..fadfa8efec 100644 --- a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -27,7 +27,7 @@ 4 030201 090109 - 030102 000001 090102 000002 090109 000001 030201 + 030102 000001 090102 000002 040503 000002 090109 000001 030201 @@ -39,8 +39,8 @@ IdleSleep - Sleep for 30 sec - 30 + Sleep for 3 sec + 3 @@ -65,4 +65,11 @@ Terminate OAI UE + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + From 6a9c5884f3c840b146992d8fa3f9c294fa590621 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 26 Sep 2019 15:50:04 +0200 Subject: [PATCH 047/134] CI: adding support for iperf (UDP) with CUPS CN Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 91 ++++++++++++++----- .../enb_ue_usrp210_band7_test_05mhz_tm1.xml | 30 +++++- 2 files changed, 97 insertions(+), 24 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d167907c5f..229f4233c6 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -614,7 +614,7 @@ class SSHConnection(): logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log logs/hss*.*', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log logs/hss*.* ping*.log iperf*.log', '\$', 5) self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) self.command('chmod 755 ./my-hss.sh', '\$', 5) self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss.log ./my-hss.sh', '\$', 5) @@ -2342,17 +2342,33 @@ class SSHConnection(): ipnumbers[3] = '1' EPC_Iperf_UE_IPAddress = ipnumbers[0] + '.' + ipnumbers[1] + '.' + ipnumbers[2] + '.' + ipnumbers[3] - # Launch iperf server on EPC side - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 + # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address + launchFromEpc = True + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + launchFromEpc = False + cmd = 'hostname -I' + ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') + if ret.stdout is not None: + EPC_Iperf_UE_IPAddress = ret.stdout.strip() port = 5001 + idx - if udpIperf: - self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + if launchFromEpc: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + if udpIperf: + self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + else: + self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + self.close() else: - self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + if udpIperf: + cmd = 'nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' + else: + cmd = 'nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' + logging.debug(cmd + '\n') + subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') time.sleep(0.5) - self.close() # Launch iperf client on UE if (device_id == 'OAI-UE'): @@ -2388,15 +2404,23 @@ class SSHConnection(): self.close() # Kill iperf server on EPC side - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5) - self.close() + if launchFromEpc: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5) + self.close() + else: + cmd = 'killall --signal SIGKILL iperf' + logging.debug(cmd + '\n') + subprocess.run(cmd, shell=True) + time.sleep(1) + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') # in case of failure, retrieve server log if (clientStatus == -1): - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + if launchFromEpc: + time.sleep(1) + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) # in case of OAI-UE if (device_id == 'OAI-UE'): @@ -2466,9 +2490,14 @@ class SSHConnection(): time.sleep(0.5) self.close() - # Launch the IPERF client on the EPC side for DL - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + # Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn + # But for OAI-Rel14-CUPS, we launch from python executor + launchFromEpc = True + if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): + launchFromEpc = False + if launchFromEpc: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) @@ -2478,16 +2507,31 @@ class SSHConnection(): modified_options = str(self.iperf_args) time.sleep(0.5) - self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + if launchFromEpc: + self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + else: + if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log') if (useIperf3): self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) clientStatus = 0 self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) else: - iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if launchFromEpc: + iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + cmd = 'iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log' + message = cmd + '\n' + logging.debug(cmd) + ret = subprocess.run(cmd, shell=True) + iperf_status = ret.returncode + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('cat ' + self.EPCSourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) if iperf_status < 0: - self.close() + if launchFromEpc: + self.close() message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) @@ -2521,7 +2565,8 @@ class SSHConnection(): # in case of OAI UE: if (device_id == 'OAI-UE'): if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - pass + if not launchFromEpc: + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') else: self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml index fadfa8efec..c429e17b2c 100644 --- a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -27,7 +27,7 @@ 4 030201 090109 - 030102 000001 090102 000002 040503 000002 090109 000001 030201 + 030102 000001 090102 000002 040503 000002 040603 040604 040643 040644 000002 090109 000001 030201 @@ -72,4 +72,32 @@ 5 + + Iperf + iperf (5MHz - DL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (5MHz - DL/12Mbps/UDP)(30 sec) + -u -b 12M -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (5MHz - UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm -R + 50 + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec) + -u -b 2M -t 30 -i 1 -fm -R + 50 + + From 7090357e534937ee8f21bb3ac11d34278b57eb41 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 27 Sep 2019 16:01:08 +0200 Subject: [PATCH 048/134] CI: Adding scenarios for COTS-UE Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-inria-r2lab | 2 + ci-scripts/main.py | 18 ++-- .../inria/enb_ue_usrp210_band7_epc_start.xml | 4 +- .../enb_ue_usrp210_band7_test_05mhz_tm1.xml | 4 +- .../inria/enb_usrp210_band7_epc_start.xml | 53 +++++++++ .../inria/enb_usrp210_band7_epc_stop.xml | 47 ++++++++ .../enb_usrp210_band7_test_05mhz_tm1.xml | 102 ++++++++++++++++++ ...7_build.xml => ue_usrp210_band7_build.xml} | 0 8 files changed, 217 insertions(+), 13 deletions(-) create mode 100644 ci-scripts/xml_files/inria/enb_usrp210_band7_epc_start.xml create mode 100644 ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml create mode 100644 ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml rename ci-scripts/xml_files/inria/{ue_band7_build.xml => ue_usrp210_band7_build.xml} (100%) diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab index 7a51666ffe..6ae7522999 100644 --- a/ci-scripts/Jenkinsfile-inria-r2lab +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -176,6 +176,8 @@ pipeline { // Putting the adaptation parameters for the OAI UE sh "ssh -t inria_oaici@faraday.inria.fr 'scp /home/inria_oaici/for-ci/adapt_usim_parameters_${r2labUE0}.sed ${fituser}@${r2labUE0}:/tmp/adapt_usim_parameters.sed'" + sh "ssh -t inria_oaici@faraday.inria.fr 'scp /home/inria_oaici/for-ci/phones_list.txt ${fituser}@${r2labEPC0}:/tmp'" + sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S cp /tmp/phones_list.txt /etc/ci\"'" // Out of rload, the sub-network-interfaces are not up sh "ssh -t inria_oaici@faraday.inria.fr 'ssh -t -b 192.168.3.100 ${fituser}@${r2labEPC0} \"echo ${fitpasswd} | sudo -S ifconfig control:m11 172.16.1.102 up\"'" diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 229f4233c6..2919ee5ee1 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -614,10 +614,10 @@ class SSHConnection(): logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log logs/hss*.* ping*.log iperf*.log', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5) self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) self.command('chmod 755 ./my-hss.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss.log ./my-hss.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss_' + self.testCase_id + '.log ./my-hss.sh', '\$', 5) elif re.match('OAI', self.EPCType, re.IGNORECASE): logging.debug('Using the OAI EPC HSS') self.command('cd ' + self.EPCSourceCodePath, '\$', 5) @@ -644,10 +644,10 @@ class SSHConnection(): if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): logging.debug('Using the OAI EPC Release 14 MME') self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f mme.log', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f mme_' + self.testCase_id + '.log', '\$', 5) self.command('echo "./run_mme --config-file /usr/local/etc/oai/mme.conf --set-virt-if" > ./my-mme.sh', '\$', 5) self.command('chmod 755 ./my-mme.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/mme.log ./my-mme.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/mme_' + self.testCase_id + '.log ./my-mme.sh', '\$', 5) elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) @@ -675,14 +675,14 @@ class SSHConnection(): if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): logging.debug('Using the OAI EPC Release 14 SPGW-CUPS') self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f spgwc.log spgwu.log', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f spgwc_' + self.testCase_id + '.log spgwu_' + self.testCase_id + '.log', '\$', 5) self.command('echo "spgwc -c /usr/local/etc/oai/spgw_c.conf" > ./my-spgwc.sh', '\$', 5) self.command('chmod 755 ./my-spgwc.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwc.log ./my-spgwc.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwc_' + self.testCase_id + '.log ./my-spgwc.sh', '\$', 5) time.sleep(5) self.command('echo "spgwu -c /usr/local/etc/oai/spgw_u.conf" > ./my-spgwu.sh', '\$', 5) self.command('chmod 755 ./my-spgwu.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwu.log ./my-spgwu.sh', '\$', 5) + self.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwu_' + self.testCase_id + '.log ./my-spgwu.sh', '\$', 5) elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) @@ -1308,9 +1308,9 @@ class SSHConnection(): count = max_count while count > 0: if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep mDataConnectionState', '\$', 15) + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep mDataConnectionState', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml index ed41e8b977..51aaba439e 100644 --- a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_epc_start.xml @@ -21,8 +21,8 @@ --> - build-tab - Build + epc-start-oai-ue + EPC-Start-OAI-UE log-in 050101 000001 060101 000001 070101 diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml index c429e17b2c..1471b9a016 100644 --- a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -21,8 +21,8 @@ --> - test-05-tm1 - Test-05MHz-TM1 + test-05-tm1-oai-ue + Test-05MHz-TM1-OAI-UE tasks 4 diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_start.xml new file mode 100644 index 0000000000..5fc3a2e960 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_start.xml @@ -0,0 +1,53 @@ + + + epc-start + EPC-Start + log-in + + 050102 000001 060102 000001 070102 + + + + + IdleSleep + Sleep + 20 + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml new file mode 100644 index 0000000000..aa1884baf9 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml @@ -0,0 +1,47 @@ + + + epc-stop + EPC-Stop + log-out + + 050201 060201 070201 + + + + + Terminate_HSS + Terminate HSS + + + + Terminate_MME + Terminate MME + + + + Terminate_SPGW + Terminate SPGW + + + diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000..7e8e765b97 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,102 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + 4 + + 030201 + 030102 000002 040301 000002 040504 000001 040401 000002 030201 + + + + + IdleSleep + Sleep for 10 sec + 10 + + + + IdleSleep + Sleep for 3 sec + 3 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT + + + + Terminate_eNB + Terminate eNB + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (5MHz - DL/12Mbps/UDP)(30 sec) + -u -b 12M -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (5MHz - UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm -R + 50 + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec) + -u -b 2M -t 30 -i 1 -fm -R + 50 + + + diff --git a/ci-scripts/xml_files/inria/ue_band7_build.xml b/ci-scripts/xml_files/inria/ue_usrp210_band7_build.xml similarity index 100% rename from ci-scripts/xml_files/inria/ue_band7_build.xml rename to ci-scripts/xml_files/inria/ue_usrp210_band7_build.xml From 77115590cd80cbda700bae5833a51164688e23a3 Mon Sep 17 00:00:00 2001 From: DUFRENE Louis Adrien TGI/OLS Date: Fri, 27 Sep 2019 16:06:25 +0200 Subject: [PATCH 049/134] [not built] CDRX CU/DU split ok, in case of mono still MAC code in RRC --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 38 +++++++++++++------- openair2/F1AP/f1ap_du_task.c | 2 +- openair2/RRC/LTE/rrc_eNB.c | 38 ++++++++++++++------ 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 9d332b168c..ea22ce7672 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -399,25 +399,34 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, LTE_SRB_ToAddModList_t *SRB_configList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->srb_ToAddModList; LTE_DRB_ToReleaseList_t *DRB_ReleaseList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToReleaseList; LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + for (i = 0; i< 8; i++){ DRB2LCHAN[i] = 0; } + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + + /* CDRX Configuration */ + // Need to check if UE is a BR UE int UE_id = find_UE_id(ctxt.module_id, ctxt.rnti); + if (UE_id != -1) { eNB_RRC_INST *rrc_inst = RC.rrc[ctxt.module_id]; uint8_t cc_id = ue_context_p->ue_context.primaryCC_id; eNB_MAC_INST *mac = RC.mac[ctxt.module_id]; UE_list_t *UE_list = &(mac->UE_list); - if (rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL && - UE_list->UE_template[cc_id][UE_id].rach_resource_type == 0) { + if (rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL && UE_list->UE_template[cc_id][UE_id].rach_resource_type == 0) { + // CDRX can be only configured in case of FDD and non BR UE (27/09/19) + + LOG_D(F1AP, "Processing the DRX configuration in DU RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { LTE_UE_EUTRA_Capability_t *UEcap = ue_context_p->ue_context.UE_Capability; - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, - &rrc_inst->configuration, - UEcap); + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { LOG_E(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); } else { @@ -426,12 +435,15 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); } } else { - LOG_E(F1AP, "Invalid CC_id for DRX configuration\n"); + LOG_E(F1AP, "Invalid CC_id for DRX configuration\n"); } + } else { // CDRX not implemented for TDD and LTE-M (09/04/19) + LOG_I(F1AP, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(F1AP, "Invalid UE_id found!\n"); } + /* End of CDRX configuration */ } LTE_MeasGapConfig_t *measGapConfig = NULL; @@ -737,24 +749,24 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: LOG_I(F1AP, "[MSG] RRC UL rrcConnectionReconfigurationComplete\n"); - + + /* CDRX: (under test) activated when RRC Connection Reconfiguration was sent */ int UE_id_mac = find_UE_id(instance, rnti); if (UE_id_mac == -1) { - LOG_E(MAC, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); + LOG_E(F1AP, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); break; } UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]); - if (UE_scheduling_control == NULL) { - LOG_E(MAC, "Can't get UE scheduling control structure of UE rnti %x\n", rnti); - break; - } else if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; // UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is sent (under test) - LOG_I(MAC, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); + LOG_I(F1AP, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); } + /* End of CDRX processing */ + break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index d287e1e5bf..566391ac7a 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) { &received_msg->ittiMsg.sctp_data_ind); break; - case F1AP_UL_RRC_MESSAGE: // from rrc + case F1AP_UL_RRC_MESSAGE: // to rrc LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), &F1AP_UL_RRC_MESSAGE(received_msg)); diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 89d3960e89..f7c4b1f06b 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3204,7 +3204,8 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->drx_Config = NULL; rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE int UE_id = find_UE_id(module_id, rnti); @@ -3222,26 +3223,25 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t /* Process the IE drx_Config */ if (cc_id < MAX_NUM_CCs) { mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { - LOG_E(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); } } else { LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - LOG_D(RRC, "CDRX not implemented for TDD and LTE-M\n"); + LOG_I(RRC, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); } - } else { // No CDRX with the CU/DU split in this version - LOG_E(RRC, "CU/DU split activated\n"); } - if (mac_MainConfig->drx_Config != NULL) { - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - } + /* End of CDRX configuration */ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -6494,6 +6494,24 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + /* CDRX: (under test) activated when RRC Connection Reconfiguration was sent */ + int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + if (UE_id_mac == -1) { + LOG_E(rrc, "Can't find UE_id(MAC) of UE rnti %x\n", ue_context_pP->ue_context.rnti); + return; + } + + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); + + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + // UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is sent (under test) + LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + } + /* End of CDRX processing */ + } + T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), From 03526f90a8122747ee665878b85d8ba0b2ffc3c0 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 3 Oct 2019 11:50:10 +0200 Subject: [PATCH 050/134] CI: adding tshark capturing on EPC side Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 32 +++++++++++++++++-- .../inria/enb_usrp210_band7_build.xml | 22 +------------ .../inria/enb_usrp210_band7_epc_stop.xml | 6 ++++ .../enb_usrp210_band7_test_05mhz_tm1.xml | 18 +++++++---- 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 2919ee5ee1..2cc828a255 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -145,6 +145,7 @@ class SSHConnection(): self.UEDevicesRemoteUser = [] self.UEDevicesOffCmd = [] self.UEDevicesOnCmd = [] + self.UEDevicesRebootCmd = [] self.CatMDevices = [] self.UEIPAddresses = [] self.htmlFile = '' @@ -613,6 +614,14 @@ class SSHConnection(): if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + self.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep --colour=never "s11"', '\$', 5) + result = re.search('interfaceToUse=(?P[a-zA-Z0-9\-\_\:]+)done', str(self.ssh.before)) + if result is not None: + eth_interface = result.group('eth_interface') + logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' and lo \u001B[0m') + EPC_PcapFileName = 'epc_' + self.testCase_id + '.pcap' + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f ' + EPC_PcapFileName, '\$', 5) + self.command('echo $USER; nohup sudo tshark -i ' + eth_interface + ' -i lo -w ' + self.EPCSourceCodePath + '/scripts/' + EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5) self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) @@ -873,8 +882,21 @@ class SSHConnection(): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if not self.ADBCentralized: + # Reboot UE + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) + # Wait + time.sleep(60) + # Put in LTE-Mode only + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60) + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60) # enable data service self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) + # we need to do radio on/off cycle to make sure of above changes + # airplane mode off // radio on + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) + time.sleep(10) # airplane mode on // radio off self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) self.close() @@ -1615,6 +1637,7 @@ class SSHConnection(): self.UEDevicesRemoteUser.append(comma_split[2]) self.UEDevicesOffCmd.append(comma_split[3]) self.UEDevicesOnCmd.append(comma_split[4]) + self.UEDevicesRebootCmd.append(comma_split[5]) phone_list_file.close() if terminate_ue_flag == False: @@ -3461,6 +3484,11 @@ class SSHConnection(): if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL spgwc spgwu || true', '\$', 5) self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-spgw*.sh', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep tshark | grep -v grep', '\$', 5) + result = re.search('-w ', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT tshark || true', '\$', 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 ' + self.EPCSourceCodePath + '/scripts/*.pcap', '\$', 5) elif re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5) time.sleep(2) @@ -3776,8 +3804,8 @@ class SSHConnection(): self.command('zip hss.log.zip hss*.log', '\$', 60) self.command('echo ' + self.EPCPassword + ' | sudo -S rm hss*.log', '\$', 5) if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip hss.log.zip logs/hss*.*', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm logs/hss*.*', '\$', 5) + self.command('zip hss.log.zip logs/hss*.* *.pcap', '\$', 60) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f logs/hss*.* *.pcap', '\$', 5) elif re.match('ltebox', self.EPCType, re.IGNORECASE): self.command('cp /opt/hss_sim0609/hss.log .', '\$', 60) self.command('zip hss.log.zip hss.log', '\$', 60) diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml index c1ba7359b3..776c92106d 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml @@ -25,7 +25,7 @@ Build eNB0 wrench - 010101 040101 + 010101 @@ -35,24 +35,4 @@ -w USRP -c --eNB - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - - - Initialize_UE - Initialize UE - - diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml index aa1884baf9..617e78b3bf 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_epc_stop.xml @@ -26,6 +26,7 @@ log-out 050201 060201 070201 + 040101 @@ -44,4 +45,9 @@ Terminate SPGW + + Initialize_UE + Initialize UE + + diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml index 7e8e765b97..5843539f72 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml @@ -19,18 +19,24 @@ For more information about the OpenAirInterface (OAI) Software Alliance: contact@openairinterface.org + 030102 000002 040301 000002 040504 040605 040606 040645 040646 000001 040401 000002 030201 --> test-05-tm1 Test-05MHz-TM1 tasks - 4 + 2 - 030201 + 030201 040101 030102 000002 040301 000002 040504 000001 040401 000002 030201 + + Initialize_UE + Initialize UE + + IdleSleep Sleep for 10 sec @@ -71,28 +77,28 @@ 5 - + Iperf iperf (5MHz - DL/1Mbps/UDP)(30 sec) -u -b 1M -t 30 -i 1 -fm 50 - + Iperf iperf (5MHz - DL/12Mbps/UDP)(30 sec) -u -b 12M -t 30 -i 1 -fm 50 - + Iperf iperf (5MHz - UL/1Mbps/UDP)(30 sec) -u -b 1M -t 30 -i 1 -fm -R 50 - + Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec) -u -b 2M -t 30 -i 1 -fm -R From 09fefc7162233c0f41a1eb964583f1e6ef0cd38c Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 4 Oct 2019 15:59:45 +0200 Subject: [PATCH 051/134] CI: better yet not final tshark capture filter initial support for iperf in distributed environment Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 2cc828a255..bb00d806dd 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -614,14 +614,10 @@ class SSHConnection(): if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep --colour=never "s11"', '\$', 5) - result = re.search('interfaceToUse=(?P[a-zA-Z0-9\-\_\:]+)done', str(self.ssh.before)) - if result is not None: - eth_interface = result.group('eth_interface') - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' and lo \u001B[0m') - EPC_PcapFileName = 'epc_' + self.testCase_id + '.pcap' - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f ' + EPC_PcapFileName, '\$', 5) - self.command('echo $USER; nohup sudo tshark -i ' + eth_interface + ' -i lo -w ' + self.EPCSourceCodePath + '/scripts/' + EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) + logging.debug('\u001B[1m Launching tshark on all interfaces \u001B[0m') + EPC_PcapFileName = 'epc_' + self.testCase_id + '.pcap' + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f ' + EPC_PcapFileName, '\$', 5) + self.command('echo $USER; nohup sudo tshark -f "tcp port not 22 and port not 53" -i any -w ' + self.EPCSourceCodePath + '/scripts/' + EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5) self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) @@ -2500,16 +2496,21 @@ class SSHConnection(): else: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - if (useIperf3): - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) + if self.ADBCentralized: + if (useIperf3): + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) + else: + self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('-u', str(self.iperf_args)) + if result is None: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + udpIperf = False + else: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) else: self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - udpIperf = False - else: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &\' > /dev/null 2>&1', self.ADBUserName, 60) + time.sleep(0.5) self.close() @@ -2568,11 +2569,17 @@ class SSHConnection(): self.command('killall iperf', '\$', 5) else: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60) result = re.search('shell +(?P\d+)', str(self.ssh.before)) if result is not None: pid_iperf = result.group('pid') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) + if self.ADBCentralized: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) self.close() # if the client report is absent, try to analyze the server log file if (clientStatus == -1): From c94a3b85e9accfd1bdee76cd959f9e8f1e553366 Mon Sep 17 00:00:00 2001 From: magounak Date: Tue, 8 Oct 2019 12:25:55 +0200 Subject: [PATCH 052/134] improve hack multi-rru-clean.c --- common/utils/T/tracer/hacks/multi-rru-clean.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/hacks/multi-rru-clean.c b/common/utils/T/tracer/hacks/multi-rru-clean.c index c85dc0de7f..791ef6fac9 100644 --- a/common/utils/T/tracer/hacks/multi-rru-clean.c +++ b/common/utils/T/tracer/hacks/multi-rru-clean.c @@ -12,6 +12,7 @@ void usage(void) "usage: \n" "options:\n" " -d this option is mandatory\n" + " -e trace given event (default CALIBRATION_CHANNEL_ESTIMATES)\n" ); exit(1); } @@ -88,6 +89,7 @@ int main(int n, char **v) int number_of_tags = -1; char *input_filename = NULL; char *output_filename = NULL; + char *event_name = "CALIBRATION_CHANNEL_ESTIMATES"; int i; FILE *in; FILE *out; @@ -107,6 +109,8 @@ int main(int n, char **v) if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-e")) { if (i > n-2) usage(); + event_name = v[++i]; continue; } if (number_of_tags == -1) { number_of_tags = atoi(v[i]); if (number_of_tags <= 0) {usage();} continue; } if (input_filename == NULL) { input_filename = v[i]; continue; } @@ -124,7 +128,7 @@ int main(int n, char **v) database = parse_database(database_filename); - channel_estimate_id = event_id_from_name(database, "CALIBRATION_CHANNEL_ESTIMATES"); + channel_estimate_id = event_id_from_name(database, event_name); f = get_format(database, channel_estimate_id); frame_arg = get_field(&f, "frame", "int"); From b7908ec25d48d5c34ca691bdf806ade0e3cd7f81 Mon Sep 17 00:00:00 2001 From: laurent Date: Tue, 8 Oct 2019 14:27:39 +0200 Subject: [PATCH 053/134] bug fixies --- cmake_targets/CMakeLists.txt | 4 +-- openair1/PHY/CODING/lte_segmentation.c | 2 +- openair1/PHY/LTE_TRANSPORT/uci_tools.c | 4 ++- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 3 +- openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c | 4 +-- openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c | 4 +-- openair1/SCHED_UE/phy_procedures_lte_ue.c | 25 ++++++++------ openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 2 +- openair2/PHY_INTERFACE/IF_Module.c | 6 ++-- openair2/UTIL/OPT/probe.c | 8 +++-- targets/ARCH/rfsimulator/simulator.c | 2 +- targets/ARCH/rfsimulator/stored_node.c | 36 ++++++++++++++++---- targets/RT/USER/lte-ru.c | 7 ++-- 14 files changed, 70 insertions(+), 39 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0a20060af8..3ec21faed5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -183,8 +183,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU ######################### # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O2") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") set(GIT_BRANCH "UNKNOWN") diff --git a/openair1/PHY/CODING/lte_segmentation.c b/openair1/PHY/CODING/lte_segmentation.c index 5116c765b8..6a38707580 100644 --- a/openair1/PHY/CODING/lte_segmentation.c +++ b/openair1/PHY/CODING/lte_segmentation.c @@ -105,7 +105,7 @@ int lte_segmentation(unsigned char *input_buffer, #endif *Kminus = (*Kplus - 64); } else { - printf("lte_segmentation.c: Illegal codeword size !!!\n"); + LOG_E(PHY,"lte_segmentation.c: Illegal codeword size !!!\n"); return(-1); } diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index c301c8510f..08addbb635 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -49,7 +49,9 @@ int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_ else if ((eNB->uci_vars[i].active == 0) && (first_free_index==-1)) first_free_index=i; } if (type == SEARCH_EXIST) return(-1); - else return(first_free_index); + if (first_free_index==-1) + LOG_E(MAC,"UCI table is full\n"); + return(first_free_index); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 5d23c3c23d..20794ae131 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -584,8 +584,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n", r, G, Kr*3, - Q_m, - nb_rb, + ulsch_harq->Qm, ulsch_harq->Nl); #endif start_meas(&eNB->ulsch_rate_unmatching_stats); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c index 968597bfb8..100dd3b2f1 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c @@ -590,10 +590,10 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { LOG_I(PHY,"[UE%d] Initial sync : Estimated power: %d dB\n",ue->Mod_id,ue->measurements.rx_power_avg_dB[0] ); - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) + if (IS_SOFTMODEM_BASICSIM ) phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0); } else { - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) + if (IS_SOFTMODEM_BASICSIM ) phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0); } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c index 8139c496ae..49fa484c26 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c @@ -80,7 +80,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 int i, prach_len; uint16_t first_nonzero_root_idx=0; - if ( !(IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) ) { + if ( !(IS_SOFTMODEM_BASICSIM ) ) { prach_start = (ue->rx_offset+subframe*ue->frame_parms.samples_per_tti-ue->hw_timing_advance-ue->N_TA_offset); #ifdef PRACH_DEBUG LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, @@ -473,7 +473,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 AssertFatal(prach_fmt<4, "prach_fmt4 not fully implemented" ); - if (!(IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) ) { + if (!(IS_SOFTMODEM_BASICSIM ) ) { int j; int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*ue->frame_parms.samples_per_tti; LOG_I( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 5da97b3a1a..9e6644def9 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -166,13 +166,16 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb int gain_dB; double gain_lin; - if (power_dBm<=power_max_dBm) + if ( (power_dBm<=power_max_dBm) && ! IS_SOFTMODEM_RFSIM) gain_dB = power_dBm - power_max_dBm; else gain_dB = 0; gain_lin = pow(10,.1*gain_dB); AssertFatal((nb_rb >0) && (nb_rb <= N_RB_UL),"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL); + LOG_D(PHY," tx gain: %d = %d * sqrt ( pow(10, 0.1*max(0,%d-%d)) * %d/%d ) (gain lin=%f (dB=%d))\n", + (int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)), + AMP, power_dBm, power_max_dBm, N_RB_UL, nb_rb, gain_lin, gain_dB); return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb))); } @@ -1099,7 +1102,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - if (!(IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) ) { + if (!IS_SOFTMODEM_BASICSIM) { ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti- ue->hw_timing_advance- ue->timing_advance- @@ -1130,7 +1133,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt } for (aa=0; aanb_antennas_tx; aa++) { - int *Buff = (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) ? &ue->common_vars.txdata[aa][ulsch_start] :dummy_tx_buffer; + int *Buff = IS_SOFTMODEM_BASICSIM ? &ue->common_vars.txdata[aa][ulsch_start] :dummy_tx_buffer; if (frame_parms->Ncp == 1) { PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], @@ -1151,7 +1154,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt &ue->frame_parms); } - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (IS_SOFTMODEM_BASICSIM ) { apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0); apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1); } else { @@ -1159,7 +1162,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt apply_7_5_kHz(ue,dummy_tx_buffer,1); } - if (!(IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) ) { + if (!(IS_SOFTMODEM_BASICSIM ) ) { overflow = ulsch_start - 9*frame_parms->samples_per_tti; for (k=ulsch_start,l=0; ksamples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) { @@ -1259,7 +1262,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->prach_resources[eNB_id]->ra_RNTI); ue->tx_total_RE[subframe_tx] = 96; - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (IS_SOFTMODEM_BASICSIM ) { ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, @@ -1630,7 +1633,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->tx_total_RE[subframe_tx] = nb_rb*12; - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (IS_SOFTMODEM_BASICSIM ) { tx_amp = AMP; } else { tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx], @@ -1704,7 +1707,7 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8 Po_SRS = ue->tx_power_max_dBm; } - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (IS_SOFTMODEM_BASICSIM) { tx_amp = AMP; } else { if (ue->mac_enabled==1) { @@ -1942,7 +1945,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->tx_power_dBm[subframe_tx] = Po_PUCCH; ue->tx_total_RE[subframe_tx] = 12; - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (IS_SOFTMODEM_BASICSIM ) { tx_amp = AMP; } else { tx_amp = get_tx_amp(Po_PUCCH, @@ -2023,7 +2026,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->tx_power_dBm[subframe_tx] = Po_PUCCH; ue->tx_total_RE[subframe_tx] = 12; - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (IS_SOFTMODEM_BASICSIM ) { tx_amp = AMP; } else { tx_amp = get_tx_amp(Po_PUCCH, @@ -2269,7 +2272,7 @@ void ue_measurement_procedures( // AGC VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN); - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) + if (IS_SOFTMODEM_BASICSIM ) phy_adjust_gain (ue,dB_fixed(ue->measurements.rssi),0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 134089dbf4..2c317900bf 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1506,7 +1506,7 @@ schedule_ue_spec(module_id_t module_idP, tpc = 1; //0 } - LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d\n", + LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d (normal case)\n", module_idP, frameP, subframeP, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index c071c1f505..cc08f4f611 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -2836,7 +2836,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, } if (tpc!=1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", + LOG_D(MAC,"[eNB %d] ULSCH schedulerRR: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP,frameP,subframeP,harq_pid,tpc, tpc_accumulated,snr,target_snr); } diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index 2cc43189c6..98d099add8 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -388,10 +388,10 @@ static void dump_ul(UL_IND_t *u) { A("XXXX crc_ind %d\n", u->crc_ind.crc_indication_body.number_of_crcs); A("XXXX sr_ind %d\n", u->sr_ind.sr_indication_body.number_of_srs); - A("XXXX cqi_ind %d\n", u->cqi_ind.number_of_cqis); + A("XXXX cqi_ind %d\n", u->cqi_ind.cqi_indication_body.number_of_cqis); - for (i = 0; i < u->cqi_ind.number_of_cqis; i++) { - nfapi_cqi_indication_pdu_t *v = &u->cqi_ind.cqi_pdu_list[i]; + for (i = 0; i < u->cqi_ind.cqi_indication_body.number_of_cqis; i++) { + nfapi_cqi_indication_pdu_t *v = &u->cqi_ind.cqi_indication_body.cqi_pdu_list[i]; A("XXXX cqi ind %d\n", i); A("XXXX cqi ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi, v->ul_cqi_information.channel); diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index b032784028..32facd6889 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -396,11 +396,15 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, MAC_Context_Info_t pdu_context; int radioType=FDD_RADIO; - if (RC.eNB[0][0]!=NULL) + if (RC.eNB && RC.eNB[0][0]!=NULL) radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; - if (PHY_vars_UE_g[0][0] != NULL) + else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL) radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; + else { + LOG_E(OPT,"not a eNB neither a UE!!! \n"); + return; + } switch (opt_type) { case OPT_WIRESHARK : diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 76f2f3f0fb..042dd52742 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -430,7 +430,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) { b->circularBuf[(index*nbAnt+a)%CirSize].i=0; } } - + if ( abs(b->th.timestamp-b->lastReceivedTS) > 50 ) LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); } diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index 8cf3aa3bb2..07d6861d57 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -7,6 +7,21 @@ volatile int oai_exit = 0; +int fullread(int fd, void *_buf, int count) +{ + char *buf = _buf; + int ret = 0; + int l; + while (count) { + l = read(fd, buf, count); + if (l <= 0) return -1; + count -= l; + buf += l; + ret += l; + } + return ret; +} + void fullwrite(int fd, void *_buf, int count) { char *buf = _buf; int l; @@ -63,10 +78,10 @@ sin_addr: bool connected=false; while(!connected) { - LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port); + //LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port); if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { - LOG_I(HW,"rfsimulator: connection established\n"); + //LOG_I(HW,"rfsimulator: connection established\n"); connected=true; } @@ -108,12 +123,13 @@ int main(int argc, char *argv[]) { if (strcmp(argv[2],"server")==0) { serviceSock=server_start(atoi(argv[3])); } else { - client_start(argv[2],atoi(argv[3])); + serviceSock=client_start(argv[2],atoi(argv[3])); } samplesBlockHeader_t header; int bufSize=100000; void *buff=malloc(bufSize); + uint64_t readTS=0; while (1) { //Rewind the file to loop on the samples @@ -125,6 +141,7 @@ int main(int argc, char *argv[]) { AssertFatal(read(fd,&header,sizeof(header)), ""); fullwrite(serviceSock, &header, sizeof(header)); int dataSize=sizeof(int32_t)*header.size*header.nbAnt; + uint64_t wroteTS=header.timestamp; if (dataSize>bufSize) { void * new_buff = realloc(buff, dataSize); @@ -139,9 +156,16 @@ int main(int argc, char *argv[]) { AssertFatal(read(fd,buff,dataSize) == dataSize, ""); fullwrite(serviceSock, buff, dataSize); // Purge incoming samples - setblocking(serviceSock, notBlocking); - - while(recv(serviceSock,buff, bufSize, MSG_DONTWAIT) > 0) { + setblocking(serviceSock, blocking); + while(readTS < wroteTS) { + if ( fullread(serviceSock, &header,sizeof(header)) != sizeof(header) || + fullread(serviceSock, buff, sizeof(int32_t)*header.size*header.nbAnt) != + sizeof(int32_t)*header.size*header.nbAnt + ) { + printf("error: %s\n", strerror(errno)); + exit(1); + } + readTS=header.timestamp; } } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 89abd12499..b1894be28f 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1202,7 +1202,8 @@ void wakeup_L1s(RU_t *ru) { ru->proc.emulate_rf_busy = 0; } -inline int wakeup_prach_ru(RU_t *ru) { + +void wakeup_prach_ru(RU_t *ru) { int ret; struct timespec wait; int time_ns = 5000000L; @@ -1234,11 +1235,10 @@ inline int wakeup_prach_ru(RU_t *ru) { } else LOG_W(PHY,"RU prach thread busy, skipping\n"); AssertFatal((ret=pthread_mutex_unlock( &ru->proc.mutex_prach ))==0,"mutex_unlock returns %d\n",ret); - return(0); } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -inline int wakeup_prach_ru_br(RU_t *ru) { +void wakeup_prach_ru_br(RU_t *ru) { int ret; struct timespec wait; int time_ns = 5000000L; @@ -1264,7 +1264,6 @@ inline int wakeup_prach_ru_br(RU_t *ru) { } else LOG_W(PHY,"RU prach thread busy, skipping\n"); AssertFatal((ret=pthread_mutex_unlock( &ru->proc.mutex_prach_br ))==0,"mutex_unlock returns %d\n",ret); - return(0); } #endif From 445cf84e94d55177679cd946bcb2cd8e8e6afad2 Mon Sep 17 00:00:00 2001 From: laurent Date: Tue, 8 Oct 2019 16:04:10 +0200 Subject: [PATCH 054/134] clean up wireshark traces --- openair1/SCHED_UE/phy_procedures_lte_ue.c | 2 -- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 18 ++++------- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 30 ++----------------- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 35 +--------------------- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 4 --- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 7 +---- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 7 ----- openair2/LAYER2/MAC/ra_procedures.c | 16 ++-------- openair2/LAYER2/MAC/rar_tools.c | 15 ---------- openair2/LAYER2/MAC/rar_tools_ue.c | 5 ---- openair2/LAYER2/MAC/ue_procedures.c | 27 ----------------- openair2/UTIL/OPT/README.txt | 7 ++++- openair2/UTIL/OPT/opt.h | 6 ++-- openair2/UTIL/OPT/probe.c | 4 ++- 14 files changed, 24 insertions(+), 159 deletions(-) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 9e6644def9..b522af0857 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2349,8 +2349,6 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0]; trace_pdu( DIRECTION_DOWNLINK, dummy, WS_C_RNTI, ue->Mod_id, 0, 0, frame_rx, subframe_rx, 0, 0); - LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n", - ue->Mod_id, subframe_rx); } if (pbch_tx_ant>2) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 732e7d984f..439fdbc281 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -914,10 +914,10 @@ generate_Msg4(module_id_t module_idP, T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_idP), T_INT (ra->rnti), T_INT (frameP), T_INT (subframeP), T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize)); - if (opt_enabled == 1) { - trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], ra->msg4_rrc_sdu_length, UE_id, 3, UE_RNTI (module_idP, UE_id), mac->frame, mac->subframe, 0, 0); - LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_idP, frameP, UE_RNTI (module_idP, UE_id), ra->msg4_rrc_sdu_length); - } + trace_pdu (DIRECTION_DOWNLINK, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], + ra->msg4_rrc_sdu_length, + UE_id, 3, UE_RNTI (module_idP, UE_id), + mac->frame, mac->subframe, 0, 0); } // Msg4 frame/subframe } // rach_resource_type > 0 else @@ -1095,20 +1095,12 @@ generate_Msg4(module_id_t module_idP, T_BUFFER(&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id]. payload[0], ra->msg4_TBsize)); - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) mac-> UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, WS_C_RNTI, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, CC_idP, frameP, UE_RNTI(module_idP, - UE_id), - rrc_sdu_length); - } - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) { set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index d523fb4e17..51674ae881 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -281,15 +281,10 @@ schedule_SIB1_MBMS(module_id_t module_idP, eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_BR_pdu[0].payload[0], bcch_sdu_length, 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); - } if (cc->tdd_Config != NULL) { //TDD LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", @@ -509,15 +504,10 @@ schedule_SIB1_BR(module_id_t module_idP, eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, + trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_BR_pdu[0].payload[0], bcch_sdu_length, 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); - } if (cc->tdd_Config != NULL) { //TDD LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", @@ -709,7 +699,6 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_BR_pdu[i + 1].payload[0], bcch_sdu_length, @@ -717,9 +706,6 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); - } if (cc->tdd_Config != NULL) { //TDD LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n", frameP, i, CC_id, bcch_sdu_length); @@ -919,17 +905,11 @@ schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_MBMS_pdu.payload, bcch_sdu_length)); - if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_MBMS_pdu.payload[0], bcch_sdu_length, 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][BCH-MBMS] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, - bcch_sdu_length); - } if (0/*cc->tdd_Config != NULL*/) { //TDD not for FeMBMS LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", @@ -1224,17 +1204,11 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_pdu.payload, bcch_sdu_length)); - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, + trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_pdu.payload[0], bcch_sdu_length, 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, - bcch_sdu_length); - } if (cc->tdd_Config != NULL) { //TDD LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 2c317900bf..3080b4153a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1422,7 +1422,6 @@ schedule_ue_spec(module_id_t module_idP, dlsch_pdu->payload[0][offset + sdu_length_total + j] = 0; } - if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_pdu->payload[0], TBS, @@ -1434,14 +1433,6 @@ schedule_ue_spec(module_id_t module_idP, eNB->subframe, 0, 0); - LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, - CC_id, - frameP, - UE_RNTI(module_idP, - UE_id), - TBS); - } T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), @@ -2345,8 +2336,7 @@ schedule_ue_spec_br(module_id_t module_idP, UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus()&0xff); } - if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS, module_idP, @@ -2356,13 +2346,6 @@ schedule_ue_spec_br(module_id_t module_idP, mac->subframe, 0, 0); - LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, - CC_id, - frameP, - UE_RNTI(module_idP, UE_id), - TBS); - } T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), @@ -2557,7 +2540,6 @@ schedule_ue_spec_br(module_id_t module_idP, T_INT (0 /* harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length)); - if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], TX_req->pdu_length, @@ -2568,13 +2550,6 @@ schedule_ue_spec_br(module_id_t module_idP, subframeP, 0, 0); - LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, - CC_id, - frameP, - rnti, - TX_req->pdu_length); - } } // end else if ((subframeP == 7) && (round_DL < 8)) } // end loop on UE_id } @@ -3180,7 +3155,6 @@ schedule_PCH(module_id_t module_idP, continue; } - if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, &eNB->common_channels[CC_id].PCCH_pdu.payload[0], pcch_sdu_length, @@ -3191,13 +3165,6 @@ schedule_PCH(module_id_t module_idP, eNB->subframe, 0, 0); - LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, - frameP, - CC_id, - 0xffff, - pcch_sdu_length); - } eNB->eNB_stats[CC_id].total_num_pcch_pdu++; eNB->eNB_stats[CC_id].pcch_buffer = pcch_sdu_length; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index cc08f4f611..a837f3edf4 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -1703,13 +1703,9 @@ schedule_ue_spec_fairRR(module_id_t module_idP, UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); } - if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id), eNB->frame, eNB->subframe,0,0); - LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP, UE_id), TBS); - } T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index cf358752e8..a8191f3abb 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -766,14 +766,9 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } /* Tracing of PDU is done on UE side */ - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xffff, // M_RNTI = 6 in wirehsark + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xffff, // M_RNTI = 6 in wirehsark RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n", - module_idP, CC_id, frameP, TBS); - } /* for (j=0;jrx_ulsch_sdu); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); - if (opt_enabled == 1) { trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0); - LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", - enb_mod_idP, - frameP, - current_rnti, - sdu_lenP); - } if (UE_id != -1) { UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index 70cee3e24b..f47cdaca0e 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -256,16 +256,11 @@ Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, // start contention resolution timer UE_mac_inst[module_idP].RA_attempt_number++; - if (opt_enabled) { - trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI, + trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI, UE_mac_inst[module_idP].RA_prach_resources. ra_PreambleIndex, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, UE_mac_inst[module_idP].RA_attempt_number); - LOG_D(OPT, - "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size); - } } @@ -281,18 +276,11 @@ Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0; UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; - if (opt_enabled) { // msg3 - trace_pdu(DIRECTION_UPLINK, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], + trace_pdu(DIRECTION_UPLINK, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", - module_idP, frameP, UE_mac_inst[module_idP].crnti - /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex */ - , UE_mac_inst[module_idP].RA_Msg3_size); - } } diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index cb18d8dffe..7661759611 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -95,16 +95,9 @@ fill_rar(const module_id_t module_idP, (((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) | ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1); - if (opt_enabled) { trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, module_idP, WS_RA_RNTI , 1, RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", - module_idP, CC_id, frameP, ra->rnti, rarh->RAPID, - input_buffer_length); - } - return (ra->rnti); } @@ -209,7 +202,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, ra->preamble_index, ra->timing_offset); - if (opt_enabled) { trace_pdu(DIRECTION_DOWNLINK, dlsch_buffer, input_buffer_length, @@ -221,13 +213,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, 0, 0); - LOG_D(OPT, "[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", - frameP, - ra->rnti, - rarh->RAPID, - input_buffer_length); - } - return (ra->rnti); } #endif diff --git a/openair2/LAYER2/MAC/rar_tools_ue.c b/openair2/LAYER2/MAC/rar_tools_ue.c index 35d1f7925e..b08173a406 100644 --- a/openair2/LAYER2/MAC/rar_tools_ue.c +++ b/openair2/LAYER2/MAC/rar_tools_ue.c @@ -115,14 +115,9 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra (uint16_t) rar[5] + (rar[4] << 8)); #endif - if (opt_enabled) { - LOG_D(OPT, - "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", - module_idP, CC_id, frameP, ra_rnti); trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, module_idP, WS_RA_RNTI, ra_rnti, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); - } if (preamble_index == rarh->RAPID) { *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti; diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index f001c5f2ae..8f3892013b 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -403,14 +403,8 @@ ue_send_sdu(module_id_t module_idP, //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); - if (opt_enabled) { trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI, UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0); - LOG_D(OPT, - "[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, UE_mac_inst[module_idP].crnti, sdu_len); - } - payload_ptr = parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_len); @@ -617,7 +611,6 @@ ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frameP, #if UE_TIMING_TRACE stop_meas(&UE_mac_inst[module_idP].rx_si); #endif - if (opt_enabled == 1) { trace_pdu(DIRECTION_UPLINK, (uint8_t *) pdu, len, @@ -626,10 +619,6 @@ ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frameP, 0xffff, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, len); - } } #endif @@ -653,7 +642,6 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, stop_meas(&UE_mac_inst[module_idP].rx_si); #endif - if (opt_enabled == 1) { trace_pdu(DIRECTION_UPLINK, (uint8_t *) pdu, len, @@ -662,10 +650,6 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, 0xffff, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, len); - } } void @@ -689,7 +673,6 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, stop_meas(&UE_mac_inst[module_idP].rx_p); #endif - if (opt_enabled == 1) { trace_pdu(DIRECTION_UPLINK, (uint8_t *) pdu, len, @@ -698,10 +681,6 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, P_RNTI, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, P_RNTI, len); - } } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -2462,16 +2441,10 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); #endif - if (opt_enabled) { trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][ULSCH] Frame %d subframe %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, subframe, UE_mac_inst[module_idP].crnti, - buflen); - } } diff --git a/openair2/UTIL/OPT/README.txt b/openair2/UTIL/OPT/README.txt index c56aeda93d..a8cbf10d82 100644 --- a/openair2/UTIL/OPT/README.txt +++ b/openair2/UTIL/OPT/README.txt @@ -8,6 +8,11 @@ How to configure wireshark for dissecting LTE protocols: - select RLC-LTE, and check all the options except the "May see RLC headers only", and set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM. How to use -- start eNB or UE with option -W (or -P if you want to make a pcap file) +- start eNB or UE with option --opt.type wireshark + --opt options are: + --opt.type none/wireshark/pcap + --opt.ip 127.0.0.1 to specify the output IP address (default: 127.0.0.1) + output port is always: 9999 (to change it, change constant: PACKET_MAC_LTE_DEFAULT_UDP_PORT in OAI code) + --opt.path file_name to specify the file name (pcap) - capture on local interface "lo" - filter out the ICMP/DNS/TCP messages (e.g. "!icmp && !dns && !tcp") diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index 5ae19f9b55..1dbb606252 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -111,7 +111,10 @@ typedef enum radio_type_e { * function def */ -void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, +extern int opt_enabled; +#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(x) + +void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe, int oob_event, int oob_event_value); @@ -119,7 +122,6 @@ int init_opt(void); void terminate_opt(void); -extern int opt_enabled; //double *timing_analyzer(int index, int direction ); #endif /* OPT_H_ */ diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 32facd6889..d5631032b9 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -390,11 +390,13 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, extern RAN_CONTEXT_t RC; #include /* Remote serveraddress (where Wireshark is running) */ -void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, +void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, int oob_event_value) { MAC_Context_Info_t pdu_context; int radioType=FDD_RADIO; + LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n", + direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber); if (RC.eNB && RC.eNB[0][0]!=NULL) radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; From 0b7489b12211b651044e895840b5116301e28bec Mon Sep 17 00:00:00 2001 From: laurent Date: Tue, 8 Oct 2019 16:15:29 +0200 Subject: [PATCH 055/134] astyle only --- openair1/PHY/CODING/lte_segmentation.c | 2 +- openair1/PHY/LTE_TRANSPORT/uci_tools.c | 14 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 41 +- openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c | 248 ++- openair1/SCHED_UE/phy_procedures_lte_ue.c | 927 +++++---- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 53 +- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 1769 +++++++++--------- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 103 +- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 36 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 1416 +++++++------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 967 +++++----- openair2/LAYER2/MAC/ra_procedures.c | 20 +- openair2/LAYER2/MAC/rar_tools.c | 142 +- openair2/LAYER2/MAC/rar_tools_ue.c | 160 +- openair2/LAYER2/MAC/ue_procedures.c | 94 +- openair2/PHY_INTERFACE/IF_Module.c | 191 +- openair2/UTIL/OPT/README.txt | 30 +- openair2/UTIL/OPT/opt.h | 4 +- openair2/UTIL/OPT/probe.c | 15 +- targets/ARCH/rfsimulator/simulator.c | 3 +- targets/ARCH/rfsimulator/stored_node.c | 29 +- targets/RT/USER/lte-ru.c | 1264 ++++++------- 22 files changed, 3705 insertions(+), 3823 deletions(-) diff --git a/openair1/PHY/CODING/lte_segmentation.c b/openair1/PHY/CODING/lte_segmentation.c index 6a38707580..7b8308656a 100644 --- a/openair1/PHY/CODING/lte_segmentation.c +++ b/openair1/PHY/CODING/lte_segmentation.c @@ -59,7 +59,7 @@ int lte_segmentation(unsigned char *input_buffer, } if ((*C)>MAX_NUM_DLSCH_SEGMENTS) { - printf("%d\n",*(int*)0); + printf("%d\n",*(int *)0); LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime); return(-1); } diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 08addbb635..f8ade9afc8 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -31,7 +31,7 @@ */ #include "PHY/defs_eNB.h" #ifdef DEBUG_UCI_TOOLS -#include "PHY/vars.h" + #include "PHY/vars.h" #endif //#define DEBUG_UCI 1 @@ -41,16 +41,20 @@ int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_ uint16_t i; int16_t first_free_index=-1; AssertFatal(eNB!=NULL,"eNB is null\n"); + for (i=0; iuci_vars[i].active >0) && - (eNB->uci_vars[i].rnti==rnti) && - (eNB->uci_vars[i].frame==frame) && - (eNB->uci_vars[i].subframe==subframe)) return(i); + (eNB->uci_vars[i].rnti==rnti) && + (eNB->uci_vars[i].frame==frame) && + (eNB->uci_vars[i].subframe==subframe)) return(i); else if ((eNB->uci_vars[i].active == 0) && (first_free_index==-1)) first_free_index=i; } + if (type == SEARCH_EXIST) return(-1); + if (first_free_index==-1) - LOG_E(MAC,"UCI table is full\n"); + LOG_E(MAC,"UCI table is full\n"); + return(first_free_index); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 20794ae131..946f6b3ee1 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -563,8 +563,8 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) else tc = *decoder8; - if(ulsch_harq->repetition_number == 1){ - memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions + if(ulsch_harq->repetition_number == 1) { + memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions } for (r=0; rC; r++) { @@ -609,27 +609,23 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) } stop_meas(&eNB->ulsch_rate_unmatching_stats); - max_Ncb = 3*ulsch_harq->RTC[r]*32 ; - if(ulsch_harq->total_number_of_repetitions > 1) - { - if (ulsch_harq->rvidx==1) - { // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1 - for (int nn=0;nnw[r][nn] ; - } + if(ulsch_harq->total_number_of_repetitions > 1) { + if (ulsch_harq->rvidx==1) { + // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1 + for (int nn=0; nnw[r][nn] ; } - if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) - { - for (int nn=0;nnw[r][nn] = pusch_rep_buffer[nn] ; - } - } } + if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) { + for (int nn=0; nnw[r][nn] = pusch_rep_buffer[nn] ; + } + } + } + r_offset += E; start_meas(&eNB->ulsch_deinterleaving_stats); sub_block_deinterleaving_turbo(4+Kr, @@ -763,18 +759,17 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int frame = proc->frame_rx; int subframe = proc->subframe_rx; LTE_UL_eNB_HARQ_t *ulsch_harq; - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(PHY,"ue_type %d\n",ulsch->ue_type); + if (ulsch->ue_type>0) harq_pid = 0; else #endif - { - harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); - } + { + harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1); - // x1 is set in lte_gold_generic x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1 ulsch_harq = ulsch->harq_processes[harq_pid]; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c index 100dd3b2f1..3478d522ab 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c @@ -50,7 +50,6 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy; LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; char phich_resource[6]; - LOG_D(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id, ue->rx_offset); @@ -95,7 +94,6 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { 0); } - LOG_D(PHY,"[UE %d] RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n", ue->Mod_id, ue->measurements.rx_rssi_dBm[0] - ((ue->frame_parms.nb_antennas_rx==2) ? 3 : 0), @@ -106,7 +104,6 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { ue->measurements.rx_power_avg_dB[0], ue->measurements.rx_power_avg[0], ue->rx_total_gain_dB); - LOG_D(PHY,"[UE %d] N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n", ue->Mod_id, ue->measurements.n0_power_tot_dBm, @@ -116,57 +113,60 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { ue->measurements.n0_power[1], ue->measurements.n0_power_avg_dB, ue->measurements.n0_power_avg); - pbch_decoded = 0; for (frame_mod4=0; frame_mod4<4; frame_mod4++) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ue->FeMBMS_active != 2){ + + if (ue->FeMBMS_active != 2) { #endif - pbch_tx_ant = rx_pbch(&ue->common_vars, - ue->pbch_vars[0], - frame_parms, - 0, - SISO, - ue->high_speed_flag, - frame_mod4); + pbch_tx_ant = rx_pbch(&ue->common_vars, + ue->pbch_vars[0], + frame_parms, + 0, + SISO, + ue->high_speed_flag, + frame_mod4); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - }else{ - pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, - ue->pbch_vars[0], - frame_parms, - 0, - SISO, - ue->high_speed_flag, - frame_mod4); - } + } else { + pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, + ue->pbch_vars[0], + frame_parms, + 0, + SISO, + ue->high_speed_flag, + frame_mod4); + } + #endif - if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) { - pbch_decoded = 1; - break; + if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) { + pbch_decoded = 1; + break; } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ue->FeMBMS_active != 2){ + + if (ue->FeMBMS_active != 2) { #endif - pbch_tx_ant = rx_pbch(&ue->common_vars, - ue->pbch_vars[0], - frame_parms, - 0, - ALAMOUTI, - ue->high_speed_flag, - frame_mod4); + pbch_tx_ant = rx_pbch(&ue->common_vars, + ue->pbch_vars[0], + frame_parms, + 0, + ALAMOUTI, + ue->high_speed_flag, + frame_mod4); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - }else{ - pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, - ue->pbch_vars[0], - frame_parms, - 0, - ALAMOUTI, - ue->high_speed_flag, - frame_mod4); + } else { + pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, + ue->pbch_vars[0], + frame_parms, + 0, + ALAMOUTI, + ue->high_speed_flag, + frame_mod4); } + #endif if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) { @@ -218,73 +218,72 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(ue->FeMBMS_active != 2) { + + if(ue->FeMBMS_active != 2) { #endif - // now check for PHICH parameters - frame_parms->phich_config_common.phich_duration = (PHICH_DURATION_t)((ue->pbch_vars[0]->decoded_output[2]>>4)&1); - dummy = (ue->pbch_vars[0]->decoded_output[2]>>2)&3; + // now check for PHICH parameters + frame_parms->phich_config_common.phich_duration = (PHICH_DURATION_t)((ue->pbch_vars[0]->decoded_output[2]>>4)&1); + dummy = (ue->pbch_vars[0]->decoded_output[2]>>2)&3; - switch (dummy) { - case 0: - frame_parms->phich_config_common.phich_resource = oneSixth; - sprintf(phich_resource,"1/6"); - break; + switch (dummy) { + case 0: + frame_parms->phich_config_common.phich_resource = oneSixth; + sprintf(phich_resource,"1/6"); + break; - case 1: - frame_parms->phich_config_common.phich_resource = half; - sprintf(phich_resource,"1/2"); - break; + case 1: + frame_parms->phich_config_common.phich_resource = half; + sprintf(phich_resource,"1/2"); + break; - case 2: - frame_parms->phich_config_common.phich_resource = one; - sprintf(phich_resource,"1"); - break; + case 2: + frame_parms->phich_config_common.phich_resource = one; + sprintf(phich_resource,"1"); + break; - case 3: - frame_parms->phich_config_common.phich_resource = two; - sprintf(phich_resource,"2"); - break; + case 3: + frame_parms->phich_config_common.phich_resource = two; + sprintf(phich_resource,"2"); + break; - default: - LOG_E(PHY,"[UE%d] Initial sync: Unknown PHICH_DURATION\n",ue->Mod_id); - return -1; - break; - } + default: + LOG_E(PHY,"[UE%d] Initial sync: Unknown PHICH_DURATION\n",ue->Mod_id); + return -1; + break; + } - for(int i=0; iproc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; - ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; - ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; - } + for(int i=0; iproc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; + ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; + ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; + } - - LOG_D(PHY,"[UE%d] Initial sync: pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n", - ue->Mod_id, - frame_parms->nb_antenna_ports_eNB, - pbch_tx_ant, - ue->proc.proc_rxtx[0].frame_rx, - frame_parms->N_RB_DL, - frame_parms->phich_config_common.phich_duration, - phich_resource); //frame_parms->phich_config_common.phich_resource); - -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - }else{ - for(int i=0; iproc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&31)<<1) + (ue->pbch_vars[0]->decoded_output[1]>>7))<<4; - ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; - } - LOG_D(PHY,"[UE%d] Initial sync: FeMBMS pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, AdditionalNonMBSFN_SF %d, frame_mod4 %d\n", + LOG_D(PHY,"[UE%d] Initial sync: pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n", ue->Mod_id, frame_parms->nb_antenna_ports_eNB, pbch_tx_ant, ue->proc.proc_rxtx[0].frame_rx, frame_parms->N_RB_DL, - 0, - frame_mod4 - ); - - } + frame_parms->phich_config_common.phich_duration, + phich_resource); //frame_parms->phich_config_common.phich_resource); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + } else { + for(int i=0; iproc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&31)<<1) + (ue->pbch_vars[0]->decoded_output[1]>>7))<<4; + ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; + } + + LOG_D(PHY,"[UE%d] Initial sync: FeMBMS pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, AdditionalNonMBSFN_SF %d, frame_mod4 %d\n", + ue->Mod_id, + frame_parms->nb_antenna_ports_eNB, + pbch_tx_ant, + ue->proc.proc_rxtx[0].frame_rx, + frame_parms->N_RB_DL, + 0, + frame_mod4 + ); + } + #endif return(0); } else { @@ -310,7 +309,6 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { frame_parms->frame_type=FDD; frame_parms->nb_antenna_ports_eNB = 2; init_frame_parms(frame_parms,1); - /* LOG_M("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); exit(-1); @@ -325,9 +323,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { else sync_pos2 = sync_pos + FRAME_LENGTH_COMPLEX_SAMPLES - frame_parms->nb_prefix_samples; - LOG_D(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n",ue->Mod_id,sync_pos,ue->common_vars.eNb_id); - // SSS detection // PSS is hypothesized in last symbol of first slot in Frame sync_pos_slot = (frame_parms->samples_per_tti>>1) - frame_parms->ofdm_symbol_size - frame_parms->nb_prefix_samples; @@ -350,22 +346,23 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell); ret = pbch_detection(ue,mode); // LOG_M("rxdata2.m","rxd2",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); - LOG_D(PHY,"FDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ret==-1){ - ue->FeMBMS_active = 2; - ret = pbch_detection(ue,mode); - if (ret==-1){ - ue->FeMBMS_active = 0; - frame_parms->FeMBMS_active = 0; - } - else frame_parms->FeMBMS_active = 1; + + if (ret==-1) { + ue->FeMBMS_active = 2; + ret = pbch_detection(ue,mode); + + if (ret==-1) { + ue->FeMBMS_active = 0; + frame_parms->FeMBMS_active = 0; + } else frame_parms->FeMBMS_active = 1; + LOG_D(PHY,"FeMBMS Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", - frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret); - } + frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret); + } + #endif } else { LOG_D(PHY,"FDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot); @@ -406,23 +403,22 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { // LOG_M("rxdata3.m","rxd3",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); LOG_D(PHY,"FDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ret==-1){ - ue->FeMBMS_active = 2; - ret = pbch_detection(ue,mode); - if (ret==-1){ - ue->FeMBMS_active = 0; - frame_parms->FeMBMS_active = 0; - } - else frame_parms->FeMBMS_active = 1; - LOG_I(PHY,"FeMBMS CAS Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", - frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret); + if (ret==-1) { + ue->FeMBMS_active = 2; + ret = pbch_detection(ue,mode); + + if (ret==-1) { + ue->FeMBMS_active = 0; + frame_parms->FeMBMS_active = 0; + } else frame_parms->FeMBMS_active = 1; + + LOG_I(PHY,"FeMBMS CAS Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", + frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret); } + #endif - - } else { LOG_D(PHY,"FDD Extended prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot); } @@ -460,9 +456,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell); ret = pbch_detection(ue,mode); // LOG_M("rxdata4.m","rxd4",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); - LOG_D(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", - frame_parms->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,flip_tdd_ncp,ret); if (ret==-1) { @@ -496,9 +490,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { lte_gold(frame_parms,ue->lte_gold_table[0],frame_parms->Nid_cell); ret = pbch_detection(ue,mode); // LOG_M("rxdata5.m","rxd5",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); - LOG_D(PHY,"TDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", - frame_parms->Nid_cell,metric_tdd_ecp,phase_tdd_ecp,flip_tdd_ecp,ret); } } @@ -525,7 +517,6 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { generate_pcfich_reg_mapping(frame_parms); generate_phich_reg_mapping(frame_parms); ue->pbch_vars[0]->pdu_errors_conseq=0; - } LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id, @@ -562,7 +553,6 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { metric_tdd_ecp,Nid_cell_tdd_ecp);*/ LOG_D(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id, frame_parms->Nid_cell,frame_parms->frame_type); - ue->UE_mode[0] = NOT_SYNCHED; ue->pbch_vars[0]->pdu_errors_last=ue->pbch_vars[0]->pdu_errors; ue->pbch_vars[0]->pdu_errors++; @@ -587,7 +577,6 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { // we might add a low-pass filter here later ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx; ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]); - LOG_I(PHY,"[UE%d] Initial sync : Estimated power: %d dB\n",ue->Mod_id,ue->measurements.rx_power_avg_dB[0] ); if (IS_SOFTMODEM_BASICSIM ) @@ -595,7 +584,6 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { } else { if (IS_SOFTMODEM_BASICSIM ) phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0); - } return ret; diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index b522af0857..84db43933a 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -19,17 +19,17 @@ * contact@openairinterface.org */ - /*! \file phy_procedures_lte_ue.c - * \brief Implementation of UE procedures from 36.213 LTE specifications / This includes FeMBMS UE procedures from 36.213 v14.2.0 specification - * \author R. Knopp, F. Kaltenberger, N. Nikaein, J. Morgade - * \date 2011 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr, javier.morgad +/*! \file phy_procedures_lte_ue.c + * \brief Implementation of UE procedures from 36.213 LTE specifications / This includes FeMBMS UE procedures from 36.213 v14.2.0 specification + * \author R. Knopp, F. Kaltenberger, N. Nikaein, J. Morgade + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr, javier.morgad e@ieee.org - * \note - * \warning - */ + * \note + * \warning + */ #define _GNU_SOURCE @@ -173,9 +173,9 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb gain_lin = pow(10,.1*gain_dB); AssertFatal((nb_rb >0) && (nb_rb <= N_RB_UL),"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL); - LOG_D(PHY," tx gain: %d = %d * sqrt ( pow(10, 0.1*max(0,%d-%d)) * %d/%d ) (gain lin=%f (dB=%d))\n", - (int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)), - AMP, power_dBm, power_max_dBm, N_RB_UL, nb_rb, gain_lin, gain_dB); + LOG_D(PHY," tx gain: %d = %d * sqrt ( pow(10, 0.1*max(0,%d-%d)) * %d/%d ) (gain lin=%f (dB=%d))\n", + (int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)), + AMP, power_dBm, power_max_dBm, N_RB_UL, nb_rb, gain_lin, gain_dB); return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb))); } @@ -1664,8 +1664,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++) generate_drs_pusch(ue, proc, - (LTE_DL_FRAME_PARMS *)NULL, - (int32_t**)NULL, + (LTE_DL_FRAME_PARMS *)NULL, + (int32_t **)NULL, eNB_id, tx_amp, subframe_tx, @@ -2312,24 +2312,23 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin //for (pbch_phase=0;pbch_phase<4;pbch_phase++) { //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)){ - pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, - ue->pbch_vars[eNB_id], - &ue->frame_parms, - eNB_id, - ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, - ue->high_speed_flag, - pbch_phase); - - }else + if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { + pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, + ue->pbch_vars[eNB_id], + &ue->frame_parms, + eNB_id, + ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, + ue->high_speed_flag, + pbch_phase); + } else #endif - pbch_tx_ant = rx_pbch(&ue->common_vars, - ue->pbch_vars[eNB_id], - &ue->frame_parms, - eNB_id, - ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, - ue->high_speed_flag, - pbch_phase); + pbch_tx_ant = rx_pbch(&ue->common_vars, + ue->pbch_vars[eNB_id], + &ue->frame_parms, + eNB_id, + ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, + ue->high_speed_flag, + pbch_phase); if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) { break; @@ -2357,21 +2356,21 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin return; } - ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)){ - frame_tx = (int)((ue->pbch_vars[eNB_id]->decoded_output[2]&31)<<1); - frame_tx += ue->pbch_vars[eNB_id]->decoded_output[1]>>7; - frame_tx +=4*pbch_phase; - }else{ + if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { + frame_tx = (int)((ue->pbch_vars[eNB_id]->decoded_output[2]&31)<<1); + frame_tx += ue->pbch_vars[eNB_id]->decoded_output[1]>>7; + frame_tx +=4*pbch_phase; + } else { #endif - frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8); - frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc)); - frame_tx += pbch_phase; + frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8); + frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc)); + frame_tx += pbch_phase; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - } + } + #endif if (ue->mac_enabled==1) { @@ -2795,9 +2794,9 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -, uint8_t fembms_flag + , uint8_t fembms_flag #endif -) { + ) { int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; @@ -2828,72 +2827,75 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs if (pmch_mcs>=0) { LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs); fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/){ -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_FUNCTION_IN); - slot_fep_mbsfn_khz_1dot25(ue,subframe_rx,0); -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_FUNCTION_OUT); - } - else{ + + if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_FUNCTION_IN); + slot_fep_mbsfn_khz_1dot25(ue,subframe_rx,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_FUNCTION_OUT); + } else { #endif -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_FUNCTION_IN); - for (l=2; l<12; l++) { - slot_fep_mbsfn(ue, - l, - subframe_rx, - 0,0);//ue->rx_offset,0); - } -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_FUNCTION_IN); + + for (l=2; l<12; l++) { + slot_fep_mbsfn(ue, + l, + subframe_rx, + 0,0);//ue->rx_offset,0); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_FUNCTION_OUT); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) } -#endif +#endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/){ -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_FUNCTION_IN); - rx_pmch_khz_1dot25(ue,0,subframe_rx,pmch_mcs); -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_FUNCTION_OUT); - } - else{ + if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_FUNCTION_IN); + rx_pmch_khz_1dot25(ue,0,subframe_rx,pmch_mcs); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_FUNCTION_OUT); + } else { #endif -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_FUNCTION_IN); - for (l=2; l<12; l++) { - rx_pmch(ue, - 0, - subframe_rx, - l); - } -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_FUNCTION_IN); + + for (l=2; l<12; l++) { + rx_pmch(ue, + 0, + subframe_rx, + l); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_FUNCTION_OUT); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) } -#endif -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_FUNCTION_IN); +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_FUNCTION_IN); ue->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(pmch_mcs); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/) - ue->dlsch_MCH[0]->harq_processes[0]->G = get_G_khz_1dot25(&ue->frame_parms, - ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, - ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, - ue->dlsch_MCH[0]->harq_processes[0]->Qm, - 1, - 2, - frame_rx, - subframe_rx, - 0); + ue->dlsch_MCH[0]->harq_processes[0]->G = get_G_khz_1dot25(&ue->frame_parms, + ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, + ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, + ue->dlsch_MCH[0]->harq_processes[0]->Qm, + 1, + 2, + frame_rx, + subframe_rx, + 0); else #endif - ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms, - ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, - ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, - ue->dlsch_MCH[0]->harq_processes[0]->Qm, - 1, - 2, - frame_rx, - subframe_rx, - 0); + ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms, + ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, + ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, + ue->dlsch_MCH[0]->harq_processes[0]->Qm, + 1, + 2, + frame_rx, + subframe_rx, + 0); dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0], ue->dlsch_MCH[0]->harq_processes[0]->G, @@ -2913,7 +2915,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_D subframe_rx, 0, 0,1); -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_FUNCTION_OUT); if (mcch_active == 1) ue->dlsch_mcch_trials[sync_area][0]++; @@ -2935,7 +2937,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_D ue->dlsch_MCH[0]->max_turbo_iterations, ue->dlsch_MCH[0]->harq_processes[0]->G); // dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); - //if(subframe_rx == 3){ + //if(subframe_rx == 3){ //dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); //exit_fun("nothing to add"); //} @@ -2960,7 +2962,6 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_D ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, ue->dlsch_MCH[0]->max_turbo_iterations, ue->dlsch_MCH[0]->harq_processes[0]->G); - ue_send_mch_sdu(ue->Mod_id, CC_id, frame_rx, @@ -3448,24 +3449,24 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, case SI_PDSCH: #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(subframe_rx == 0) { - ue_decode_si_mbms(ue->Mod_id, - CC_id, - frame_rx, - eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->b, - ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + if(subframe_rx == 0) { + ue_decode_si_mbms(ue->Mod_id, + CC_id, + frame_rx, + eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->b, + ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + } else { + ue_decode_si(ue->Mod_id, + CC_id, + frame_rx, + eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->b, + ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + } - } else { - ue_decode_si(ue->Mod_id, - CC_id, - frame_rx, - eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->b, - ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); - } #else - ue_decode_si(ue->Mod_id, + ue_decode_si(ue->Mod_id, CC_id, frame_rx, eNB_id, @@ -4361,228 +4362,70 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); } - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if(is_fembms_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)){ - ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag,1); - return 0; - }else{ // this gets closed at end + + if(is_fembms_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { + ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag,1); + return 0; + } else { // this gets closed at end #endif - - - pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; - - if (do_pdcch_flag) { - // deactivate reception until we scan pdcch - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]) - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0; - - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]) - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0; - - if (ue->dlsch_SI[eNB_id]) - ue->dlsch_SI[eNB_id]->active = 0; - - if (ue->dlsch_p[eNB_id]) - ue->dlsch_p[eNB_id]->active = 0; - - if (ue->dlsch_ra[eNB_id]) - ue->dlsch_ra[eNB_id]->active = 0; - } - - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - ue->Mod_id,frame_rx, subframe_rx); - } - - if (ue->frame_parms.Ncp == 0) { // normal prefix - pilot1 = 4; - } else { // extended prefix - pilot1 = 3; - } - - if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 4; - } else if (pmch_flag == 1) { // do first 2 symbols only - l2 = 1; - } else { // normal subframe, last symbol to be processed is the first of the second slot - l2 = (ue->frame_parms.symbols_per_tti/2)-1; - } - - int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1); - - if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // RX processing of symbols l=0...l2 - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - l=0; - } else { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch) - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - l=1; - } - - LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - - for (; l<=l2; l++) { - if (abstraction_flag == 0) { - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ofdm_demod_stats); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - slot_fep(ue, - l, - (subframe_rx<<1), - 0, - 0, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); - - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ofdm_demod_stats); - } - } - - ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; if (do_pdcch_flag) { - if ((l==pilot1) || - ((pmch_flag==1)&&(l==l2))) { - LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); + // deactivate reception until we scan pdcch + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]) + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0; - //start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); - if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); - return(-1); - } + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]) + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0; - //stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); - //printf("subframe %d n_pdcch_sym %d pdcch procedures %5.3f \n", - // subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - // (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); - LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); - } - } - } // for l=1..l2 + if (ue->dlsch_SI[eNB_id]) + ue->dlsch_SI[eNB_id]->active = 0; - ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); - LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + if (ue->dlsch_p[eNB_id]) + ue->dlsch_p[eNB_id]->active = 0; - // If this is PMCH, call procedures, do channel estimation for first symbol of next DL subframe and return - if (pmch_flag == 1) { - ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -,0 -#endif -); - int next_subframe_rx = (1+subframe_rx)%10; - - if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { - slot_fep(ue, - 0, - (next_subframe_rx<<1), - 0, - 0, - 0); + if (ue->dlsch_ra[eNB_id]) + ue->dlsch_ra[eNB_id]->active = 0; } - return 0; - } + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", + ue->Mod_id,frame_rx, subframe_rx); + } - slot_fep(ue, - 0, - 1+(subframe_rx<<1), - 0, - 0, - 0); + if (ue->frame_parms.Ncp == 0) { // normal prefix + pilot1 = 4; + } else { // extended prefix + pilot1 = 3; + } - // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - } + if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only + l2 = 4; + } else if (pmch_flag == 1) { // do first 2 symbols only + l2 = 1; + } else { // normal subframe, last symbol to be processed is the first of the second slot + l2 = (ue->frame_parms.symbols_per_tti/2)-1; + } - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1); - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->generic_stat); - start_meas(&ue->crnti_procedures_stats); - } + if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) { + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // RX processing of symbols l=0...l2 + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + l=0; + } else { + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch) + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + l=1; + } - // do procedures for C-RNTI - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); - } + LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->crnti_procedures_stats); - } - - LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - - // do procedures for SI-RNTI - if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); - } - - // do procedures for SI-RNTI - if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); - } - - // do procedures for RA-RNTI - if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); - } - - LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - - if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) { // do front-end processing for second slot, and first symbol of next subframe - for (l=1; lframe_parms.symbols_per_tti>>1; l++) { + for (; l<=l2; l++) { if (abstraction_flag == 0) { if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ofdm_demod_stats); @@ -4591,7 +4434,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); slot_fep(ue, l, - 1+(subframe_rx<<1), + (subframe_rx<<1), 0, 0, 0); @@ -4602,174 +4445,330 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, } } - ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); + ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + + if (do_pdcch_flag) { + if ((l==pilot1) || + ((pmch_flag==1)&&(l==l2))) { + LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); + + //start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); + if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { + LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); + return(-1); + } + + //stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); + //printf("subframe %d n_pdcch_sym %d pdcch procedures %5.3f \n", + // subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + // (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); + LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); + } + } } // for l=1..l2 - ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); - // do first symbol of next downlink subframe for channel estimation - int next_subframe_rx = (1+subframe_rx)%10; + ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { - slot_fep(ue, - 0, - (next_subframe_rx<<1), - 0, - 0, - 0); + // If this is PMCH, call procedures, do channel estimation for first symbol of next DL subframe and return + if (pmch_flag == 1) { + ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0 +#endif + ); + int next_subframe_rx = (1+subframe_rx)%10; + + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { + slot_fep(ue, + 0, + (next_subframe_rx<<1), + 0, + 0, + 0); + } + + return 0; } - } // not an S-subframe - if(LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->generic_stat); - LOG_I(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); - } + slot_fep(ue, + 0, + 1+(subframe_rx<<1), + 0, + 0, + 0); - LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } - if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) { - ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); - } - - // do procedures for C-RNTI - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->generic_stat); + start_meas(&ue->crnti_procedures_stats); + } + + // do procedures for C-RNTI + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + } + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->crnti_procedures_stats); } - ue_pdsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + + // do procedures for SI-RNTI + if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); + } + + // do procedures for SI-RNTI + if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); + } + + // do procedures for RA-RNTI + if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); + } + + LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + + if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) { // do front-end processing for second slot, and first symbol of next subframe + for (l=1; lframe_parms.symbols_per_tti>>1; l++) { + if (abstraction_flag == 0) { + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_demod_stats); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); + slot_fep(ue, + l, + 1+(subframe_rx<<1), + 0, + 0, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } + } + + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); + } // for l=1..l2 + + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); + // do first symbol of next downlink subframe for channel estimation + int next_subframe_rx = (1+subframe_rx)%10; + + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { + slot_fep(ue, + 0, + (next_subframe_rx<<1), + 0, + 0, + 0); + } + } // not an S-subframe + + if(LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->generic_stat); + LOG_I(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + } + + LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + + if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) { + ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); + } + + // do procedures for C-RNTI + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } + + ue_pdsch_procedures(ue, + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } + + ue_dlsch_procedures(ue, + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1], + &ue->dlsch_errors[eNB_id], + mode, + abstraction_flag); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + } if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->generic_stat); } - ue_dlsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1], - &ue->dlsch_errors[eNB_id], - mode, - abstraction_flag); - - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - LOG_I(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { + if(subframe_rx==5 && ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20) { + //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); + //LOG_M("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + LOG_M("rxdataF0_current.m", "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1, + 1); + LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + LOG_M("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + AssertFatal (0,""); + } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); - } - - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->generic_stat); - } - - if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { - if(subframe_rx==5 && ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20) { - //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); - //LOG_M("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - LOG_M("rxdataF0_current.m", "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1, - 1); - LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); - LOG_M("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); - //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); - //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); - AssertFatal (0,""); + // do procedures for SI-RNTI + if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { + ue_pdsch_procedures(ue, + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); + ue_dlsch_procedures(ue, + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + &ue->dlsch_SI_errors[eNB_id], + mode, + abstraction_flag); + ue->dlsch_SI[eNB_id]->active = 0; } - } - // do procedures for SI-RNTI - if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { - ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); - ue_dlsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - &ue->dlsch_SI_errors[eNB_id], - mode, - abstraction_flag); - ue->dlsch_SI[eNB_id]->active = 0; - } + // do procedures for P-RNTI + if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { + ue_pdsch_procedures(ue, + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); + ue_dlsch_procedures(ue, + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + &ue->dlsch_p_errors[eNB_id], + mode, + abstraction_flag); + ue->dlsch_p[eNB_id]->active = 0; + } - // do procedures for P-RNTI - if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { - ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); - ue_dlsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - &ue->dlsch_p_errors[eNB_id], - mode, - abstraction_flag); - ue->dlsch_p[eNB_id]->active = 0; - } - - // do procedures for RA-RNTI - if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { - ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); - ue_dlsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - &ue->dlsch_ra_errors[eNB_id], - mode, - abstraction_flag); - ue->dlsch_ra[eNB_id]->active = 0; - } + // do procedures for RA-RNTI + if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { + ue_pdsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); + ue_dlsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + &ue->dlsch_ra_errors[eNB_id], + mode, + abstraction_flag); + ue->dlsch_ra[eNB_id]->active = 0; + } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) } // This commes from feMBMS subframe filtering ! -#endif +#endif // duplicate harq structure uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid; LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 439fdbc281..9c20d59d28 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -143,13 +143,14 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb); // Re13 fields ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; + if (ra->rach_resource_type > 0) { - pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions= pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][ra->pusch_repetition_levels]; - } - else{ - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions=1; + pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions= pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][ra->pusch_repetition_levels]; + } else { + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions=1; } + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_req_body->number_of_pdus++; @@ -273,10 +274,9 @@ void generate_Msg2(module_id_t module_idP, uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe; if (ra->rach_resource_type > 0) { - PUSCH_Rep_Level= *(rrc->configuration.pusch_repetitionLevelCEmodeA_r13[CC_idP]); - } - else { - PUSCH_Rep_Level= 0; + PUSCH_Rep_Level= *(rrc->configuration.pusch_repetitionLevelCEmodeA_r13[CC_idP]); + } else { + PUSCH_Rep_Level= 0; } if (absSF > absSF_Msg2) { @@ -347,9 +347,7 @@ void generate_Msg2(module_id_t module_idP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - LOG_E(MAC, "start_symbol = %d \n", dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI @@ -421,7 +419,7 @@ void generate_Msg2(module_id_t module_idP, } ra->pusch_repetition_levels = PUSCH_Rep_Level; - + if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { /* Program PDSCH */ LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", @@ -913,11 +911,10 @@ generate_Msg4(module_id_t module_idP, ul_req_body->number_of_pdus++; T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_idP), T_INT (ra->rnti), T_INT (frameP), T_INT (subframeP), T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize)); - - trace_pdu (DIRECTION_DOWNLINK, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], - ra->msg4_rrc_sdu_length, - UE_id, 3, UE_RNTI (module_idP, UE_id), - mac->frame, mac->subframe, 0, 0); + trace_pdu (DIRECTION_DOWNLINK, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], + ra->msg4_rrc_sdu_length, + UE_id, 3, UE_RNTI (module_idP, UE_id), + mac->frame, mac->subframe, 0, 0); } // Msg4 frame/subframe } // rach_resource_type > 0 else @@ -979,12 +976,10 @@ generate_Msg4(module_id_t module_idP, 1, // tpc, none getRIV(N_RB_DL, first_rb, 4), // resource_block_coding ra->msg4_mcs, // mcs - 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid], + 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid], 0, // rv 0); // vrb_flag - - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid] = 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid]; - + UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid] = 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid]; LOG_D(MAC, "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n", frameP, subframeP, dl_req_body->number_pdu, @@ -1074,7 +1069,7 @@ generate_Msg4(module_id_t module_idP, mac->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, (frameP * 10) + subframeP, - rrc_sdu_length+offset, + rrc_sdu_length+offset, mac->pdu_index[CC_idP], mac->UE_list. DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); @@ -1094,13 +1089,13 @@ generate_Msg4(module_id_t module_idP, T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ), T_BUFFER(&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id]. payload[0], ra->msg4_TBsize)); - trace_pdu(DIRECTION_DOWNLINK, - (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], - rrc_sdu_length, UE_id, WS_C_RNTI, - UE_RNTI(module_idP, UE_id), mac->frame, - mac->subframe, 0, 0); + (uint8_t *) mac-> + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, WS_C_RNTI, + UE_RNTI(module_idP, UE_id), mac->frame, + mac->subframe, 0, 0); + if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) { set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); } @@ -1211,7 +1206,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, 1, // tpc, none getRIV(N_RB_DL, first_rb, 4), // resource_block_coding ra->msg4_mcs, // mcs - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid], + UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid], round & 3, // rv 0); // vrb_flag diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 51674ae881..fcecc4c77d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -46,7 +46,7 @@ #include "pdcp.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif #define ENABLE_MAC_PAYLOAD_DEBUG @@ -78,223 +78,223 @@ int SIB1_BR_TBS_table[6] = { 208, 256, 328, 504, 712, 936 }; //------------------------------------------------------------------------------ void schedule_SIB1_MBMS(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP) + frame_t frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { #ifdef SCHEDULE_SIB1_MBMS - int8_t bcch_sdu_length; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int first_rb = -1; - int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - nfapi_dl_config_request_body_t *dl_req; - int m, i, N_S_NB; - int *Sj; - int n_NB = 0; - int TBS; - int k = 0, rvidx; - uint16_t sfn_sf = frameP<<4|subframeP; + int8_t bcch_sdu_length; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int first_rb = -1; + int N_RB_DL; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + int m, i, N_S_NB; + int *Sj; + int n_NB = 0; + int TBS; + int k = 0, rvidx; + uint16_t sfn_sf = frameP<<4|subframeP; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + cc = &eNB->common_channels[CC_id]; + vrb_map = (void *) &cc->vrb_map; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + int foffset = cc->physCellId & 1; + int sfoffset = (cc->tdd_Config == NULL) ? 0 : 1; - cc = &eNB->common_channels[CC_id]; - vrb_map = (void *) &cc->vrb_map; - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + // Time-domain scheduling + if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) + continue; + else + switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) { + case 0: // repetition 4 + k = (frameP >> 1) & 3; - int foffset = cc->physCellId & 1; - int sfoffset = (cc->tdd_Config == NULL) ? 0 : 1; + if ((subframeP != (4 + sfoffset)) + || ((frameP & 1) != foffset)) + continue; - // Time-domain scheduling - if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) - continue; - else - switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) { - case 0: // repetition 4 - k = (frameP >> 1) & 3; - if ((subframeP != (4 + sfoffset)) - || ((frameP & 1) != foffset)) - continue; - break; - case 1: // repetition 8 - k = frameP & 3; - AssertFatal(N_RB_DL > 15, - "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n", - N_RB_DL); - if ((foffset == 0) && (subframeP != (4 + sfoffset))) - continue; - else if ((foffset == 1) - && (subframeP != ((9 + sfoffset) % 10))) - continue; - break; - case 2: // repetition 16 - k = ((10 * frameP) + subframeP) & 3; - AssertFatal(N_RB_DL > 15, - "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n", - N_RB_DL); - if ((sfoffset == 1) - && ((subframeP != 0) || (subframeP != 5))) - continue; - else if ((sfoffset == 0) && (foffset == 0) - && (subframeP != 4) && (subframeP != 9)) - continue; - else if ((sfoffset == 0) && (foffset == 1) - && (subframeP != 0) && (subframeP != 9)) - continue; - break; - } - // if we get here we have to schedule SIB1_BR in this frame/subframe + break; - // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit - if ((frameP & 7) == 0) - cc->SIB1_BR_cnt = 0; - else - cc->SIB1_BR_cnt++; + case 1: // repetition 8 + k = frameP & 3; + AssertFatal(N_RB_DL > 15, + "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n", + N_RB_DL); - // Frequency-domain scheduling - switch (N_RB_DL) { - case 6: - case 15: - default: - m = 1; - n_NB = 0; - N_S_NB = 0; - Sj = NULL; - break; - case 25: - m = 2; - N_S_NB = 2; - Sj = Sj25; - break; - case 50: - m = 2; - N_S_NB = 6; - Sj = Sj50; - break; - case 75: - m = 4; - N_S_NB = 10; - Sj = Sj75; - break; - case 100: - m = 4; - N_S_NB = 14; - Sj = Sj100; - break; - } - // Note: definition of k above and rvidx from 36.321 section 5.3.1 - rvidx = (((3 * k) >> 1) + (k & 1)) & 3; + if ((foffset == 0) && (subframeP != (4 + sfoffset))) + continue; + else if ((foffset == 1) + && (subframeP != ((9 + sfoffset) % 10))) + continue; - i = cc->SIB1_BR_cnt & (m - 1); + break; - n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + case 2: // repetition 16 + k = ((10 * frameP) + subframeP) & 3; + AssertFatal(N_RB_DL > 15, + "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n", + N_RB_DL); + if ((sfoffset == 1) + && ((subframeP != 0) || (subframeP != 5))) + continue; + else if ((sfoffset == 0) && (foffset == 0) + && (subframeP != 4) && (subframeP != 9)) + continue; + else if ((sfoffset == 0) && (foffset == 1) + && (subframeP != 0) && (subframeP != 9)) + continue; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case + break; + } - AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, - "schedulingInfoSIB1_BR_r13 %d > 18\n", - (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + // if we get here we have to schedule SIB1_BR in this frame/subframe - AssertFatal(bcch_sdu_length > 0, - "RRC returned 0 bytes for SIB1-BR\n"); + // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit + if ((frameP & 7) == 0) + cc->SIB1_BR_cnt = 0; + else + cc->SIB1_BR_cnt++; - TBS = - SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 - - 1) / 3] >> 3; + // Frequency-domain scheduling + switch (N_RB_DL) { + case 6: + case 15: + default: + m = 1; + n_NB = 0; + N_S_NB = 0; + Sj = NULL; + break; - AssertFatal(bcch_sdu_length <= TBS, - "length returned by RRC %d is not compatible with the TBS %d from MIB\n", - bcch_sdu_length, TBS); + case 25: + m = 2; + N_S_NB = 2; + Sj = Sj25; + break; - if ((frameP & 1023) < 200) - LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n", - module_idP, frameP, subframeP, CC_id, bcch_sdu_length, - n_NB, i, m, N_S_NB, rvidx); + case 50: + m = 2; + N_S_NB = 6; + Sj = Sj50; + break; - // allocate all 6 PRBs in narrowband for SIB1_BR + case 75: + m = 4; + N_S_NB = 10; + Sj = Sj75; + break; - first_rb = narrowband_to_first_rb(cc, n_NB); - - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; - vrb_map[first_rb + 4] = 1; - vrb_map[first_rb + 5] = 1; - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx - - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - // Program TX Request - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = bcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; - eNB->TX_req[CC_id].sfn_sf = sfn_sf; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - - trace_pdu(DIRECTION_DOWNLINK, - &cc->BCCH_BR_pdu[0].payload[0], - bcch_sdu_length, - 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - if (cc->tdd_Config != NULL) { //TDD - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", - frameP, CC_id, bcch_sdu_length); - } else { - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", - frameP, CC_id, bcch_sdu_length); - } + case 100: + m = 4; + N_S_NB = 14; + Sj = Sj100; + break; } + + // Note: definition of k above and rvidx from 36.321 section 5.3.1 + rvidx = (((3 * k) >> 1) + (k & 1)) & 3; + i = cc->SIB1_BR_cnt & (m - 1); + n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case + AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, + "schedulingInfoSIB1_BR_r13 %d > 18\n", + (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + AssertFatal(bcch_sdu_length > 0, + "RRC returned 0 bytes for SIB1-BR\n"); + TBS = + SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 - + 1) / 3] >> 3; + AssertFatal(bcch_sdu_length <= TBS, + "length returned by RRC %d is not compatible with the TBS %d from MIB\n", + bcch_sdu_length, TBS); + + if ((frameP & 1023) < 200) + LOG_D(MAC, + "[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n", + module_idP, frameP, subframeP, CC_id, bcch_sdu_length, + n_NB, i, m, N_S_NB, rvidx); + + // allocate all 6 PRBs in narrowband for SIB1_BR + first_rb = narrowband_to_first_rb(cc, n_NB); + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + vrb_map[first_rb + 4] = 1; + vrb_map[first_rb + 5] = 1; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + // Program TX Request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_BR_pdu[0].payload[0], + bcch_sdu_length, + 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); + + if (cc->tdd_Config != NULL) { //TDD + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", + frameP, CC_id, bcch_sdu_length); + } else { + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", + frameP, CC_id, bcch_sdu_length); + } + } + #endif } @@ -302,222 +302,221 @@ schedule_SIB1_MBMS(module_id_t module_idP, //------------------------------------------------------------------------------ void schedule_SIB1_BR(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP) + frame_t frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int8_t bcch_sdu_length; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int first_rb = -1; - int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - nfapi_dl_config_request_body_t *dl_req; - int m, i, N_S_NB; - int *Sj; - int n_NB = 0; - int TBS; - int k = 0, rvidx; - uint16_t sfn_sf = frameP<<4|subframeP; + int8_t bcch_sdu_length; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int first_rb = -1; + int N_RB_DL; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + int m, i, N_S_NB; + int *Sj; + int n_NB = 0; + int TBS; + int k = 0, rvidx; + uint16_t sfn_sf = frameP<<4|subframeP; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + cc = &eNB->common_channels[CC_id]; + vrb_map = (void *) &cc->vrb_map; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + int foffset = cc->physCellId & 1; + int sfoffset = (cc->tdd_Config == NULL) ? 0 : 1; - cc = &eNB->common_channels[CC_id]; - vrb_map = (void *) &cc->vrb_map; - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + // Time-domain scheduling + if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) + continue; + else + switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) { + case 0: // repetition 4 + k = (frameP >> 1) & 3; - int foffset = cc->physCellId & 1; - int sfoffset = (cc->tdd_Config == NULL) ? 0 : 1; + if ((subframeP != (4 + sfoffset)) + || ((frameP & 1) != foffset)) + continue; - // Time-domain scheduling - if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) - continue; - else - switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) { - case 0: // repetition 4 - k = (frameP >> 1) & 3; - if ((subframeP != (4 + sfoffset)) - || ((frameP & 1) != foffset)) - continue; - break; - case 1: // repetition 8 - k = frameP & 3; - AssertFatal(N_RB_DL > 15, - "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n", - N_RB_DL); - if ((foffset == 0) && (subframeP != (4 + sfoffset))) - continue; - else if ((foffset == 1) - && (subframeP != ((9 + sfoffset) % 10))) - continue; - break; - case 2: // repetition 16 - k = ((10 * frameP) + subframeP) & 3; - AssertFatal(N_RB_DL > 15, - "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n", - N_RB_DL); - if ((sfoffset == 1) - && ((subframeP != 0) || (subframeP != 5))) - continue; - else if ((sfoffset == 0) && (foffset == 0) - && (subframeP != 4) && (subframeP != 9)) - continue; - else if ((sfoffset == 0) && (foffset == 1) - && (subframeP != 0) && (subframeP != 9)) - continue; - break; - } - // if we get here we have to schedule SIB1_BR in this frame/subframe + break; - // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit - if ((frameP & 7) == 0) - cc->SIB1_BR_cnt = 0; - else - cc->SIB1_BR_cnt++; + case 1: // repetition 8 + k = frameP & 3; + AssertFatal(N_RB_DL > 15, + "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n", + N_RB_DL); - // Frequency-domain scheduling - switch (N_RB_DL) { - case 6: - case 15: - default: - m = 1; - n_NB = 0; - N_S_NB = 0; - Sj = NULL; - break; - case 25: - m = 2; - N_S_NB = 2; - Sj = Sj25; - break; - case 50: - m = 2; - N_S_NB = 6; - Sj = Sj50; - break; - case 75: - m = 4; - N_S_NB = 10; - Sj = Sj75; - break; - case 100: - m = 4; - N_S_NB = 14; - Sj = Sj100; - break; - } - // Note: definition of k above and rvidx from 36.321 section 5.3.1 - rvidx = (((3 * k) >> 1) + (k & 1)) & 3; + if ((foffset == 0) && (subframeP != (4 + sfoffset))) + continue; + else if ((foffset == 1) + && (subframeP != ((9 + sfoffset) % 10))) + continue; - i = cc->SIB1_BR_cnt & (m - 1); + break; - n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + case 2: // repetition 16 + k = ((10 * frameP) + subframeP) & 3; + AssertFatal(N_RB_DL > 15, + "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n", + N_RB_DL); + if ((sfoffset == 1) + && ((subframeP != 0) || (subframeP != 5))) + continue; + else if ((sfoffset == 0) && (foffset == 0) + && (subframeP != 4) && (subframeP != 9)) + continue; + else if ((sfoffset == 0) && (foffset == 1) + && (subframeP != 0) && (subframeP != 9)) + continue; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 0xFFFF, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case + break; + } - AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, - "schedulingInfoSIB1_BR_r13 %d > 18\n", - (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + // if we get here we have to schedule SIB1_BR in this frame/subframe - AssertFatal(bcch_sdu_length > 0, - "RRC returned 0 bytes for SIB1-BR\n"); + // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit + if ((frameP & 7) == 0) + cc->SIB1_BR_cnt = 0; + else + cc->SIB1_BR_cnt++; - TBS = - SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 - - 1) / 3] >> 3; + // Frequency-domain scheduling + switch (N_RB_DL) { + case 6: + case 15: + default: + m = 1; + n_NB = 0; + N_S_NB = 0; + Sj = NULL; + break; - AssertFatal(bcch_sdu_length <= TBS, - "length returned by RRC %d is not compatible with the TBS %d from MIB\n", - bcch_sdu_length, TBS); + case 25: + m = 2; + N_S_NB = 2; + Sj = Sj25; + break; - if ((frameP & 1023) < 200) - LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n", - module_idP, frameP, subframeP, CC_id, bcch_sdu_length, - n_NB, i, m, N_S_NB, rvidx); + case 50: + m = 2; + N_S_NB = 6; + Sj = Sj50; + break; - // allocate all 6 PRBs in narrowband for SIB1_BR + case 75: + m = 4; + N_S_NB = 10; + Sj = Sj75; + break; - first_rb = narrowband_to_first_rb(cc, n_NB); - - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; - vrb_map[first_rb + 4] = 1; - vrb_map[first_rb + 5] = 1; - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx - - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - // Program TX Request - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = bcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; - eNB->TX_req[CC_id].sfn_sf = sfn_sf; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - - trace_pdu(DIRECTION_DOWNLINK, - &cc->BCCH_BR_pdu[0].payload[0], - bcch_sdu_length, - 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - if (cc->tdd_Config != NULL) { //TDD - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", - frameP, CC_id, bcch_sdu_length); - } else { - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", - frameP, CC_id, bcch_sdu_length); - } + case 100: + m = 4; + N_S_NB = 14; + Sj = Sj100; + break; } + + // Note: definition of k above and rvidx from 36.321 section 5.3.1 + rvidx = (((3 * k) >> 1) + (k & 1)) & 3; + i = cc->SIB1_BR_cnt & (m - 1); + n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 0xFFFF, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case + AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, + "schedulingInfoSIB1_BR_r13 %d > 18\n", + (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + AssertFatal(bcch_sdu_length > 0, + "RRC returned 0 bytes for SIB1-BR\n"); + TBS = + SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 - + 1) / 3] >> 3; + AssertFatal(bcch_sdu_length <= TBS, + "length returned by RRC %d is not compatible with the TBS %d from MIB\n", + bcch_sdu_length, TBS); + + if ((frameP & 1023) < 200) + LOG_D(MAC, + "[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n", + module_idP, frameP, subframeP, CC_id, bcch_sdu_length, + n_NB, i, m, N_S_NB, rvidx); + + // allocate all 6 PRBs in narrowband for SIB1_BR + first_rb = narrowband_to_first_rb(cc, n_NB); + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + vrb_map[first_rb + 4] = 1; + vrb_map[first_rb + 5] = 1; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + // Program TX Request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_BR_pdu[0].payload[0], + bcch_sdu_length, + 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); + + if (cc->tdd_Config != NULL) { //TDD + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", + frameP, CC_id, bcch_sdu_length); + } else { + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", + frameP, CC_id, bcch_sdu_length); + } + } } int si_WindowLength_BR_r13tab[LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 20, 40, 60, 80, 120, 160, 200 }; @@ -528,7 +527,7 @@ int si_WindowLength_MBMS_r14tab[8] = { 1, 2, 5, 10, 15, 20, 40, 80 }; //------------------------------------------------------------------------------ void schedule_SI_BR(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) + sub_frame_t subframeP) //------------------------------------------------------------------------------ { int8_t bcch_sdu_length; @@ -545,55 +544,48 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, int rvidx; int absSF = (frameP*10)+subframeP; - for (CC_id=0; CC_idcommon_channels[CC_id]; - vrb_map = (void*)&cc->vrb_map; + vrb_map = (void *)&cc->vrb_map; N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; // Time-domain scheduling if (cc->mib->message.schedulingInfoSIB1_BR_r13==0) continue; else { - - AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, - "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - + "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); LTE_SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; AssertFatal(schedulingInfoList_BR_r13!=NULL, - "sib_v13ext->schedulingInfoList_BR_r13 is null\n"); - + "sib_v13ext->schedulingInfoList_BR_r13 is null\n"); LTE_SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; AssertFatal(schedulingInfoList_BR_r13->list.count==schedulingInfoList->list.count, - "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", - schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); - - AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, - "si_WindowLength_BR_r13 %d > %d\n", - (int)cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, - LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); - + "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", + schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<= + LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, + "si_WindowLength_BR_r13 %d > %d\n", + (int)cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, + LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); // check that SI frequency-hopping is disabled - AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13==LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, - "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13== + LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, + "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); long si_WindowLength_BR_r13 = si_WindowLength_BR_r13tab[cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; - long si_RepetitionPattern_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; AssertFatal(si_RepetitionPattern_r13<=LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, - "si_RepetitionPattern_r13 %d > %d\n", - (int)si_RepetitionPattern_r13, - LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); + "si_RepetitionPattern_r13 %d > %d\n", + (int)si_RepetitionPattern_r13, + LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); // cycle through SIB list - for (i=0;ilist.count;i++) { + for (i=0; ilist.count; i++) { long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; - // check if the SI is to be scheduled now int period_in_sf; + if ((si_Periodicity >= 0) && (si_Periodicity < 25)) { // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms period_in_sf = 80 << ((int) si_Periodicity); @@ -602,19 +594,17 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, } else if (si_Periodicity > 24) { period_in_sf = 80 << 24; } + int sf_mod_period = absSF % period_in_sf; int k = sf_mod_period & 3; // Note: definition of k and rvidx from 36.321 section 5.3.1 rvidx = (((3 * k) >> 1) + (k & 1)) & 3; if ((sf_mod_period < si_WindowLength_BR_r13) - && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled - - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 0xFFFF, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 0); // not used in this case - - + && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 0xFFFF, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 0); // not used in this case AssertFatal(bcch_sdu_length > 0, - "RRC returned 0 bytes for SI-BR %d\n", i); + "RRC returned 0 bytes for SI-BR %d\n", i); if (bcch_sdu_length > 0) { AssertFatal(bcch_sdu_length <= (si_TBS_r13 >> 3), @@ -637,23 +627,20 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n", - module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, - sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, - bcch_sdu_length); - + module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, + sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, + bcch_sdu_length); //// Rel10 fields (for PDSCH starting symbol) //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; //// Rel13 fields // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE - //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; - //// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; //dl_req->number_pdu++; // dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; @@ -671,7 +658,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; @@ -686,10 +673,8 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; - - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; - // Program TX Request TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; @@ -698,26 +683,27 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_BR_pdu[i + 1].payload[0], + bcch_sdu_length, + 0xffff, + WS_SI_RNTI, + 0xffff, eNB->frame, eNB->subframe, 0, + 0); - trace_pdu(DIRECTION_DOWNLINK, - &cc->BCCH_BR_pdu[i + 1].payload[0], - bcch_sdu_length, - 0xffff, - WS_SI_RNTI, - 0xffff, eNB->frame, eNB->subframe, 0, - 0); - if (cc->tdd_Config != NULL) { //TDD - LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n", - frameP, i, CC_id, bcch_sdu_length); + if (cc->tdd_Config != NULL) { //TDD + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n", + frameP, i, CC_id, bcch_sdu_length); } else { - LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n", - frameP, i, CC_id, bcch_sdu_length); + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n", + frameP, i, CC_id, bcch_sdu_length); } } - } // scheduling in current frame/subframe - } //for SI List - } // eMTC is activated - } // CC_id + } // scheduling in current frame/subframe + } //for SI List + } // eMTC is activated + } // CC_id + return; } @@ -725,294 +711,274 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, //------------------------------------------------------------------------------ void schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) + sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int8_t bcch_sdu_length; - int mcs = -1; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int first_rb = -1; - int N_RB_DL; - nfapi_dl_config_request_t *dl_config_request; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - nfapi_dl_config_request_body_t *dl_req; - uint16_t sfn_sf = frameP << 4 | subframeP; + int8_t bcch_sdu_length; + int mcs = -1; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int first_rb = -1; + int N_RB_DL; + nfapi_dl_config_request_t *dl_config_request; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; + start_meas(&eNB->schedule_si_mbms); - start_meas(&eNB->schedule_si_mbms); + // Only schedule LTE System Information in subframe 0 + if (subframeP == 0) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + cc = &eNB->common_channels[CC_id]; + vrb_map = (void *) &cc->vrb_map; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_MBMS,0xFFFF, 1, &cc->BCCH_MBMS_pdu.payload[0], 0); // not used in this case - // Only schedule LTE System Information in subframe 0 - if (subframeP == 0) { + if (bcch_sdu_length > 0) { + LOG_D(MAC, "[eNB %d] Frame %d : BCCH-MBMS->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + // Allocate 4 PRBs in a random location + /* + while (1) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4)); + if ((vrb_map[first_rb] != 1) && + (vrb_map[first_rb+1] != 1) && + (vrb_map[first_rb+2] != 1) && + (vrb_map[first_rb+3] != 1)) + break; + } + */ + switch (N_RB_DL) { + case 6: + first_rb = 0; + break; - cc = &eNB->common_channels[CC_id]; - vrb_map = (void *) &cc->vrb_map; - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - dl_config_request = &eNB->DL_req[CC_id]; - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + case 15: + first_rb = 6; + break; + case 25: + first_rb = 11; + break; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_MBMS,0xFFFF, 1, &cc->BCCH_MBMS_pdu.payload[0], 0); // not used in this case + case 50: + first_rb = 23; + break; - if (bcch_sdu_length > 0) { - LOG_D(MAC, "[eNB %d] Frame %d : BCCH-MBMS->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); + case 100: + first_rb = 48; + break; + } - // Allocate 4 PRBs in a random location - /* - while (1) { - first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4)); - if ((vrb_map[first_rb] != 1) && - (vrb_map[first_rb+1] != 1) && - (vrb_map[first_rb+2] != 1) && - (vrb_map[first_rb+3] != 1)) - break; - } - */ - switch (N_RB_DL) { - case 6: - first_rb = 0; - break; - case 15: - first_rb = 6; - break; - case 25: - first_rb = 11; - break; - case 50: - first_rb = 23; - break; - case 100: - first_rb = 48; - break; - } + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; + // Get MCS for length of SI, 3 PRBs + if (bcch_sdu_length <= 7) { + mcs = 0; + } else if (bcch_sdu_length <= 11) { + mcs = 1; + } else if (bcch_sdu_length <= 18) { + mcs = 2; + } else if (bcch_sdu_length <= 22) { + mcs = 3; + } else if (bcch_sdu_length <= 26) { + mcs = 4; + } else if (bcch_sdu_length <= 28) { + mcs = 5; + } else if (bcch_sdu_length <= 32) { + mcs = 6; + } else if (bcch_sdu_length <= 41) { + mcs = 7; + } else if (bcch_sdu_length <= 49) { + mcs = 8; + } - // Get MCS for length of SI, 3 PRBs - if (bcch_sdu_length <= 7) { - mcs = 0; - } else if (bcch_sdu_length <= 11) { - mcs = 1; - } else if (bcch_sdu_length <= 18) { - mcs = 2; - } else if (bcch_sdu_length <= 22) { - mcs = 3; - } else if (bcch_sdu_length <= 26) { - mcs = 4; - } else if (bcch_sdu_length <= 28) { - mcs = 5; - } else if (bcch_sdu_length <= 32) { - mcs = 6; - } else if (bcch_sdu_length <= 41) { - mcs = 7; - } else if (bcch_sdu_length <= 49) { - mcs = 8; - } + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_request->sfn_sf = sfn_sf; + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { + LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI MBMS\n", frameP, subframeP); + dl_req->number_dci++; + dl_req->number_pdu++; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + // Program TX Request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_MBMS_pdu.payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + } else { + LOG_E(MAC, + "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI MBMS\n", + module_idP, CC_id, frameP, subframeP); + } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), + T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_MBMS_pdu.payload, bcch_sdu_length)); + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_MBMS_pdu.payload[0], + bcch_sdu_length, + 0xffff, + WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + if (0/*cc->tdd_Config != NULL*/) { //TDD not for FeMBMS + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", + frameP, CC_id, bcch_sdu_length, mcs); + } else { + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-MBMS->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); + } - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_request->sfn_sf = sfn_sf; - - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { - LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI MBMS\n", frameP, subframeP); - dl_req->number_dci++; - dl_req->number_pdu++; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF - - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; - - // Program TX Request - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = bcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = cc->BCCH_MBMS_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - eNB->TX_req[CC_id].sfn_sf = sfn_sf; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - - } else { - LOG_E(MAC, - "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI MBMS\n", - module_idP, CC_id, frameP, subframeP); - } - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), - T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_MBMS_pdu.payload, bcch_sdu_length)); - - trace_pdu(DIRECTION_DOWNLINK, - &cc->BCCH_MBMS_pdu.payload[0], - bcch_sdu_length, - 0xffff, - WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - if (0/*cc->tdd_Config != NULL*/) { //TDD not for FeMBMS - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", - frameP, CC_id, bcch_sdu_length, mcs); - } else { - LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-MBMS->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); - } - - - eNB->eNB_stats[CC_id].total_num_bcch_pdu += 1; - eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; - eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; - eNB->eNB_stats[CC_id].bcch_mcs = mcs; -//printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////****************************** - } else { - - //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); - } - } + eNB->eNB_stats[CC_id].total_num_bcch_pdu += 1; + eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; + eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; + eNB->eNB_stats[CC_id].bcch_mcs = mcs; + //printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////****************************** + } else { + //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); + } } + } + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - //schedule_SIB1_BR(module_idP, frameP, subframeP); - //schedule_SI_BR(module_idP, frameP, subframeP); + //schedule_SIB1_BR(module_idP, frameP, subframeP); + //schedule_SI_BR(module_idP, frameP, subframeP); #endif - stop_meas(&eNB->schedule_si_mbms); - - } #endif void -schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) -{ - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - int mib_sdu_length; - int CC_id; - nfapi_dl_config_request_t *dl_config_request; - nfapi_dl_config_request_body_t *dl_req; - uint16_t sfn_sf = frameP << 4 | subframeP; +schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + int mib_sdu_length; + int CC_id; + nfapi_dl_config_request_t *dl_config_request; + nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; + AssertFatal(subframeP == 0, "Subframe must be 0\n"); + AssertFatal((frameP & 3) == 0, "Frame must be a multiple of 4\n"); - AssertFatal(subframeP == 0, "Subframe must be 0\n"); - AssertFatal((frameP & 3) == 0, "Frame must be a multiple of 4\n"); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &dl_config_request->dl_config_request_body; + cc = &eNB->common_channels[CC_id]; + mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 0xFFFF, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case + LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if (mib_sdu_length > 0) { + LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); - dl_config_request = &eNB->DL_req[CC_id]; - dl_req = &dl_config_request->dl_config_request_body; - cc = &eNB->common_channels[CC_id]; - - mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 0xFFFF, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case - - LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length); - - if (mib_sdu_length > 0) { - - LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); - - if ((frameP & 1023) < 40) + if ((frameP & 1023) < 40) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LOG_D(MAC, - "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n", - module_idP, frameP, CC_id, mib_sdu_length, - (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + LOG_D(MAC, + "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n", + module_idP, frameP, CC_id, mib_sdu_length, + (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + #else - LOG_D(MAC, - "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", - module_idP, frameP, CC_id, mib_sdu_length); + LOG_D(MAC, + "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", + module_idP, frameP, CC_id, mib_sdu_length); #endif - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = - 2 + sizeof(nfapi_dl_config_bch_pdu); - dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; - dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; - dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dl_req->number_pdu++; - - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; - - LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); - // DL request - - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 3; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 3; - TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - eNB->TX_req[CC_id].sfn_sf = sfn_sf; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - } + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = + 2 + sizeof(nfapi_dl_config_bch_pdu); + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; + dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_req->number_pdu++; + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); + // DL request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 3; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 3; + TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; } + } } @@ -1021,218 +987,207 @@ void schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { + int8_t bcch_sdu_length; + int mcs = -1; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int first_rb = -1; + int N_RB_DL; + nfapi_dl_config_request_t *dl_config_request; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; + start_meas(&eNB->schedule_si); - int8_t bcch_sdu_length; - int mcs = -1; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int first_rb = -1; - int N_RB_DL; - nfapi_dl_config_request_t *dl_config_request; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - nfapi_dl_config_request_body_t *dl_req; - uint16_t sfn_sf = frameP << 4 | subframeP; + // Only schedule LTE System Information in subframe 5 + if (subframeP == 5) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + cc = &eNB->common_channels[CC_id]; + vrb_map = (void *) &cc->vrb_map; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 0xFFFF,1, &cc->BCCH_pdu.payload[0], 0); // not used in this case - start_meas(&eNB->schedule_si); + if (bcch_sdu_length > 0) { + LOG_D(MAC, "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); - // Only schedule LTE System Information in subframe 5 - if (subframeP == 5) { + // Allocate 4 PRBs in a random location + /* + while (1) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4)); + if ((vrb_map[first_rb] != 1) && + (vrb_map[first_rb+1] != 1) && + (vrb_map[first_rb+2] != 1) && + (vrb_map[first_rb+3] != 1)) + break; + } + */ + switch (N_RB_DL) { + case 6: + first_rb = 0; + break; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + case 15: + first_rb = 6; + break; - cc = &eNB->common_channels[CC_id]; - vrb_map = (void *) &cc->vrb_map; - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - dl_config_request = &eNB->DL_req[CC_id]; - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + case 25: + first_rb = 11; + break; + case 50: + first_rb = 23; + break; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 0xFFFF,1, &cc->BCCH_pdu.payload[0], 0); // not used in this case + case 100: + first_rb = 48; + break; + } - if (bcch_sdu_length > 0) { - LOG_D(MAC, "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; - // Allocate 4 PRBs in a random location - /* - while (1) { - first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4)); - if ((vrb_map[first_rb] != 1) && - (vrb_map[first_rb+1] != 1) && - (vrb_map[first_rb+2] != 1) && - (vrb_map[first_rb+3] != 1)) - break; - } - */ - switch (N_RB_DL) { - case 6: - first_rb = 0; - break; - case 15: - first_rb = 6; - break; - case 25: - first_rb = 11; - break; - case 50: - first_rb = 23; - break; - case 100: - first_rb = 48; - break; - } + // Get MCS for length of SI, 3 PRBs + if (bcch_sdu_length <= 7) { + mcs = 0; + } else if (bcch_sdu_length <= 11) { + mcs = 1; + } else if (bcch_sdu_length <= 18) { + mcs = 2; + } else if (bcch_sdu_length <= 22) { + mcs = 3; + } else if (bcch_sdu_length <= 26) { + mcs = 4; + } else if (bcch_sdu_length <= 28) { + mcs = 5; + } else if (bcch_sdu_length <= 32) { + mcs = 6; + } else if (bcch_sdu_length <= 41) { + mcs = 7; + } else if (bcch_sdu_length <= 49) { + mcs = 8; + } else if (bcch_sdu_length <= 59) { + mcs = 9; + } else AssertFatal(1==0,"Cannot Assign mcs for bcch_sdu_length %d (max mcs 9)\n",bcch_sdu_length); - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_request->sfn_sf = sfn_sf; - // Get MCS for length of SI, 3 PRBs - if (bcch_sdu_length <= 7) { - mcs = 0; - } else if (bcch_sdu_length <= 11) { - mcs = 1; - } else if (bcch_sdu_length <= 18) { - mcs = 2; - } else if (bcch_sdu_length <= 22) { - mcs = 3; - } else if (bcch_sdu_length <= 26) { - mcs = 4; - } else if (bcch_sdu_length <= 28) { - mcs = 5; - } else if (bcch_sdu_length <= 32) { - mcs = 6; - } else if (bcch_sdu_length <= 41) { - mcs = 7; - } else if (bcch_sdu_length <= 49) { - mcs = 8; - } else if (bcch_sdu_length <= 59) { - mcs = 9; - } - else AssertFatal(1==0,"Cannot Assign mcs for bcch_sdu_length %d (max mcs 9)\n",bcch_sdu_length); + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { + LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP); + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + // Program TX Request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + } else { + LOG_E(MAC, + "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n", + module_idP, CC_id, frameP, subframeP); + } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), + T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_pdu.payload, bcch_sdu_length)); + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_pdu.payload[0], + bcch_sdu_length, + 0xffff, + WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + if (cc->tdd_Config != NULL) { //TDD + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", + frameP, CC_id, bcch_sdu_length, mcs); + } else { + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); + } - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_request->sfn_sf = sfn_sf; - - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { - LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP); - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF - - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; - - // Program TX Request - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = bcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - eNB->TX_req[CC_id].sfn_sf = sfn_sf; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - - } else { - LOG_E(MAC, - "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n", - module_idP, CC_id, frameP, subframeP); - } - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), - T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_pdu.payload, bcch_sdu_length)); - - trace_pdu(DIRECTION_DOWNLINK, - &cc->BCCH_pdu.payload[0], - bcch_sdu_length, - 0xffff, - WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); - if (cc->tdd_Config != NULL) { //TDD - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", - frameP, CC_id, bcch_sdu_length, mcs); - } else { - LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); - } - - - eNB->eNB_stats[CC_id].total_num_bcch_pdu += 1; - eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; - eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; - eNB->eNB_stats[CC_id].bcch_mcs = mcs; -//printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////****************************** - } else { - - //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); - } - } + eNB->eNB_stats[CC_id].total_num_bcch_pdu += 1; + eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; + eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; + eNB->eNB_stats[CC_id].bcch_mcs = mcs; + //printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////****************************** + } else { + //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); + } } -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - schedule_SIB1_BR(module_idP, frameP, subframeP); - schedule_SI_BR(module_idP, frameP, subframeP); -#endif + } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + schedule_SIB1_BR(module_idP, frameP, subframeP); + schedule_SI_BR(module_idP, frameP, subframeP); +#endif stop_meas(&eNB->schedule_si); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 3080b4153a..6ce7d85ac9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -565,7 +565,6 @@ schedule_ue_spec(module_id_t module_idP, dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth; N_RB_DL[CC_id] = to_prb(dl_Bandwidth); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - // get number of PRBs less those used by common channels total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; @@ -622,7 +621,6 @@ schedule_ue_spec(module_id_t module_idP, LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", CC_id, UE_id); - continue_flag = 0; // reset the flag to allow allocation for the remaining UEs rnti = UE_RNTI(module_idP, UE_id); ue_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; @@ -776,7 +774,8 @@ schedule_ue_spec(module_id_t module_idP, if (ue_sched_ctrl->cdrx_configured) { ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission - /* + + /* * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop. */ if (harq_pid == 0) { @@ -1011,9 +1010,10 @@ schedule_ue_spec(module_id_t module_idP, ); if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { - while(pthread_mutex_trylock(&rrc_release_freelist)){ + while(pthread_mutex_trylock(&rrc_release_freelist)) { /* spin... */ } + uint16_t release_total = 0; for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0]; @@ -1060,10 +1060,10 @@ schedule_ue_spec(module_id_t module_idP, if(release_total >= rrc_release_info.num_UEs) break; } + pthread_mutex_unlock(&rrc_release_freelist); } - for (ra_ii = 0, ra = &eNB->common_channels[CC_id].ra[0]; ra_ii < NB_RA_PROC_MAX; ra_ii++, ra++) { if ((ra->rnti == rnti) && (ra->state == MSGCRNTI)) { for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { @@ -1254,7 +1254,6 @@ schedule_ue_spec(module_id_t module_idP, header_length_total += header_length_last; num_sdus++; ue_sched_ctrl->uplane_inactivity_timer = 0; - // reset RRC inactivity timer after uplane activity ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); @@ -1422,18 +1421,17 @@ schedule_ue_spec(module_id_t module_idP, dlsch_pdu->payload[0][offset + sdu_length_total + j] = 0; } - trace_pdu(DIRECTION_DOWNLINK, - (uint8_t *) dlsch_pdu->payload[0], - TBS, - module_idP, - WS_C_RNTI, - UE_RNTI(module_idP, - UE_id), - eNB->frame, - eNB->subframe, - 0, - 0); - + trace_pdu(DIRECTION_DOWNLINK, + (uint8_t *) dlsch_pdu->payload[0], + TBS, + module_idP, + WS_C_RNTI, + UE_RNTI(module_idP, + UE_id), + eNB->frame, + eNB->subframe, + 0, + 0); T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), @@ -1569,17 +1567,17 @@ schedule_ue_spec(module_id_t module_idP, dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - /* CDRX */ ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer if (ue_sched_ctrl->cdrx_configured) { ue_sched_ctrl->drx_inactivity_timer = 1; // restart drx inactivity timer when new transmission ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission - /* + /* * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop. */ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) ue_sched_ctrl->drx_inactivity_timer); + if (harq_pid == 0) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]); } @@ -2337,16 +2335,15 @@ schedule_ue_spec_br(module_id_t module_idP, } trace_pdu(DIRECTION_DOWNLINK, - (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, - module_idP, - 3, - UE_RNTI(module_idP,UE_id), - mac->frame, - mac->subframe, - 0, - 0); - + (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, + module_idP, + 3, + UE_RNTI(module_idP,UE_id), + mac->frame, + mac->subframe, + 0, + 0); T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), @@ -2539,17 +2536,16 @@ schedule_ue_spec_br(module_id_t module_idP, T_INT (subframeP), T_INT (0 /* harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length)); - - trace_pdu(1, - (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], - TX_req->pdu_length, - UE_id, - 3, - rnti, - frameP, - subframeP, - 0, - 0); + trace_pdu(1, + (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], + TX_req->pdu_length, + UE_id, + 3, + rnti, + frameP, + subframeP, + 0, + 0); } // end else if ((subframeP == 7) && (round_DL < 8)) } // end loop on UE_id } @@ -3064,8 +3060,8 @@ schedule_PCH(module_id_t module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif @@ -3155,17 +3151,16 @@ schedule_PCH(module_id_t module_idP, continue; } - trace_pdu(DIRECTION_DOWNLINK, - &eNB->common_channels[CC_id].PCCH_pdu.payload[0], - pcch_sdu_length, - 0xffff, - PCCH, - P_RNTI, - eNB->frame, - eNB->subframe, - 0, - 0); - + trace_pdu(DIRECTION_DOWNLINK, + &eNB->common_channels[CC_id].PCCH_pdu.payload[0], + pcch_sdu_length, + 0xffff, + PCCH, + P_RNTI, + eNB->frame, + eNB->subframe, + 0, + 0); eNB->eNB_stats[CC_id].total_num_pcch_pdu++; eNB->eNB_stats[CC_id].pcch_buffer = pcch_sdu_length; eNB->eNB_stats[CC_id].total_pcch_buffer += pcch_sdu_length; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index a837f3edf4..5b4eca635c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -644,16 +644,18 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, // Get total available RBS count and total UE count N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); temp_total_rbs_count = 0; - for(uint8_t rbg_i = 0;rbg_i < N_RBG[CC_id];rbg_i++ ){ - if(rballoc_sub[CC_id][rbg_i] == 0){ + + for(uint8_t rbg_i = 0; rbg_i < N_RBG[CC_id]; rbg_i++ ) { + if(rballoc_sub[CC_id][rbg_i] == 0) { if((rbg_i == N_RBG[CC_id] -1) && - ((N_RB_DL == 25) || (N_RB_DL == 50))){ + ((N_RB_DL == 25) || (N_RB_DL == 50))) { temp_total_rbs_count += (min_rb_unit[CC_id] -1); - }else{ + } else { temp_total_rbs_count += min_rb_unit[CC_id]; } } } + temp_total_ue_count = dlsch_ue_select[CC_id].ue_num; for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { @@ -1305,10 +1307,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, #endif ); - if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){ + if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { while(pthread_mutex_trylock(&rrc_release_freelist)) { /* spin... */ } + uint16_t release_total = 0; for(uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { @@ -1345,6 +1348,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, if(release_total >= rrc_release_info.num_UEs) break; } + pthread_mutex_unlock(&rrc_release_freelist); } @@ -1703,10 +1707,9 @@ schedule_ue_spec_fairRR(module_id_t module_idP, UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); } - trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id), - eNB->frame, eNB->subframe,0,0); - + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id), + eNB->frame, eNB->subframe,0,0); T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; @@ -2048,6 +2051,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; continue; @@ -2126,7 +2130,8 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; rnti = UE_RNTI(module_idP,first_ue_id[CC_id][temp]); - aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[first_ue_id[CC_id][temp]].dl_cqi[CC_id],format0); + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[first_ue_id[CC_id][temp]].dl_cqi[CC_id],format0); + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; break; @@ -2199,6 +2204,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; continue; @@ -2252,6 +2258,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( format_flag = 2; rnti = UE_RNTI(module_idP,ul_inactivity_id[CC_id][temp]); aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[ul_inactivity_id[CC_id][temp]].dl_cqi[CC_id],format0); + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; continue; @@ -2450,20 +2457,20 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } } else { - if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED){ + if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { // assigne RBS( 6 RBs) first_rb[CC_id] = first_rb[CC_id] + 6; UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 6; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 5; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; - }else{ + } else { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; } - } + } } else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE ) { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; @@ -2762,7 +2769,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; harq_pid = subframe2harqpid(cc,sched_frame,sched_subframeP); rnti = UE_RNTI(CC_id,UE_id); - aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; @@ -3043,7 +3050,6 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d)\n", module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs_rv,first_rb[CC_id],ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb,UE_template->TBS_UL[harq_pid],harq_pid); - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) //store for possible retransmission UE_template->nb_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index a8191f3abb..455ca10eca 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -48,10 +48,10 @@ #include "assertions.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif -#include "SIMULATION/TOOLS/sim.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 @@ -62,749 +62,729 @@ extern RAN_CONTEXT_t RC; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int8_t get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, - uint8_t mbsfn_sync_area) -{ - // currently there is one-to-one mapping between sf allocation pattern and sync area - if (mbsfn_sync_area >= MAX_MBSFN_AREA) { - LOG_W(MAC, - "[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ", - module_idP, CC_id, mbsfn_sync_area); - return -1; - } else if (RC.mac[module_idP]-> - common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] - != NULL) { - return mbsfn_sync_area; - } else { - LOG_W(MAC, - "[eNB %d] CC_id %d MBSFN Subframe Config pattern %d not found \n ", - module_idP, CC_id, mbsfn_sync_area); - return -1; - } + uint8_t mbsfn_sync_area) { + // currently there is one-to-one mapping between sf allocation pattern and sync area + if (mbsfn_sync_area >= MAX_MBSFN_AREA) { + LOG_W(MAC, + "[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ", + module_idP, CC_id, mbsfn_sync_area); + return -1; + } else if (RC.mac[module_idP]-> + common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] + != NULL) { + return mbsfn_sync_area; + } else { + LOG_W(MAC, + "[eNB %d] CC_id %d MBSFN Subframe Config pattern %d not found \n ", + module_idP, CC_id, mbsfn_sync_area); + return -1; + } } int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, - sub_frame_t subframeP) -{ + sub_frame_t subframeP) { + int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; + int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); + int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + int mch_scheduling_period = + 8 << (RC.mac[module_idP]->common_channels[CC_id]. + pmch_Config[0]->mch_SchedulingPeriod_r9); + unsigned char mcch_sdu_length; + unsigned char header_len_mcch = 0, header_len_msi = + 0, header_len_mtch = 0, header_len_mtch_temp = + 0, header_len_mcch_temp = 0, header_len_msi_temp = 0; + int ii = 0, msi_pos = 0; + int mcch_mcs = -1; + uint16_t TBS, j = -1, padding = 0, post_padding = 0; + mac_rlc_status_resp_t rlc_status; + int num_mtch; + int msi_length, i, k; + unsigned char sdu_lcids[11], num_sdus = 0, offset = 0; + uint16_t sdu_lengths[11], sdu_length_total = 0; + unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; + cc->MCH_pdu.Pdu_size = 0; - int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; - int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); - int mch_scheduling_period = - 8 << (RC.mac[module_idP]->common_channels[CC_id]. - pmch_Config[0]->mch_SchedulingPeriod_r9); - unsigned char mcch_sdu_length; - unsigned char header_len_mcch = 0, header_len_msi = - 0, header_len_mtch = 0, header_len_mtch_temp = - 0, header_len_mcch_temp = 0, header_len_msi_temp = 0; - int ii = 0, msi_pos = 0; - int mcch_mcs = -1; - uint16_t TBS, j = -1, padding = 0, post_padding = 0; - mac_rlc_status_resp_t rlc_status; - int num_mtch; - int msi_length, i, k; - unsigned char sdu_lcids[11], num_sdus = 0, offset = 0; - uint16_t sdu_lengths[11], sdu_length_total = 0; - unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only - - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; - - cc->MCH_pdu.Pdu_size = 0; - - for (i = 0; i < cc->num_active_mbsfn_area; i++) { - // assume, that there is always a mapping - if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) { - return 0; - } - - mbsfn_period = - 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); - mcch_period = - 32 << (cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_RepetitionPeriod_r9); - msi_pos = 0; - ii = 0; - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n", - module_idP, CC_id, frameP, subframeP, i, - cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern, - mbsfn_period, mcch_period); - - - switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { - case 0: - mcch_mcs = 2; - break; - - case 1: - mcch_mcs = 7; - break; - - case 2: - mcch_mcs = 13; - break; - - case 3: - mcch_mcs = 19; - break; - } - - // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) - if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP - if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format - - // Find the first subframeP in this MCH to transmit MSI - if (frameP % mch_scheduling_period == - cc->mbsfn_SubframeConfig[j]-> - radioframeAllocationOffset) { - while (ii == 0) { - ii = cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & (0x80 >> msi_pos); - msi_pos++; - } - - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", - module_idP, CC_id, frameP, subframeP, i, j, - cc->mbsfn_SubframeConfig[j]-> - subframeAllocation.choice.oneFrame.buf[0], - msi_pos); - } - // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 - switch (subframeP) { - case 1: - if (cc->tdd_Config == NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == - MBSFN_FDD_SF1) { - if (msi_pos == 1) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF1) == - MBSFN_FDD_SF1)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 2: - if (cc->tdd_Config == NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == - MBSFN_FDD_SF2) { - if (msi_pos == 2) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF2) == - MBSFN_FDD_SF2)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 3: - if (cc->tdd_Config != NULL) { // TDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == - MBSFN_TDD_SF3) { - if (msi_pos == 1) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF3) == - MBSFN_TDD_SF3)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } else { // FDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == - MBSFN_FDD_SF3) { - if (msi_pos == 3) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF3) == - MBSFN_FDD_SF3)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 4: - if (cc->tdd_Config != NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == - MBSFN_TDD_SF4) { - if (msi_pos == 2) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF4) == - MBSFN_TDD_SF4)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 6: - if (cc->tdd_Config == NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == - MBSFN_FDD_SF6) { - if (msi_pos == 4) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF6) == - MBSFN_FDD_SF6)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 7: - if (cc->tdd_Config != NULL) { // TDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == - MBSFN_TDD_SF7) { - if (msi_pos == 3) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF7) == - MBSFN_TDD_SF7)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } else { // FDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == - MBSFN_FDD_SF7) { - if (msi_pos == 5) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF7) == - MBSFN_FDD_SF7)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 8: - if (cc->tdd_Config != NULL) { //TDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == - MBSFN_TDD_SF8) { - if (msi_pos == 4) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF8) == - MBSFN_TDD_SF8)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } else { // FDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == - MBSFN_FDD_SF8) { - if (msi_pos == 6) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF8) == - MBSFN_FDD_SF8)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 9: - if (cc->tdd_Config != NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == - MBSFN_TDD_SF9) { - if (msi_pos == 5) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF9) == - MBSFN_TDD_SF9)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - } // end switch - - // sf allocation is non-overlapping - if ((msi_flag == 1) || (mcch_flag == 1) - || (mtch_flag == 1)) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", - module_idP, CC_id, frameP, subframeP, i, j, - msi_flag, mcch_flag, mtch_flag); - break; - } - } else { // four-frameP format - } - } - } // end of for loop - - cc->msi_active = 0; - cc->mcch_active = 0; - cc->mtch_active = 0; - - // Calculate the mcs - if ((msi_flag == 1) || (mcch_flag == 1)) { - cc->MCH_pdu.mcs = mcch_mcs; - } else if (mtch_flag == 1) { // only MTCH in this subframeP - cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; + for (i = 0; i < cc->num_active_mbsfn_area; i++) { + // assume, that there is always a mapping + if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) { + return 0; } - // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC - // there is MSI (MCH Scheduling Info) - if (msi_flag == 1) { - // Create MSI here - uint16_t msi_control_element[29], *msi_ptr; + mbsfn_period = + 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); + mcch_period = + 32 << (cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_RepetitionPeriod_r9); + msi_pos = 0; + ii = 0; + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n", + module_idP, CC_id, frameP, subframeP, i, + cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern, + mbsfn_period, mcch_period); - msi_ptr = &msi_control_element[0]; - ((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH + switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; - if (mcch_flag == 1) { - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; - } else { // no mcch for this MSP - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047 - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; - } + case 1: + mcch_mcs = 7; + break; - msi_ptr += sizeof(MSI_ELEMENT); + case 2: + mcch_mcs = 13; + break; - //Header for MTCHs - num_mtch = cc->mbms_SessionList[0]->list.count; - - for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment - ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; - msi_ptr += sizeof(MSI_ELEMENT); - } - - msi_length = msi_ptr - msi_control_element; - - if (msi_length < 128) { - header_len_msi = 2; - } else { - header_len_msi = 3; - } - - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes \n", - module_idP, CC_id, frameP, msi_length); - //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" ); - - // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length); - // Store MSI data to mch_buffer[0] - memcpy((char *) &mch_buffer[sdu_length_total], - msi_control_element, msi_length); - - sdu_lcids[num_sdus] = MCH_SCHDL_INFO; - sdu_lengths[num_sdus] = msi_length; - sdu_length_total += sdu_lengths[num_sdus]; - LOG_I(MAC, "[eNB %d] CC_id %d Create %d bytes for MSI\n", - module_idP, CC_id, sdu_lengths[num_sdus]); - num_sdus++; - cc->msi_active = 1; + case 3: + mcch_mcs = 19; + break; } - // there is MCCH + + // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) + if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP + if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + + // Find the first subframeP in this MCH to transmit MSI + if (frameP % mch_scheduling_period == + cc->mbsfn_SubframeConfig[j]-> + radioframeAllocationOffset) { + while (ii == 0) { + ii = cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & (0x80 >> msi_pos); + msi_pos++; + } + + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", + module_idP, CC_id, frameP, subframeP, i, j, + cc->mbsfn_SubframeConfig[j]-> + subframeAllocation.choice.oneFrame.buf[0], + msi_pos); + } + + // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframeP) { + case 1: + if (cc->tdd_Config == NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == + MBSFN_FDD_SF1) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF1) == + MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 2: + if (cc->tdd_Config == NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == + MBSFN_FDD_SF2) { + if (msi_pos == 2) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF2) == + MBSFN_FDD_SF2)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 3: + if (cc->tdd_Config != NULL) { // TDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == + MBSFN_TDD_SF3) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF3) == + MBSFN_TDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } else { // FDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == + MBSFN_FDD_SF3) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF3) == + MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 4: + if (cc->tdd_Config != NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == + MBSFN_TDD_SF4) { + if (msi_pos == 2) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF4) == + MBSFN_TDD_SF4)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 6: + if (cc->tdd_Config == NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == + MBSFN_FDD_SF6) { + if (msi_pos == 4) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF6) == + MBSFN_FDD_SF6)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 7: + if (cc->tdd_Config != NULL) { // TDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == + MBSFN_TDD_SF7) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF7) == + MBSFN_TDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } else { // FDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == + MBSFN_FDD_SF7) { + if (msi_pos == 5) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF7) == + MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 8: + if (cc->tdd_Config != NULL) { //TDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == + MBSFN_TDD_SF8) { + if (msi_pos == 4) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF8) == + MBSFN_TDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } else { // FDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == + MBSFN_FDD_SF8) { + if (msi_pos == 6) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF8) == + MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 9: + if (cc->tdd_Config != NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == + MBSFN_TDD_SF9) { + if (msi_pos == 5) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF9) == + MBSFN_TDD_SF9)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + } // end switch + + // sf allocation is non-overlapping + if ((msi_flag == 1) || (mcch_flag == 1) + || (mtch_flag == 1)) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + module_idP, CC_id, frameP, subframeP, i, j, + msi_flag, mcch_flag, mtch_flag); + break; + } + } else { // four-frameP format + } + } + } // end of for loop + + cc->msi_active = 0; + cc->mcch_active = 0; + cc->mtch_active = 0; + + // Calculate the mcs + if ((msi_flag == 1) || (mcch_flag == 1)) { + cc->MCH_pdu.mcs = mcch_mcs; + } else if (mtch_flag == 1) { // only MTCH in this subframeP + cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; + } + + // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC + + // there is MSI (MCH Scheduling Info) + if (msi_flag == 1) { + // Create MSI here + uint16_t msi_control_element[29], *msi_ptr; + msi_ptr = &msi_control_element[0]; + ((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH + if (mcch_flag == 1) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", - module_idP, CC_id, frameP, subframeP, i, j); - - mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], - i); // this is the mbsfn sync area index - - if (mcch_sdu_length > 0) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", - module_idP, CC_id, frameP, subframeP, mcch_sdu_length); - - header_len_mcch = 2; - - if (cc->tdd_Config != NULL) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", - module_idP, CC_id, frameP, subframeP, - mcch_sdu_length, mcch_mcs); - } else { - LOG_I(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", - module_idP, CC_id, frameP, subframeP, - mcch_sdu_length, mcch_mcs); - } - - cc->mcch_active = 1; - - memcpy((char *) &mch_buffer[sdu_length_total], - &cc->MCCH_pdu.payload[0], mcch_sdu_length); - sdu_lcids[num_sdus] = MCCH_LCHANID; - sdu_lengths[num_sdus] = mcch_sdu_length; - - if (sdu_lengths[num_sdus] > 128) { - header_len_mcch = 3; - } - - sdu_length_total += sdu_lengths[num_sdus]; - LOG_D(MAC, - "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n", - module_idP, CC_id, sdu_lengths[num_sdus]); - num_sdus++; - } + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; + } else { // no mcch for this MSP + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047 + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; } - TBS = - get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - // do not let mcch and mtch multiplexing when relaying is active - // for sync area 1, so not transmit data - //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { -#endif + msi_ptr += sizeof(MSI_ELEMENT); + //Header for MTCHs + num_mtch = cc->mbms_SessionList[0]->list.count; - // there is MTCHs, loop if there are more than 1 - if (mtch_flag == 1) { - // Calculate TBS - /* if ((msi_flag==1) || (mcch_flag==1)) { - TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL); - } - else { // only MTCH in this subframeP - TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL); - } - - // get MTCH data from RLC (like for DTCH) - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j); - - header_len_mtch = 3; - LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", - Mod_id,CC_id,frame,MTCH,TBS, - TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); - - rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG, - TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); - printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); - - */ - - // get MTCH data from RLC (like for DTCH) - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", - module_idP, CC_id, frameP, subframeP, i, j); - - header_len_mtch = 3; - LOG_D(MAC, - "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", - module_idP, CC_id, frameP, MTCH, TBS, - TBS - header_len_mcch - header_len_msi - sdu_length_total - - header_len_mtch); - - rlc_status = - mac_rlc_status_ind(module_idP, 0, frameP, subframeP, - module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, - MTCH, - TBS - header_len_mcch - header_len_msi - - sdu_length_total - header_len_mtch -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 -#endif - ); - - LOG_D(MAC, - "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", - MTCH, frameP, subframeP, rlc_status.bytes_in_buffer); - - if (rlc_status.bytes_in_buffer > 0) { - LOG_I(MAC, - "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n", - module_idP, CC_id, frameP, - TBS - header_len_mcch - header_len_msi - - sdu_length_total - header_len_mtch, header_len_mtch); - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used - (char *) - &mch_buffer[sdu_length_total] -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, - 0 -#endif - ); - - - //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]); - LOG_I(MAC, - "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n", - module_idP, CC_id, sdu_lengths[num_sdus], MTCH); - cc->mtch_active = 1; - sdu_lcids[num_sdus] = MTCH; - sdu_length_total += sdu_lengths[num_sdus]; - - if (sdu_lengths[num_sdus] < 128) { - header_len_mtch = 2; - } - - num_sdus++; - } else { - header_len_mtch = 0; - } + for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment + ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; + msi_ptr += sizeof(MSI_ELEMENT); } -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - // } -#endif - // FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs - if ((sdu_length_total + header_len_msi + header_len_mcch + - header_len_mtch) > 0) { - // Adjust the last subheader - /* if ((msi_flag==1) || (mcch_flag==1)) { - RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs; - } - else if (mtch_flag == 1) { // only MTCH in this subframeP - RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9; - } - */ - header_len_mtch_temp = header_len_mtch; - header_len_mcch_temp = header_len_mcch; - header_len_msi_temp = header_len_msi; + msi_length = msi_ptr - msi_control_element; - if (header_len_mtch > 0) { - header_len_mtch = 1; // remove Length field in the subheader for the last PDU - } else if (header_len_mcch > 0) { - header_len_mcch = 1; - } else { - header_len_msi = 1; - } - - // Calculate the padding - if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - - sdu_length_total) < 0) { - LOG_E(MAC, "Error in building MAC PDU, TBS %d < PDU %d \n", - TBS, - header_len_mtch + header_len_mcch + header_len_msi + - sdu_length_total); - return 0; - } else - if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - - sdu_length_total) <= 2) { - padding = - (TBS - header_len_mtch - header_len_mcch - header_len_msi - - sdu_length_total); - post_padding = 0; - } else { // using post_padding, give back the Length field of subheader for the last PDU - padding = 0; - - if (header_len_mtch > 0) { - header_len_mtch = header_len_mtch_temp; - } else if (header_len_mcch > 0) { - header_len_mcch = header_len_mcch_temp; - } else { - header_len_msi = header_len_msi_temp; - } - - post_padding = - TBS - sdu_length_total - header_len_msi - header_len_mcch - - header_len_mtch; - } - - // Generate the MAC Header for MCH - // here we use the function for DLSCH because DLSCH & MCH have the same Header structure - offset = generate_dlsch_header((unsigned char *) cc->MCH_pdu.payload, num_sdus, sdu_lengths, sdu_lcids, 255, // no drx - 31, // no timing advance - NULL, // no contention res id - padding, post_padding); - - cc->MCH_pdu.Pdu_size = TBS; - cc->MCH_pdu.sync_area = i; - cc->MCH_pdu.msi_active = cc->msi_active; - cc->MCH_pdu.mcch_active = cc->mcch_active; - cc->MCH_pdu.mtch_active = cc->mtch_active; - LOG_D(MAC, - " MCS for this sf is %d (mcch active %d, mtch active %d)\n", - cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active, - cc->MCH_pdu.mtch_active); - LOG_I(MAC, - "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", - module_idP, CC_id, sdu_length_total, num_sdus, - sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding, - cc->MCH_pdu.mcs, TBS, header_len_mtch, header_len_mcch, - header_len_msi); - // copy SDU to mch_pdu after the MAC Header - memcpy(&cc->MCH_pdu.payload[offset], mch_buffer, sdu_length_total); - - // filling remainder of MCH with random data if necessery - for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - cc->MCH_pdu.payload[offset + sdu_length_total + j] = - (char) (taus() & 0xff); - } - - /* Tracing of PDU is done on UE side */ - trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xffff, // M_RNTI = 6 in wirehsark - RC.mac[module_idP]->frame, - RC.mac[module_idP]->subframe, 0, 0); - - /* - for (j=0;jMCH_pdu.payload[j+offset]); - printf(" \n"); */ - return 1; + if (msi_length < 128) { + header_len_msi = 2; } else { - cc->MCH_pdu.Pdu_size = 0; - cc->MCH_pdu.sync_area = 0; - cc->MCH_pdu.msi_active = 0; - cc->MCH_pdu.mcch_active = 0; - cc->MCH_pdu.mtch_active = 0; - // for testing purpose, fill with random data - //for (j=0;j<(TBS-sdu_length_total-offset);j++) - // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); - return 0; + header_len_msi = 3; } - //this is for testing - /* - if (mtch_flag == 1) { - // LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]); - return 1; + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes \n", + module_idP, CC_id, frameP, msi_length); + //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" ); + // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length); + // Store MSI data to mch_buffer[0] + memcpy((char *) &mch_buffer[sdu_length_total], + msi_control_element, msi_length); + sdu_lcids[num_sdus] = MCH_SCHDL_INFO; + sdu_lengths[num_sdus] = msi_length; + sdu_length_total += sdu_lengths[num_sdus]; + LOG_I(MAC, "[eNB %d] CC_id %d Create %d bytes for MSI\n", + module_idP, CC_id, sdu_lengths[num_sdus]); + num_sdus++; + cc->msi_active = 1; + } + + // there is MCCH + if (mcch_flag == 1) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", + module_idP, CC_id, frameP, subframeP, i, j); + mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], + i); // this is the mbsfn sync area index + + if (mcch_sdu_length > 0) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", + module_idP, CC_id, frameP, subframeP, mcch_sdu_length); + header_len_mcch = 2; + + if (cc->tdd_Config != NULL) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } else { + LOG_I(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } + + cc->mcch_active = 1; + memcpy((char *) &mch_buffer[sdu_length_total], + &cc->MCCH_pdu.payload[0], mcch_sdu_length); + sdu_lcids[num_sdus] = MCCH_LCHANID; + sdu_lengths[num_sdus] = mcch_sdu_length; + + if (sdu_lengths[num_sdus] > 128) { + header_len_mcch = 3; + } + + sdu_length_total += sdu_lengths[num_sdus]; + LOG_D(MAC, + "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n", + module_idP, CC_id, sdu_lengths[num_sdus]); + num_sdus++; + } + } + + TBS = + get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // do not let mcch and mtch multiplexing when relaying is active + // for sync area 1, so not transmit data + //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { +#endif + + // there is MTCHs, loop if there are more than 1 + if (mtch_flag == 1) { + // Calculate TBS + /* if ((msi_flag==1) || (mcch_flag==1)) { + TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL); } - else - return 0; + else { // only MTCH in this subframeP + TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL); + } + + // get MTCH data from RLC (like for DTCH) + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j); + + header_len_mtch = 3; + LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + Mod_id,CC_id,frame,MTCH,TBS, + TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); + + rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG, + TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); + printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); + */ + // get MTCH data from RLC (like for DTCH) + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", + module_idP, CC_id, frameP, subframeP, i, j); + header_len_mtch = 3; + LOG_D(MAC, + "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + module_idP, CC_id, frameP, MTCH, TBS, + TBS - header_len_mcch - header_len_msi - sdu_length_total - + header_len_mtch); + rlc_status = + mac_rlc_status_ind(module_idP, 0, frameP, subframeP, + module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, + MTCH, + TBS - header_len_mcch - header_len_msi - + sdu_length_total - header_len_mtch +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 +#endif + ); + LOG_D(MAC, + "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", + MTCH, frameP, subframeP, rlc_status.bytes_in_buffer); + + if (rlc_status.bytes_in_buffer > 0) { + LOG_I(MAC, + "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n", + module_idP, CC_id, frameP, + TBS - header_len_mcch - header_len_msi - + sdu_length_total - header_len_mtch, header_len_mtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used + (char *) + &mch_buffer[sdu_length_total] +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, + 0 +#endif + ); + //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]); + LOG_I(MAC, + "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n", + module_idP, CC_id, sdu_lengths[num_sdus], MTCH); + cc->mtch_active = 1; + sdu_lcids[num_sdus] = MTCH; + sdu_length_total += sdu_lengths[num_sdus]; + + if (sdu_lengths[num_sdus] < 128) { + header_len_mtch = 2; + } + + num_sdus++; + } else { + header_len_mtch = 0; + } + } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // } +#endif + + // FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs + if ((sdu_length_total + header_len_msi + header_len_mcch + + header_len_mtch) > 0) { + // Adjust the last subheader + /* if ((msi_flag==1) || (mcch_flag==1)) { + RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs; + } + else if (mtch_flag == 1) { // only MTCH in this subframeP + RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9; + } + */ + header_len_mtch_temp = header_len_mtch; + header_len_mcch_temp = header_len_mcch; + header_len_msi_temp = header_len_msi; + + if (header_len_mtch > 0) { + header_len_mtch = 1; // remove Length field in the subheader for the last PDU + } else if (header_len_mcch > 0) { + header_len_mcch = 1; + } else { + header_len_msi = 1; + } + + // Calculate the padding + if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - + sdu_length_total) < 0) { + LOG_E(MAC, "Error in building MAC PDU, TBS %d < PDU %d \n", + TBS, + header_len_mtch + header_len_mcch + header_len_msi + + sdu_length_total); + return 0; + } else if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - + sdu_length_total) <= 2) { + padding = + (TBS - header_len_mtch - header_len_mcch - header_len_msi - + sdu_length_total); + post_padding = 0; + } else { // using post_padding, give back the Length field of subheader for the last PDU + padding = 0; + + if (header_len_mtch > 0) { + header_len_mtch = header_len_mtch_temp; + } else if (header_len_mcch > 0) { + header_len_mcch = header_len_mcch_temp; + } else { + header_len_msi = header_len_msi_temp; + } + + post_padding = + TBS - sdu_length_total - header_len_msi - header_len_mcch - + header_len_mtch; + } + + // Generate the MAC Header for MCH + // here we use the function for DLSCH because DLSCH & MCH have the same Header structure + offset = generate_dlsch_header((unsigned char *) cc->MCH_pdu.payload, num_sdus, sdu_lengths, sdu_lcids, 255, // no drx + 31, // no timing advance + NULL, // no contention res id + padding, post_padding); + cc->MCH_pdu.Pdu_size = TBS; + cc->MCH_pdu.sync_area = i; + cc->MCH_pdu.msi_active = cc->msi_active; + cc->MCH_pdu.mcch_active = cc->mcch_active; + cc->MCH_pdu.mtch_active = cc->mtch_active; + LOG_D(MAC, + " MCS for this sf is %d (mcch active %d, mtch active %d)\n", + cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active, + cc->MCH_pdu.mtch_active); + LOG_I(MAC, + "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", + module_idP, CC_id, sdu_length_total, num_sdus, + sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding, + cc->MCH_pdu.mcs, TBS, header_len_mtch, header_len_mcch, + header_len_msi); + // copy SDU to mch_pdu after the MAC Header + memcpy(&cc->MCH_pdu.payload[offset], mch_buffer, sdu_length_total); + + // filling remainder of MCH with random data if necessery + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + cc->MCH_pdu.payload[offset + sdu_length_total + j] = + (char) (taus() & 0xff); + } + + /* Tracing of PDU is done on UE side */ + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI, 0xffff, // M_RNTI = 6 in wirehsark + RC.mac[module_idP]->frame, + RC.mac[module_idP]->subframe, 0, 0); + /* + for (j=0;jMCH_pdu.payload[j+offset]); + printf(" \n"); */ + return 1; + } else { + cc->MCH_pdu.Pdu_size = 0; + cc->MCH_pdu.sync_area = 0; + cc->MCH_pdu.msi_active = 0; + cc->MCH_pdu.mcch_active = 0; + cc->MCH_pdu.mtch_active = 0; + // for testing purpose, fill with random data + //for (j=0;j<(TBS-sdu_length_total-offset);j++) + // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); + return 0; + } + + //this is for testing + /* + if (mtch_flag == 1) { + // LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]); + return 1; + } + else + return 0; + */ } MCH_PDU *get_mch_sdu(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t subframeP) -{ - // RC.mac[module_idP]->MCH_pdu.mcs=0; - //LOG_D(MAC," MCH_pdu.mcs is %d\n", RC.mac[module_idP]->MCH_pdu.mcs); -//#warning "MCH pdu should take the CC_id index" - return (&RC.mac[module_idP]->common_channels[CC_id].MCH_pdu); + sub_frame_t subframeP) { + // RC.mac[module_idP]->MCH_pdu.mcs=0; + //LOG_D(MAC," MCH_pdu.mcs is %d\n", RC.mac[module_idP]->MCH_pdu.mcs); + //#warning "MCH pdu should take the CC_id index" + return (&RC.mac[module_idP]->common_channels[CC_id].MCH_pdu); } #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 890cd63a5c..4aa09b59de 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -85,11 +85,10 @@ uint8_t rb_table[34] = { }; // This table hold the possible number of MTC repetition for CE ModeA -const uint8_t pusch_repetition_Table8_2_36213[3][4]= -{ - {1 , 2 , 4 , 8 }, - {1 , 4 , 8 , 16}, - {1 , 4 , 16, 32} +const uint8_t pusch_repetition_Table8_2_36213[3][4]= { + {1, 2, 4, 8 }, + {1, 4, 8, 16}, + {1, 4, 16, 32} }; extern mui_t rrc_eNB_mui; @@ -131,7 +130,6 @@ rx_sdu(const module_id_t enb_mod_idP, rrc_eNB_ue_context_t *ue_contextP = NULL; UE_sched_ctrl_t *UE_scheduling_control = NULL; UE_TEMPLATE *UE_template_ptr = NULL; - /* Init */ current_rnti = rntiP; UE_id = find_UE_id(enb_mod_idP, current_rnti); @@ -143,13 +141,11 @@ rx_sdu(const module_id_t enb_mod_idP, memset(rx_lengths, 0, NB_RB_MAX * sizeof(unsigned short)); start_meas(&mac->rx_ulsch_sdu); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); - - trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0); + trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0); if (UE_id != -1) { UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); - LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", enb_mod_idP, harq_pid, @@ -160,7 +156,6 @@ rx_sdu(const module_id_t enb_mod_idP, current_rnti, UE_id, ul_cqi); - AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); if (sduP != NULL) { @@ -175,7 +170,6 @@ rx_sdu(const module_id_t enb_mod_idP, UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; UE_scheduling_control->ul_consecutive_errors = 0; - first_rb = UE_template_ptr->first_rb_ul[harq_pid]; if (UE_scheduling_control->ul_out_of_sync > 0) { @@ -232,7 +226,7 @@ rx_sdu(const module_id_t enb_mod_idP, if (UE_scheduling_control->cdrx_configured == TRUE) { /* Synchronous UL HARQ */ UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; - /* + /* * The NACK is programmed in n+4 subframes, so UE will have drxRetransmission running. * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer. * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer. @@ -241,13 +235,11 @@ rx_sdu(const module_id_t enb_mod_idP, } first_rb = UE_template_ptr->first_rb_ul[harq_pid]; - /* Program NACK for PHICH */ LOG_D(MAC, "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n", current_rnti, harq_pid, first_rb); - nfapi_hi_dci0_request_t *hi_dci0_req = NULL; uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP + sf_ahead_dl) % 10]; @@ -302,22 +294,20 @@ rx_sdu(const module_id_t enb_mod_idP, if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } else { - if (ra->rach_resource_type > 0) { - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // TODO: Currently we don't support retransmission of Msg3 ( If in error Cancel RA procedure and reattach) - } - else - { - // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! - ra->msg3_round++; - /* Prepare handling of retransmission */ - get_Msg3allocret(&mac->common_channels[CC_idP], - ra->Msg3_subframe, - ra->Msg3_frame, - &ra->Msg3_frame, - &ra->Msg3_subframe); - // prepare handling of retransmission - add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP); - } + if (ra->rach_resource_type > 0) { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // TODO: Currently we don't support retransmission of Msg3 ( If in error Cancel RA procedure and reattach) + } else { + // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! + ra->msg3_round++; + /* Prepare handling of retransmission */ + get_Msg3allocret(&mac->common_channels[CC_idP], + ra->Msg3_subframe, + ra->Msg3_frame, + &ra->Msg3_frame, + &ra->Msg3_subframe); + // prepare handling of retransmission + add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP); + } } /* TODO: program NACK for PHICH? */ @@ -393,7 +383,6 @@ rx_sdu(const module_id_t enb_mod_idP, CC_idP, rx_ces[i], UE_template_ptr->phr_info); - UE_template_ptr->phr_info_configured = 1; UE_scheduling_control->phr_received = 1; } @@ -425,13 +414,11 @@ rx_sdu(const module_id_t enb_mod_idP, CC_idP, old_rnti, old_UE_id); - UE_id = old_UE_id; current_rnti = old_rnti; /* Clear timer */ UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); - UE_scheduling_control->uplane_inactivity_timer = 0; UE_scheduling_control->ul_inactivity_timer = 0; UE_scheduling_control->ul_failure_timer = 0; @@ -444,6 +431,7 @@ rx_sdu(const module_id_t enb_mod_idP, subframeP, old_rnti); } + UE_template_ptr->ul_SR = 1; UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; UE_list->UE_template[UE_PCCID(enb_mod_idP, UE_id)][UE_id].configured = 1; @@ -468,51 +456,52 @@ rx_sdu(const module_id_t enb_mod_idP, if (RA_id != -1) { RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); int8_t ret = mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - UE_id, - old_rnti, - DCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - 0 + CC_idP, + frameP, subframeP, + UE_id, + old_rnti, + DCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,ra->rach_resource_type > 0 + ,ra->rach_resource_type > 0 #endif - ); + ); + /* Received a new rnti */ if (ret == 0) { - ra->state = MSGCRNTI; - LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n", - enb_mod_idP, - frameP, - subframeP, - CC_idP, - old_rnti, - old_UE_id); - UE_id = old_UE_id; - current_rnti = old_rnti; - ra->rnti = old_rnti; - ra->crnti_rrc_mui = rrc_eNB_mui-1; - ra->crnti_harq_pid = -1; + ra->state = MSGCRNTI; + LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n", + enb_mod_idP, + frameP, + subframeP, + CC_idP, + old_rnti, + old_UE_id); + UE_id = old_UE_id; + current_rnti = old_rnti; + ra->rnti = old_rnti; + ra->crnti_rrc_mui = rrc_eNB_mui-1; + ra->crnti_harq_pid = -1; + /* Clear timer */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + UE_scheduling_control->uplane_inactivity_timer = 0; + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; - /* Clear timer */ - UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); - UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti); + } - UE_scheduling_control->uplane_inactivity_timer = 0; - UE_scheduling_control->ul_inactivity_timer = 0; - UE_scheduling_control->ul_failure_timer = 0; - - if (UE_scheduling_control->ul_out_of_sync > 0) { - UE_scheduling_control->ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti); - } - UE_template_ptr->ul_SR = 1; - UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; + UE_template_ptr->ul_SR = 1; + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; } else { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } + // break; } } @@ -546,7 +535,6 @@ rx_sdu(const module_id_t enb_mod_idP, UE_template_ptr->ul_buffer_info[LCGID1] + UE_template_ptr->ul_buffer_info[LCGID2] + UE_template_ptr->ul_buffer_info[LCGID3]; - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); if (UE_id == UE_list->head) { @@ -587,21 +575,19 @@ rx_sdu(const module_id_t enb_mod_idP, UE_template_ptr->ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; UE_template_ptr->ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; UE_template_ptr->ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; - UE_template_ptr->estimated_ul_buffer = UE_template_ptr->ul_buffer_info[LCGID0] + UE_template_ptr->ul_buffer_info[LCGID1] + UE_template_ptr->ul_buffer_info[LCGID2] + UE_template_ptr->ul_buffer_info[LCGID3]; - LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = %u LCGID2 = %u LCGID3 = %u\n", - enb_mod_idP, - CC_idP, - rx_ces[i], - UE_template_ptr->ul_buffer_info[LCGID0], - UE_template_ptr->ul_buffer_info[LCGID1], - UE_template_ptr->ul_buffer_info[LCGID2], - UE_template_ptr->ul_buffer_info[LCGID3]); + enb_mod_idP, + CC_idP, + rx_ces[i], + UE_template_ptr->ul_buffer_info[LCGID0], + UE_template_ptr->ul_buffer_info[LCGID1], + UE_template_ptr->ul_buffer_info[LCGID2], + UE_template_ptr->ul_buffer_info[LCGID3]); if (crnti_rx == 1) { LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received CRNTI.\n", @@ -712,7 +698,6 @@ rx_sdu(const module_id_t enb_mod_idP, frameP, ra->rnti, UE_id); - UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); } @@ -808,7 +793,7 @@ rx_sdu(const module_id_t enb_mod_idP, mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; - + if (mac_eNB_get_rrc_status(enb_mod_idP, current_rnti) < RRC_RECONFIGURED) { UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; } @@ -871,7 +856,6 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; /* Clear uplane_inactivity_timer */ UE_scheduling_control->uplane_inactivity_timer = 0; - /* Reset RRC inactivity timer after uplane activity */ ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti); @@ -913,7 +897,7 @@ rx_sdu(const module_id_t enb_mod_idP, if (UE_scheduling_control->cdrx_configured == TRUE) { /* Synchronous UL HARQ */ UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; - /* + /* * The ACK is programmed in n+4 subframes, so UE will have drxRetransmission running. * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer. * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer @@ -927,11 +911,9 @@ rx_sdu(const module_id_t enb_mod_idP, current_rnti, harq_pid, first_rb); - nfapi_hi_dci0_request_t *hi_dci0_req; uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; @@ -1136,13 +1118,11 @@ schedule_ulsch(module_id_t module_idP, COMMON_channels_t *cc = NULL; int sched_subframe; int sched_frame; - /* Init */ mac = RC.mac[module_idP]; sli = &(mac->slice_info); memset(first_rb, 0, NFAPI_CC_MAX * sizeof(uint16_t)); start_meas(&(mac->schedule_ulsch)); - sched_subframe = (subframeP + 4) % 10; sched_frame = frameP; cc = mac->common_channels; @@ -1253,13 +1233,26 @@ schedule_ulsch(module_id_t module_idP, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) first_rb[CC_id] = (emtc_active[CC_id] == 1) ? 7 : 1; #else + /* Note: the size of PUCCH is arbitrary, to be done properly. */ switch (RC.eNB[module_idP][CC_id]->frame_parms.N_RB_DL) { - case 25: first_rb[CC_id] = 1; break; // leave out first RB for PUCCH - case 50: first_rb[CC_id] = 2; break; // leave out first RB for PUCCH - case 100: first_rb[CC_id] = 3; break; // leave out first RB for PUCCH - default: LOG_E(MAC, "nb RBs not handled, todo.\n"); exit(1); + case 25: + first_rb[CC_id] = 1; + break; // leave out first RB for PUCCH + + case 50: + first_rb[CC_id] = 2; + break; // leave out first RB for PUCCH + + case 100: + first_rb[CC_id] = 3; + break; // leave out first RB for PUCCH + + default: + LOG_E(MAC, "nb RBs not handled, todo.\n"); + exit(1); } + #endif RA_t *ra_ptr = cc->ra; @@ -1385,6 +1378,7 @@ schedule_ulsch_rnti(module_id_t module_idP, /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */ for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { n_rb_ul_tab[CC_id] = to_prb(cc[CC_id].ul_Bandwidth); // return total number of PRB + /* HACK: let's remove the PUCCH from available RBs * we suppose PUCCH size is: * - for 25 RBs: 1 RB (top and bottom of ressource grid) @@ -1395,15 +1389,27 @@ schedule_ulsch_rnti(module_id_t module_idP, * so we only remove the top part of the resource grid. */ switch (n_rb_ul_tab[CC_id]) { - case 25: n_rb_ul_tab[CC_id] -= 1; break; - case 50: n_rb_ul_tab[CC_id] -= 2; break; - case 100: n_rb_ul_tab[CC_id] -= 3; break; - default: LOG_E(MAC, "RBs setting not handled. Todo.\n"); exit(1); + case 25: + n_rb_ul_tab[CC_id] -= 1; + break; + + case 50: + n_rb_ul_tab[CC_id] -= 2; + break; + + case 100: + n_rb_ul_tab[CC_id] -= 3; + break; + + default: + LOG_E(MAC, "RBs setting not handled. Todo.\n"); + exit(1); } + UE_list->first_rb_offset[CC_id][slice_idx] = cmin(n_rb_ul_tab[CC_id], sli->ul[slice_idx].first_rb); } - /* + /* * ULSCH preprocessor: set UE_template-> * pre_allocated_nb_rb_ul[slice_idx] * pre_assigned_mcs_ul @@ -1420,7 +1426,7 @@ schedule_ulsch_rnti(module_id_t module_idP, if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) { continue; } - + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].rach_resource_type > 0) continue; // don't schedule if Msg5 is not received yet @@ -1448,7 +1454,6 @@ schedule_ulsch_rnti(module_id_t module_idP, for (int n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { /* This is the actual CC_id in the list */ CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template_ptr = &(UE_list->UE_template[CC_id][UE_id]); UE_sched_ctrl_ptr = &(UE_list->UE_sched_ctrl[UE_id]); harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); @@ -1490,7 +1495,6 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_sched_ctrl_ptr->ul_inactivity_timer, UE_sched_ctrl_ptr->ul_failure_timer, UE_sched_ctrl_ptr->cqi_req_timer); - /* Reset the scheduling request */ UE_template_ptr->ul_SR = 0; status = mac_eNB_get_rrc_status(module_idP, rnti); @@ -1500,13 +1504,12 @@ schedule_ulsch_rnti(module_id_t module_idP, /* Be sure that there are some free RBs */ if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id]) { LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP, - frameP, - subframeP, - UE_id, - rnti, - CC_id); - + module_idP, + frameP, + subframeP, + UE_id, + rnti, + CC_id); continue; } @@ -1514,27 +1517,27 @@ schedule_ulsch_rnti(module_id_t module_idP, /* This test seems to be way too long, can we provide an optimization? */ if (CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) { LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: not enough CCE\n", - module_idP, - frameP, - subframeP, - UE_id, - rnti, - CC_id); - + module_idP, + frameP, + subframeP, + UE_id, + rnti, + CC_id); continue; } - + /* Handle the aperiodic CQI report */ cqi_req = 0; LOG_D(MAC,"RRC Conenction status %d, cqi_timer %d\n",status,UE_sched_ctrl_ptr->cqi_req_timer); + if (status >= RRC_CONNECTED && UE_sched_ctrl_ptr->cqi_req_timer > 30) { if (UE_sched_ctrl_ptr->cqi_received == 0) { if (NFAPI_MODE != NFAPI_MONOLITHIC) { cqi_req = 0; } else { cqi_req = 1; - LOG_D(MAC,"Setting CQI_REQ (timer %d)\n",UE_sched_ctrl_ptr->cqi_req_timer); + /* TDD: to be safe, do not ask CQI in special Subframes:36.213/7.2.3 CQI definition */ if (cc[CC_id].tdd_Config) { switch (cc[CC_id].tdd_Config->subframeAssignment) { @@ -1542,12 +1545,14 @@ schedule_ulsch_rnti(module_id_t module_idP, if(subframeP == 1 || subframeP == 6) { cqi_req=0; } + break; case 3: if(subframeP == 1) { cqi_req=0; } + break; default: @@ -1576,7 +1581,6 @@ schedule_ulsch_rnti(module_id_t module_idP, */ snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10; target_snr = mac->puSch10xSnr / 10; - /* * This assumes accumulated tpc * Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out @@ -1585,7 +1589,6 @@ schedule_ulsch_rnti(module_id_t module_idP, if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around - UE_template_ptr->pusch_tpc_tx_frame = frameP; UE_template_ptr->pusch_tpc_tx_subframe = subframeP; @@ -1604,14 +1607,14 @@ schedule_ulsch_rnti(module_id_t module_idP, if (tpc != 1) { LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", - module_idP, - frameP, - subframeP, - harq_pid, - tpc, - tpc_accumulated, - snr, - target_snr); + module_idP, + frameP, + subframeP, + harq_pid, + tpc, + tpc_accumulated, + snr, + target_snr); } ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator @@ -1625,8 +1628,8 @@ schedule_ulsch_rnti(module_id_t module_idP, if (UE_sched_ctrl_ptr->cdrx_configured) { UE_sched_ctrl_ptr->drx_inactivity_timer = 1; // reset drx inactivity timer when new transmission VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_sched_ctrl_ptr->drx_inactivity_timer); - UE_sched_ctrl_ptr->dci0_ongoing_timer = 1; // when set the UE_template_ptr->ul_SR cannot be set to 1, - // see definition for more information + UE_sched_ctrl_ptr->dci0_ongoing_timer = 1; // when set the UE_template_ptr->ul_SR cannot be set to 1, + // see definition for more information } if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) { @@ -1764,6 +1767,7 @@ schedule_ulsch_rnti(module_id_t module_idP, 1, // repetition_number (frameP * 10) + subframeP); } + #endif if (dlsch_flag == 1) { @@ -1870,6 +1874,7 @@ schedule_ulsch_rnti(module_id_t module_idP, 0, // n_srs UE_template_ptr->TBS_UL[harq_pid]); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /* This is a BL/CE UE allocation */ if (UE_template_ptr->rach_resource_type > 0) { fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], @@ -1878,6 +1883,7 @@ schedule_ulsch_rnti(module_id_t module_idP, 1, // repetition_number (frameP * 10) + subframeP); } + #endif if(dlsch_flag == 1) { @@ -1909,14 +1915,14 @@ schedule_ulsch_rnti(module_id_t module_idP, ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - sched_frame, - sched_subframeP, - cqi_req); + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + cqi_req); /* HACK: RBs used by retransmission have to be reserved. * The current mechanism uses the notion of 'first_rb', so @@ -1930,7 +1936,7 @@ schedule_ulsch_rnti(module_id_t module_idP, */ if (first_rb_slice[CC_id] < UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid]) first_rb_slice[CC_id] = UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid]; - } // end of round > 0 + } // end of round > 0 } // UE_is_to_be_scheduled } // loop over all active CC_ids } // loop over UE_ids @@ -1970,8 +1976,8 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, UE_list_t *UE_list = &(eNB->UE_list); UE_TEMPLATE *UE_template = NULL; UE_sched_ctrl_t *UE_sched_ctrl = NULL; - uint8_t Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13; - uint8_t UL_Scheduling_DCI_SF,UL_Scheduling_DCI_Frame_Even_Odd_Flag; //TODO: To be removed after scheduler relaxation Task + uint8_t Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13; + uint8_t UL_Scheduling_DCI_SF,UL_Scheduling_DCI_Frame_Even_Odd_Flag; //TODO: To be removed after scheduler relaxation Task if (sched_subframeP < subframeP) { sched_frame++; @@ -2039,367 +2045,362 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, N_RB_UL); RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer); - pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]); Total_Num_Rep_ULSCH = pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][UE_template->pusch_repetition_levels]; - UL_Scheduling_DCI_SF = (40-4 - Total_Num_Rep_ULSCH)%10; //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task - UL_Scheduling_DCI_Frame_Even_Odd_Flag= ! (((40-4 - Total_Num_Rep_ULSCH)/10 )%2); //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task + UL_Scheduling_DCI_SF = (40-4 - Total_Num_Rep_ULSCH)%10; //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task + UL_Scheduling_DCI_Frame_Even_Odd_Flag= ! (((40-4 - Total_Num_Rep_ULSCH)/10 )%2); //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task /* If frameP odd don't schedule */ - if ((frameP&1) == UL_Scheduling_DCI_Frame_Even_Odd_Flag) //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task - { + if ((frameP&1) == UL_Scheduling_DCI_Frame_Even_Odd_Flag) { //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task + //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) { + if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == UL_Scheduling_DCI_SF)) { + /* + * if there is information on bsr of DCCH, DTCH, + * or if there is UL_SR, + * or if there is a packet to retransmit, + * or we want to schedule a periodic feedback every frame + */ + LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round_UL %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + round_UL, + UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + /* Reset the scheduling request */ + emtc_active[CC_id] = 1; + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP,rnti); + cqi_req = 0; + /* Power control: compute the expected ULSCH RX snr (for the stats) */ + /* This is the normalized snr and this should be constant (regardless of mcs) */ + snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; + target_snr = eNB->puSch10xSnr / 10; /* TODO: target_rx_power was 178, what to put? */ + /* This assumes accumulated tpc */ + /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ + int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { // frame wrap-around + UE_template->pusch_tpc_tx_frame = frameP; + UE_template->pusch_tpc_tx_subframe = subframeP; - //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) { - if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == UL_Scheduling_DCI_SF)) { - /* - * if there is information on bsr of DCCH, DTCH, - * or if there is UL_SR, - * or if there is a packet to retransmit, - * or we want to schedule a periodic feedback every frame - */ - LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round_UL %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP, - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - round_UL, - UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - /* Reset the scheduling request */ - emtc_active[CC_id] = 1; - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP,rnti); - cqi_req = 0; - /* Power control: compute the expected ULSCH RX snr (for the stats) */ - /* This is the normalized snr and this should be constant (regardless of mcs) */ - snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; - target_snr = eNB->puSch10xSnr / 10; /* TODO: target_rx_power was 178, what to put? */ - /* This assumes accumulated tpc */ - /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ - int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; - - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { // frame wrap-around - UE_template->pusch_tpc_tx_frame = frameP; - UE_template->pusch_tpc_tx_subframe = subframeP; - - if (snr > target_snr + 4) { - tpc = 0; //-1 - UE_sched_ctrl->tpc_accumulated[CC_id]--; - } else if (snr < target_snr - 4) { - tpc = 2; //+1 - UE_sched_ctrl->tpc_accumulated[CC_id]++; + if (snr > target_snr + 4) { + tpc = 0; //-1 + UE_sched_ctrl->tpc_accumulated[CC_id]--; + } else if (snr < target_snr - 4) { + tpc = 2; //+1 + UE_sched_ctrl->tpc_accumulated[CC_id]++; + } else { + tpc = 1; //0 + } } else { tpc = 1; //0 } - } else { - tpc = 1; //0 - } - if (tpc != 1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", - module_idP, - frameP, - subframeP, - harq_pid, - tpc, - UE_sched_ctrl->tpc_accumulated[CC_id], - snr, - target_snr); - } - - /* New transmission */ - if (round_UL == 0) { - ndi = 1 - UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid] = ndi; - UE_template->mcs_UL[harq_pid] = 4; - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6); - UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; - UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; - T(T_ENB_MAC_UE_UL_SCHEDULE, - T_INT(module_idP), - T_INT(CC_id), - T_INT(rnti), - T_INT(frameP), - T_INT(subframeP), - T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(0), - T_INT(6), - T_INT(UE_template->TBS_UL[harq_pid]), - T_INT(ndi)); - /* Store for possible retransmission */ - UE_template->nb_rb_ul[harq_pid] = 6; - UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); - - if (UE_id == UE_list->head) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl->ul_scheduled); + if (tpc != 1) { + LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", + module_idP, + frameP, + subframeP, + harq_pid, + tpc, + UE_sched_ctrl->tpc_accumulated[CC_id], + snr, + target_snr); } - /* Adjust total UL buffer status by TBS, wait for UL sdus to do final update */ - UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; - LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); - /* Cyclic shift for DMRS */ - cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - /* save it for a potential retransmission */ - UE_template->cshift[harq_pid] = cshift; - AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); - LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS MPDCCH Narrowband %d\n", - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - sched_frame, - sched_subframeP, - (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); - UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); - hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + hi_dci0_req->number_of_hi]); - memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted - AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; // already set above... - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = UE_template->pusch_repetition_levels; - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; - hi_dci0_req->number_of_dci++; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG. Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n", - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - sched_frame, - sched_subframeP, - (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - cqi_req, - cc, - UE_template->physicalConfigDedicated, - get_tmode(module_idP,CC_id,UE_id), - eNB->ul_handle, - rnti, - UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round_UL&3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template->TBS_UL[harq_pid] - ); - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - UE_template->rach_resource_type > 2 ? 2 : 1, - Total_Num_Rep_ULSCH, // total_number_of_repetitions - 1, // repetition_number - (frameP * 10) + subframeP); - ul_req_tmp->number_of_pdus++; - eNB->ul_handle++; - add_ue_ulsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_UL_SCHEDULED); - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", - module_idP, - CC_id, - frameP, - subframeP, - UE_id); - } else { // round_UL > 0 => retransmission - /* In LTE-M the UL HARQ process is asynchronous */ - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, - T_INT(module_idP), - T_INT(CC_id), - T_INT(rnti), - T_INT(frameP), - T_INT(subframeP), - T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(0), - T_INT(6), - T_INT(round_UL)); - AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); - LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - sched_frame, - sched_subframeP, - (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); - UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb(cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]); - memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted - AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round_UL&3]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; - hi_dci0_req->number_of_dci++; - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - cqi_req, - cc, - UE_template->physicalConfigDedicated, - get_tmode(module_idP,CC_id,UE_id), - eNB->ul_handle, - rnti, - UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round_UL&3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template->TBS_UL[harq_pid] - ); - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - UE_template->rach_resource_type>2 ? 2 : 1, - 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * 10) + subframeP); - ul_req_tmp->number_of_pdus++; - eNB->ul_handle++; - } - } // UE_is_to_be_scheduled - } // ULCCs - } // loop over UE_id + /* New transmission */ + if (round_UL == 0) { + ndi = 1 - UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid] = ndi; + UE_template->mcs_UL[harq_pid] = 4; + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6); + UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + T(T_ENB_MAC_UE_UL_SCHEDULE, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(0), + T_INT(6), + T_INT(UE_template->TBS_UL[harq_pid]), + T_INT(ndi)); + /* Store for possible retransmission */ + UE_template->nb_rb_ul[harq_pid] = 6; + UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); + + if (UE_id == UE_list->head) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl->ul_scheduled); + } + + /* Adjust total UL buffer status by TBS, wait for UL sdus to do final update */ + UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); + /* Cyclic shift for DMRS */ + cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + /* save it for a potential retransmission */ + UE_template->cshift[harq_pid] = cshift; + AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); + LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS MPDCCH Narrowband %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + hi_dci0_req->number_of_hi]); + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; // already set above... + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = UE_template->pusch_repetition_levels; + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; + hi_dci0_req->number_of_dci++; + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG. Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + cqi_req, + cc, + UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round_UL&3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template->TBS_UL[harq_pid] + ); + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + UE_template->rach_resource_type > 2 ? 2 : 1, + Total_Num_Rep_ULSCH, // total_number_of_repetitions + 1, // repetition_number + (frameP * 10) + subframeP); + ul_req_tmp->number_of_pdus++; + eNB->ul_handle++; + add_ue_ulsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_UL_SCHEDULED); + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", + module_idP, + CC_id, + frameP, + subframeP, + UE_id); + } else { // round_UL > 0 => retransmission + /* In LTE-M the UL HARQ process is asynchronous */ + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(0), + T_INT(6), + T_INT(round_UL)); + AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); + LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb(cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); + hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]); + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round_UL&3]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; + hi_dci0_req->number_of_dci++; + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + cqi_req, + cc, + UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round_UL&3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template->TBS_UL[harq_pid] + ); + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + UE_template->rach_resource_type>2 ? 2 : 1, + 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * 10) + subframeP); + ul_req_tmp->number_of_pdus++; + eNB->ul_handle++; + } + } // UE_is_to_be_scheduled + } // ULCCs + } // loop over UE_id } // Schedule new ULSCH // This section is to repeat ULSCH PDU for a number of MTC repetitions - for(int i=0;inumber_of_pdus;i++) - { - ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[i]; - if (ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) // Repeat ULSCH PDUs only - continue ; + for(int i=0; inumber_of_pdus; i++) { + ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[i]; - if(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number < ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions) - { - ul_req_body_Rep = &eNB->UL_req_tmp[CC_id][(sched_subframeP+1)%10].ul_config_request_body; - ul_config_pdu_Rep = &ul_req_body_Rep->ul_config_pdu_list[ul_req_body_Rep->number_of_pdus]; - memcpy ((void *) ul_config_pdu_Rep, ul_config_pdu, sizeof (nfapi_ul_config_request_pdu_t)); - ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; - ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel13.repetition_number = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number +1; - ul_req_body_Rep->number_of_pdus++; - } //repetition_number < total_number_of_repetitions + if (ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) // Repeat ULSCH PDUs only + continue ; + + if(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number < ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions) { + ul_req_body_Rep = &eNB->UL_req_tmp[CC_id][(sched_subframeP+1)%10].ul_config_request_body; + ul_config_pdu_Rep = &ul_req_body_Rep->ul_config_pdu_list[ul_req_body_Rep->number_of_pdus]; + memcpy ((void *) ul_config_pdu_Rep, ul_config_pdu, sizeof (nfapi_ul_config_request_pdu_t)); + ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; + ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel13.repetition_number = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number +1; + ul_req_body_Rep->number_of_pdus++; + } //repetition_number < total_number_of_repetitions } // For loop on PDUs } #endif diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index f47cdaca0e..bfa8660c9e 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -255,12 +255,11 @@ Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, "Transmission on secondary CCs is not supported yet\n"); // start contention resolution timer UE_mac_inst[module_idP].RA_attempt_number++; - trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI, - UE_mac_inst[module_idP].RA_prach_resources. - ra_PreambleIndex, UE_mac_inst[module_idP].txFrame, - UE_mac_inst[module_idP].txSubframe, 0, - UE_mac_inst[module_idP].RA_attempt_number); + UE_mac_inst[module_idP].RA_prach_resources. + ra_PreambleIndex, UE_mac_inst[module_idP].txFrame, + UE_mac_inst[module_idP].txSubframe, 0, + UE_mac_inst[module_idP].RA_attempt_number); } @@ -275,12 +274,11 @@ Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, module_idP, frameP); UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0; UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; - - trace_pdu(DIRECTION_UPLINK, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], - UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].crnti, - UE_mac_inst[module_idP].txFrame, - UE_mac_inst[module_idP].txSubframe, 0, 0); + trace_pdu(DIRECTION_UPLINK, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], + UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].crnti, + UE_mac_inst[module_idP].txFrame, + UE_mac_inst[module_idP].txSubframe, 0, 0); } diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 7661759611..e7af451f6b 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -49,56 +49,54 @@ extern RAN_CONTEXT_t RC; //------------------------------------------------------------------------------ unsigned short fill_rar(const module_id_t module_idP, - const int CC_id, - RA_t * ra, - const frame_t frameP, - uint8_t * const dlsch_buffer, - const uint16_t N_RB_UL, const uint8_t input_buffer_length) + const int CC_id, + RA_t *ra, + const frame_t frameP, + uint8_t *const dlsch_buffer, + const uint16_t N_RB_UL, const uint8_t input_buffer_length) //------------------------------------------------------------------------------ { + RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; + uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); + // subheader fixed + rarh->E = 0; // First and last RAR + rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader + rarh->RAPID = ra->preamble_index; // Respond to Preamble 0 only for the moment + rar[4] = (uint8_t) (ra->rnti >> 8); + rar[5] = (uint8_t) (ra->rnti & 0xff); + //ra->timing_offset = 0; + ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps + rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4 + rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4 + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; - RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; - uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); - - - // subheader fixed - rarh->E = 0; // First and last RAR - rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader - rarh->RAPID = ra->preamble_index; // Respond to Preamble 0 only for the moment - rar[4] = (uint8_t) (ra->rnti >> 8); - rar[5] = (uint8_t) (ra->rnti & 0xff); - //ra->timing_offset = 0; - ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4 - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; - if(N_RB_UL == 25){ - ra->msg3_first_rb = 1; - }else{ - if (cc->tdd_Config && N_RB_UL == 100) { - ra->msg3_first_rb = 3; - } else { - ra->msg3_first_rb = 2; - } + if(N_RB_UL == 25) { + ra->msg3_first_rb = 1; + } else { + if (cc->tdd_Config && N_RB_UL == 100) { + ra->msg3_first_rb = 3; + } else { + ra->msg3_first_rb = 2; } - ra->msg3_nb_rb = 1; - uint16_t rballoc = mac_computeRIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant - rar[1] |= (rballoc >> 7) & 7; // Hopping = 0 (bit 3), 3 MSBs of rballoc - rar[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc - ra->msg3_mcs = 10; - ra->msg3_TPC = 3; - ra->msg3_ULdelay = 0; - ra->msg3_cqireq = 0; - ra->msg3_round = 0; - rar[2] |= ((ra->msg3_mcs & 0x8) >> 3); // mcs 10 - rar[3] = - (((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) | - ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1); + } - trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, module_idP, WS_RA_RNTI , 1, - RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, - 0, 0); - return (ra->rnti); + ra->msg3_nb_rb = 1; + uint16_t rballoc = mac_computeRIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant + rar[1] |= (rballoc >> 7) & 7; // Hopping = 0 (bit 3), 3 MSBs of rballoc + rar[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc + ra->msg3_mcs = 10; + ra->msg3_TPC = 3; + ra->msg3_ULdelay = 0; + ra->msg3_cqireq = 0; + ra->msg3_round = 0; + rar[2] |= ((ra->msg3_mcs & 0x8) >> 3); // mcs 10 + rar[3] = + (((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) | + ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1); + trace_pdu(DIRECTION_DOWNLINK, dlsch_buffer, input_buffer_length, module_idP, WS_RA_RNTI, 1, + RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, + 0, 0); + return (ra->rnti); } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -111,14 +109,13 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, RA_t *ra, const frame_t frameP, const sub_frame_t subframeP, - uint8_t* const dlsch_buffer, + uint8_t *const dlsch_buffer, const uint8_t ce_level) //------------------------------------------------------------------------------ { RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; COMMON_channels_t *cc = &eNB->common_channels[CC_id]; uint8_t *rar = (uint8_t *)(dlsch_buffer + 1); - uint32_t rballoc = 0; uint32_t ULdelay = 0; uint32_t cqireq = 0; @@ -126,30 +123,24 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, uint32_t TPC = 0; int input_buffer_length = 0; int N_NB_index = 0; - AssertFatal(ra != NULL, "RA is null \n"); - /* Subheader fixed */ - rarh->E = 0; // First and last RAR - rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader - rarh->RAPID = ra->preamble_index; // Respond to Preamble - + rarh->E = 0; // First and last RAR + rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader + rarh->RAPID = ra->preamble_index; // Respond to Preamble /* RAR PDU */ /* TA Command */ - ra->timing_offset /= 16; // T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t) (ra->timing_offset >> 4) & 0x7f; // 7 MSBs of timing advance - rar[1] = (uint8_t) (ra->timing_offset & 0x0f) << 4; // 4 LSBs of timing advance - + ra->timing_offset /= 16; // T_A = N_TA/16, where N_TA should be on a 30.72Msps + rar[0] = (uint8_t) (ra->timing_offset >> 4) & 0x7f; // 7 MSBs of timing advance + rar[1] = (uint8_t) (ra->timing_offset & 0x0f) << 4; // 4 LSBs of timing advance /* Copy the Msg2 narrowband */ ra->msg34_narrowband = ra->msg2_narrowband; ra->msg3_first_rb = 0; ra->msg3_nb_rb = 2; - if (ce_level < 2) { // CE Level 0, 1 (CEmodeA) + if (ce_level < 2) { // CE Level 0, 1 (CEmodeA) input_buffer_length = 6; - N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); - /* UL Grant */ ra->msg3_mcs = 7; TPC = 3; // no power increase @@ -157,7 +148,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, cqireq = 0; mpdcch_nb_index = 0; rballoc = mac_computeRIV(6, ra->msg3_first_rb, ra->msg3_nb_rb); - uint32_t buffer = 0; buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index)); buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index))); @@ -167,21 +157,15 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index))); buffer |= ((ULdelay & 0x01) << (2 + (4 - N_NB_index))); buffer |= (mpdcch_nb_index << (4 - N_NB_index)); - rar[1] |= (uint8_t) (buffer >> 16) & 0x0F; rar[2] = (uint8_t) (buffer >> 8) & 0xFF; rar[3] = (uint8_t) buffer & 0xFF; - /* RA CRNTI */ rar[4] = (uint8_t)(ra->rnti >> 8); rar[5] = (uint8_t)(ra->rnti & 0xff); - } else { // CE level 2, 3 (CEModeB) - AssertFatal(1 == 0, "Shouldn't get here ...\n"); - input_buffer_length = 5; - rar[3] = (uint8_t)(ra->rnti >> 8); rar[4] = (uint8_t)(ra->rnti & 0xff); } @@ -189,7 +173,7 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, LOG_I(MAC, "[RAPROC] Frame %d Subframe %d : Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x, preamble %d/%d, TIMING OFFSET %d\n", frameP, subframeP, - *(uint8_t*) rarh, + *(uint8_t *) rarh, rar[0], rar[1], rar[2], @@ -201,18 +185,16 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, rarh->RAPID, ra->preamble_index, ra->timing_offset); - - trace_pdu(DIRECTION_DOWNLINK, - dlsch_buffer, - input_buffer_length, - eNB->Mod_id, - WS_RA_RNTI, - 1, - eNB->frame, - eNB->subframe, - 0, - 0); - + trace_pdu(DIRECTION_DOWNLINK, + dlsch_buffer, + input_buffer_length, + eNB->Mod_id, + WS_RA_RNTI, + 1, + eNB->frame, + eNB->subframe, + 0, + 0); return (ra->rnti); } #endif diff --git a/openair2/LAYER2/MAC/rar_tools_ue.c b/openair2/LAYER2/MAC/rar_tools_ue.c index b08173a406..611aaf865b 100644 --- a/openair2/LAYER2/MAC/rar_tools_ue.c +++ b/openair2/LAYER2/MAC/rar_tools_ue.c @@ -41,98 +41,96 @@ #define DEBUG_RAR //------------------------------------------------------------------------------ -uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, const uint8_t preamble_index, uint8_t * selected_rar_buffer // output argument for storing the selected RAR header and RAR payload - ) +uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t *const dlsch_buffer, rnti_t *const t_crnti, const uint8_t preamble_index, + uint8_t *selected_rar_buffer // output argument for storing the selected RAR header and RAR payload + ) //------------------------------------------------------------------------------ { - uint16_t ret = 0; // return value + uint16_t ret = 0; // return value + RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; + // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); + uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); + // get the last RAR payload for working with CMW500 + uint8_t n_rarpy = 0; // number of RAR payloads + uint8_t n_rarh = 0; // number of MAC RAR subheaders + uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs - RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; - // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); - uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); + while (1) { + n_rarh++; - // get the last RAR payload for working with CMW500 - uint8_t n_rarpy = 0; // number of RAR payloads - uint8_t n_rarh = 0; // number of MAC RAR subheaders - uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs - while (1) { - n_rarh++; - if (rarh->T == 1) { - n_rarpy++; - LOG_D(MAC, "RAPID %d\n", rarh->RAPID); - } - - if (rarh->RAPID == preamble_index) { - LOG_D(PHY, "Found RAR with the intended RAPID %d\n", - rarh->RAPID); - rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); - break; - } - - if (abs((int) rarh->RAPID - (int) preamble_index) < - abs((int) best_rx_rapid - (int) preamble_index)) { - best_rx_rapid = rarh->RAPID; - rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); - } - - if (rarh->E == 0) { - LOG_I(PHY, - "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", - best_rx_rapid); - break; - } else { - rarh++; - } - }; - LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", - n_rarh, n_rarpy); - - if (CC_id > 0) { - LOG_W(MAC, "Should not have received RAR on secondary CCs! \n"); - return (0xffff); + if (rarh->T == 1) { + n_rarpy++; + LOG_D(MAC, "RAPID %d\n", rarh->RAPID); } - LOG_I(MAC, - "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", - module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], - rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); -#ifdef DEBUG_RAR - LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", module_idP, rarh->E); - LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", module_idP, rarh->T); - LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP, - rarh->RAPID); + if (rarh->RAPID == preamble_index) { + LOG_D(PHY, "Found RAR with the intended RAPID %d\n", + rarh->RAPID); + rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); + break; + } - // LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R); - LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n", - module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); - // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag); - // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc); - // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs); - // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC); - // LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay); - // LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req); - LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP, - (uint16_t) rar[5] + (rar[4] << 8)); -#endif + if (abs((int) rarh->RAPID - (int) preamble_index) < + abs((int) best_rx_rapid - (int) preamble_index)) { + best_rx_rapid = rarh->RAPID; + rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); + } - trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, - module_idP, WS_RA_RNTI, ra_rnti, UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); - - if (preamble_index == rarh->RAPID) { - *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti; - UE_mac_inst[module_idP].crnti = *t_crnti; //rar->t_crnti; - //return(rar->Timing_Advance_Command); - ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); + if (rarh->E == 0) { + LOG_I(PHY, + "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", + best_rx_rapid); + break; } else { - UE_mac_inst[module_idP].crnti = 0; - ret = (0xffff); + rarh++; } + }; - // move the selected RAR to the front of the RA_PDSCH buffer - memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1); - memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6); + LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", + n_rarh, n_rarpy); - return ret; + if (CC_id > 0) { + LOG_W(MAC, "Should not have received RAR on secondary CCs! \n"); + return (0xffff); + } + LOG_I(MAC, + "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", + module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], + rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); +#ifdef DEBUG_RAR + LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", module_idP, rarh->E); + LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", module_idP, rarh->T); + LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP, + rarh->RAPID); + // LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R); + LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n", + module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); + // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag); + // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc); + // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs); + // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC); + // LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay); + // LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req); + LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP, + (uint16_t) rar[5] + (rar[4] << 8)); +#endif + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, + module_idP, WS_RA_RNTI, ra_rnti, UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); + + if (preamble_index == rarh->RAPID) { + *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti; + UE_mac_inst[module_idP].crnti = *t_crnti; //rar->t_crnti; + //return(rar->Timing_Advance_Command); + ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); + } else { + UE_mac_inst[module_idP].crnti = 0; + ret = (0xffff); + } + + // move the selected RAR to the front of the RA_PDSCH buffer + memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1); + memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6); + return ret; } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 8f3892013b..23f699b058 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -400,11 +400,9 @@ ue_send_sdu(module_id_t module_idP, #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); - - trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0); + trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0); payload_ptr = parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_len); @@ -591,34 +589,31 @@ ue_send_sdu(module_id_t module_idP, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frameP, - uint8_t eNB_index, void *pdu, uint16_t len) -{ + uint8_t eNB_index, void *pdu, uint16_t len) { #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].rx_si); + start_meas(&UE_mac_inst[module_idP].rx_si); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN); - - LOG_D(MAC, "[UE %d] Frame %d Sending SI MBMS to RRC (LCID Id %d,len %d)\n", - module_idP, frameP, BCCH, len); - - mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe - SI_RNTI, - BCCH_SI_MBMS, (uint8_t *) pdu, len, eNB_index, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN); + LOG_D(MAC, "[UE %d] Frame %d Sending SI MBMS to RRC (LCID Id %d,len %d)\n", + module_idP, frameP, BCCH, len); + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe + SI_RNTI, + BCCH_SI_MBMS, (uint8_t *) pdu, len, eNB_index, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].rx_si); + stop_meas(&UE_mac_inst[module_idP].rx_si); #endif - trace_pdu(DIRECTION_UPLINK, - (uint8_t *) pdu, - len, - module_idP, - WS_SI_RNTI, - 0xffff, - UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); + trace_pdu(DIRECTION_UPLINK, + (uint8_t *) pdu, + len, + module_idP, + WS_SI_RNTI, + 0xffff, + UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); } #endif @@ -641,15 +636,14 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, #if UE_TIMING_TRACE stop_meas(&UE_mac_inst[module_idP].rx_si); #endif - - trace_pdu(DIRECTION_UPLINK, - (uint8_t *) pdu, - len, - module_idP, - WS_SI_RNTI, - 0xffff, - UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); + trace_pdu(DIRECTION_UPLINK, + (uint8_t *) pdu, + len, + module_idP, + WS_SI_RNTI, + 0xffff, + UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); } void @@ -672,15 +666,14 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, #if UE_TIMING_TRACE stop_meas(&UE_mac_inst[module_idP].rx_p); #endif - - trace_pdu(DIRECTION_UPLINK, - (uint8_t *) pdu, - len, - module_idP, - WS_SI_RNTI, - P_RNTI, - UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); + trace_pdu(DIRECTION_UPLINK, + (uint8_t *) pdu, + len, + module_idP, + WS_SI_RNTI, + P_RNTI, + UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -2440,11 +2433,10 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, #if UE_TIMING_TRACE stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); #endif - - trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].crnti, - UE_mac_inst[module_idP].txFrame, - UE_mac_inst[module_idP].txSubframe, 0, 0); + trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].crnti, + UE_mac_inst[module_idP].txFrame, + UE_mac_inst[module_idP].txSubframe, 0, 0); } diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index 98d099add8..5b3b6d5da6 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -22,45 +22,45 @@ extern UL_RCC_IND_t UL_RCC_INFO; uint16_t frame_cnt=0; void handle_rach(UL_IND_t *UL_info) { int i; - if(NFAPI_MODE == NFAPI_MODE_VNF){ - for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ - if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles>0) { - AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); - LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_RCC_INFO.rach_ind[j].sfn_sf)); - initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), - NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf), - UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble, - UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, - UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti + if(NFAPI_MODE == NFAPI_MODE_VNF) { + for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) { + if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles>0) { + AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); + LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_RCC_INFO.rach_ind[j].sfn_sf)); + initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf), + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble, + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 + ,0 #endif - ); - free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list); - UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0; - UL_RCC_INFO.rach_ind[j].header.message_id = 0; - } - } - }else{ - if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { - AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); - UL_info->rach_ind.rach_indication_body.number_of_preambles=0; - LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf)); - initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf), - NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf), - UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, - UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, - UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti + ); + free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list); + UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0; + UL_RCC_INFO.rach_ind[j].header.message_id = 0; + } + } + } else { + if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { + AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); + UL_info->rach_ind.rach_indication_body.number_of_preambles=0; + LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf)); + initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf), + NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf), + UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, + UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, + UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 + ,0 #endif - ); - } + ); + } } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -97,17 +97,18 @@ void handle_sr(UL_IND_t *UL_info) { if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) { oai_nfapi_sr_indication(&UL_info->sr_ind); } - } else if(NFAPI_MODE == NFAPI_MODE_VNF){ - for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ - if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0){ - for (i=0;i 0) { + for (i=0; imodule_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_RCC_INFO.sr_ind[j].sfn_sf), - NFAPI_SFNSF2SF(UL_RCC_INFO.sr_ind[j].sfn_sf), - UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti, - UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi); + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.sr_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.sr_ind[j].sfn_sf), + UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti, + UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi); } + free(UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list); UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs=0; UL_RCC_INFO.sr_ind[j].header.message_id = 0; @@ -134,14 +135,13 @@ void handle_cqi(UL_IND_t *UL_info) { LOG_D(PHY,"UL_info->cqi_ind.number_of_cqis:%d\n", UL_info->cqi_ind.cqi_indication_body.number_of_cqis); UL_info->cqi_ind.header.message_id = NFAPI_RX_CQI_INDICATION; UL_info->cqi_ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe; - oai_nfapi_cqi_indication(&UL_info->cqi_ind); UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; } } else if (NFAPI_MODE == NFAPI_MODE_VNF) { - for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ - if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0){ - for (i=0;i 0) { + for (i=0; imodule_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_RCC_INFO.cqi_ind[j].sfn_sf), @@ -159,15 +159,15 @@ void handle_cqi(UL_IND_t *UL_info) { } } } else { - for (i=0;icqi_ind.cqi_indication_body.number_of_cqis;i++) + for (i=0; icqi_ind.cqi_indication_body.number_of_cqis; i++) cqi_indication(UL_info->module_id, UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->cqi_ind.sfn_sf), - NFAPI_SFNSF2SF(UL_info->cqi_ind.sfn_sf), - UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti, - &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].cqi_indication_rel9, - UL_info->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[i].pdu, - &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].ul_cqi_information); + NFAPI_SFNSF2SFN(UL_info->cqi_ind.sfn_sf), + NFAPI_SFNSF2SF(UL_info->cqi_ind.sfn_sf), + UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti, + &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].cqi_indication_rel9, + UL_info->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[i].pdu, + &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].ul_cqi_information); UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; } @@ -183,15 +183,15 @@ void handle_harq(UL_IND_t *UL_info) { } UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; - }else if(NFAPI_MODE == NFAPI_MODE_VNF){ - for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ - if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0){ - for (int i=0;i 0) { + for (int i=0; imodule_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_RCC_INFO.harq_ind[j].sfn_sf), - NFAPI_SFNSF2SF(UL_RCC_INFO.harq_ind[j].sfn_sf), - &UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list[i]); + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.harq_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.harq_ind[j].sfn_sf), + &UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list[i]); } free(UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list); @@ -226,48 +226,52 @@ void handle_ulsch(UL_IND_t *UL_info) { oai_nfapi_rx_ind(&UL_info->rx_ind); UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } - } else if(NFAPI_MODE == NFAPI_MODE_VNF){ - for(uint8_t k = 0;k < NUM_NFPAI_SUBFRAME;k++){ - if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)){ - for (i=0;i0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) { + for (i=0; icrc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", - j,UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i,UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti); + j,UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i,UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti); + if (UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti == UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti) { LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", - j, UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag); + j, UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag); + if (UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); - rx_sdu(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, - NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - (uint8_t *)NULL, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + rx_sdu(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + (uint8_t *)NULL, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + } else { + LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); + rx_sdu(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } - else { - LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); - rx_sdu(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, - NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); - } - if(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data != NULL){ + + if(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data != NULL) { free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data); } + break; } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti) } // for (j=0;jcrc_ind.crc_indication_body.number_of_crcs;j++) } // for (i=0;irx_ind.number_of_pdus;i++) + free(UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list); free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list); UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs = 0; @@ -699,11 +703,11 @@ void UL_indication(UL_IND_t *UL_info) { Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; IF_Module_t *ifi = if_inst[module_id]; eNB_MAC_INST *mac = RC.mac[module_id]; - LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n", UL_info->frame,UL_info->subframe, module_id,CC_id, - UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.cqi_indication_body.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); + UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, + UL_info->cqi_ind.cqi_indication_body.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); if(UL_info->frame==1023&&UL_info->subframe==6) { // dl scheduling (0,0) frame_cnt= (frame_cnt + 1)%7; // to prevent frame_cnt get too big @@ -729,7 +733,6 @@ void UL_indication(UL_IND_t *UL_info) { handle_sr(UL_info); handle_cqi(UL_info); handle_harq(UL_info); - // clear HI prior to handling ULSCH uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_id], UL_info->subframe); diff --git a/openair2/UTIL/OPT/README.txt b/openair2/UTIL/OPT/README.txt index a8cbf10d82..2ac68f83fd 100644 --- a/openair2/UTIL/OPT/README.txt +++ b/openair2/UTIL/OPT/README.txt @@ -1,18 +1,20 @@ + How to configure wireshark for dissecting LTE protocols: - start the wireshark as a sudoers -- goto analyze->enabled prototols + - goto analyze->enabled prototols => enable mac_lte_udp and rlc_lte_udp -- goto edit/preferences and expand Protocols -- select UDP and check "try heuristic sub-dissectors first" -- select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info" -- select RLC-LTE, and check all the options except the "May see RLC headers only", and set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM. + - goto edit/preferences and expand Protocols + - select UDP and check "try heuristic sub-dissectors first" + - select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info" + - select RLC-LTE, and check all the options except the "May see RLC headers only", and + set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM. -How to use -- start eNB or UE with option --opt.type wireshark - --opt options are: - --opt.type none/wireshark/pcap - --opt.ip 127.0.0.1 to specify the output IP address (default: 127.0.0.1) - output port is always: 9999 (to change it, change constant: PACKET_MAC_LTE_DEFAULT_UDP_PORT in OAI code) - --opt.path file_name to specify the file name (pcap) -- capture on local interface "lo" -- filter out the ICMP/DNS/TCP messages (e.g. "!icmp && !dns && !tcp") + How to use + - start eNB or UE with option --opt.type wireshark + --opt options are: + --opt.type none/wireshark/pcap + --opt.ip 127.0.0.1 to specify the output IP address (default: 127.0.0.1) + output port is always: 9999 (to change it, change constant: PACKET_MAC_LTE_DEFAULT_UDP_PORT in OAI code) + --opt.path file_name to specify the file name (pcap) + - capture on local interface "lo" + - filter out the ICMP/DNS/TCP messages (e.g. "!icmp && !dns && !tcp") diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index 1dbb606252..85c25cf8ad 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -115,8 +115,8 @@ extern int opt_enabled; #define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(x) void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, - int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe, - int oob_event, int oob_event_value); + int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe, + int oob_event, int oob_event_value); int init_opt(void); diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index d5631032b9..88adb1b209 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -391,22 +391,21 @@ extern RAN_CONTEXT_t RC; #include /* Remote serveraddress (where Wireshark is running) */ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, - int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, - int oob_event_value) { + int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, + int oob_event_value) { MAC_Context_Info_t pdu_context; int radioType=FDD_RADIO; LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n", - direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber); + direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber); if (RC.eNB && RC.eNB[0][0]!=NULL) radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; - else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL) radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; - else { - LOG_E(OPT,"not a eNB neither a UE!!! \n"); - return; - } + else { + LOG_E(OPT,"not a eNB neither a UE!!! \n"); + return; + } switch (opt_type) { case OPT_WIRESHARK : diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 042dd52742..7a7e1a31f8 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -430,8 +430,9 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) { b->circularBuf[(index*nbAnt+a)%CirSize].i=0; } } + if ( abs(b->th.timestamp-b->lastReceivedTS) > 50 ) - LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); + LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); } b->lastReceivedTS=b->th.timestamp; diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index 07d6861d57..a523c66bb2 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -7,18 +7,21 @@ volatile int oai_exit = 0; -int fullread(int fd, void *_buf, int count) -{ +int fullread(int fd, void *_buf, int count) { char *buf = _buf; int ret = 0; int l; + while (count) { l = read(fd, buf, count); + if (l <= 0) return -1; + count -= l; buf += l; ret += l; } + return ret; } @@ -79,7 +82,6 @@ sin_addr: while(!connected) { //LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { //LOG_I(HW,"rfsimulator: connection established\n"); connected=true; @@ -144,7 +146,8 @@ int main(int argc, char *argv[]) { uint64_t wroteTS=header.timestamp; if (dataSize>bufSize) { - void * new_buff = realloc(buff, dataSize); + void *new_buff = realloc(buff, dataSize); + if (new_buff == NULL) { free(buff); AssertFatal(1, "Could not reallocate"); @@ -157,15 +160,17 @@ int main(int argc, char *argv[]) { fullwrite(serviceSock, buff, dataSize); // Purge incoming samples setblocking(serviceSock, blocking); + while(readTS < wroteTS) { - if ( fullread(serviceSock, &header,sizeof(header)) != sizeof(header) || - fullread(serviceSock, buff, sizeof(int32_t)*header.size*header.nbAnt) != - sizeof(int32_t)*header.size*header.nbAnt - ) { - printf("error: %s\n", strerror(errno)); - exit(1); - } - readTS=header.timestamp; + if ( fullread(serviceSock, &header,sizeof(header)) != sizeof(header) || + fullread(serviceSock, buff, sizeof(int32_t)*header.size*header.nbAnt) != + sizeof(int32_t)*header.size*header.nbAnt + ) { + printf("error: %s\n", strerror(errno)); + exit(1); + } + + readTS=header.timestamp; } } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index b1894be28f..9310d55595 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -152,19 +152,21 @@ static inline void fh_if5_south_out(RU_t *ru) { // southbound IF4p5 fronthaul static inline void fh_if4p5_south_out(RU_t *ru) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + LOG_D(PHY,"ENTERED fh_if4p5_south_out Sending IF4p5 for frame %d subframe %d ru %d\n",ru->proc.frame_tx,ru->proc.subframe_tx,ru->idx); + if (subframe_select(&ru->frame_parms,ru->proc.subframe_tx)!=SF_UL) { send_IF4p5(ru,ru->proc.frame_tx, ru->proc.subframe_tx, IF4p5_PDLFFT); ru->south_out_cnt++; LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt); } -/*if (ru == RC.ru[0] || ru == RC.ru[1]) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU+ru->idx, ru->proc.frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU+ru->idx, ru->proc.subframe_tx ); - }*/ -VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx,ru->proc.frame_tx); -VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx,ru->proc.subframe_tx); + /*if (ru == RC.ru[0] || ru == RC.ru[1]) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU+ru->idx, ru->proc.frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU+ru->idx, ru->proc.subframe_tx ); + }*/ + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx,ru->proc.frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx,ru->proc.subframe_tx); } /*************************************************************/ @@ -207,61 +209,67 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { uint32_t symbol_mask_full; int pultick_received=0; + if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) + symbol_mask_full = (1<ul_symbols_in_S_subframe)-1; + else + symbol_mask_full = (1<symbols_per_tti)-1; - if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) - symbol_mask_full = (1<ul_symbols_in_S_subframe)-1; - else - symbol_mask_full = (1<symbols_per_tti)-1; LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, ru %d, mask %x\n",ru->idx,*frame,*subframe,ru->idx,proc->symbol_mask[*subframe]); AssertFatal(proc->symbol_mask[*subframe]==0 || proc->symbol_mask[*subframe]==symbol_mask_full,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]); - if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished - do { - recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number); - LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf); - if (oai_exit == 1 || ru->cmd== STOP_RU) break; - if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<symbol_mask[sf] = symbol_mask_full; - pultick_received++; -/* - if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d (RU %d) \n",f,*frame, ru->idx); - else if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx); - else break; */ - if (f==*frame || sf==*subframe) break; - } else if (packet_type == IF4p5_PRACH) { - // nothing in RU for RAU - } - LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]); - } while(proc->symbol_mask[sf] != symbol_mask_full); - } - else { - f = *frame; - sf = *subframe; + + if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished + do { + recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number); + LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf); + + if (oai_exit == 1 || ru->cmd== STOP_RU) break; + + if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<symbol_mask[sf] = symbol_mask_full; + pultick_received++; + + /* + if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d (RU %d) \n",f,*frame, ru->idx); + else if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx); + else break; */ + if (f==*frame || sf==*subframe) break; + } else if (packet_type == IF4p5_PRACH) { + // nothing in RU for RAU + } + + LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]); + } while(proc->symbol_mask[sf] != symbol_mask_full); + } else { + f = *frame; + sf = *subframe; } + //calculate timestamp_rx, timestamp_tx based on frame and subframe proc->subframe_rx = sf; proc->frame_rx = f; proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ; + if (get_nprocs()<=4) { - proc->subframe_tx = (sf+sf_ahead)%10; - proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f; + proc->subframe_tx = (sf+sf_ahead)%10; + proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f; } LOG_D(PHY,"Setting proc for (%d,%d)\n",sf,f); if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ + if (proc->subframe_rx != *subframe) { LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d, symbol_mask %x)\n",proc->subframe_rx,*subframe,proc->symbol_mask[*subframe]); - *subframe=sf; + *subframe=sf; //exit_fun("Exiting"); } + if (ru->cmd != WAIT_RESYNCH && proc->frame_rx != *frame) { LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d,symbol_mask %x\n",proc->frame_rx,*frame,proc->symbol_mask[*subframe]); //exit_fun("Exiting"); - } - else if (ru->cmd == WAIT_RESYNCH && proc->frame_rx != *frame){ - ru->cmd=EMPTY; - *frame=proc->frame_rx; + } else if (ru->cmd == WAIT_RESYNCH && proc->frame_rx != *frame) { + ru->cmd=EMPTY; + *frame=proc->frame_rx; } } else { proc->first_rx = 0; @@ -272,12 +280,10 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { /*if (ru == RC.ru[0] || ru == RC.ru[1]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU+ru->idx, f ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU+ru->idx, sf ); - - }*/ + }*/ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,f); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,sf); - proc->symbol_mask[sf] = 0; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); LOG_D(PHY,"RU %d: fh_if4p5_south_in returning ...\n",ru->idx); @@ -311,6 +317,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) { recv_IF4p5(ru, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); if (ru->cmd == STOP_RU) break; + // grab first prach information for this new subframe if (got_prach_info==0) { prach_rx = is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx); @@ -365,12 +372,13 @@ void fh_if4p5_north_in(RU_t *ru,int *frame,int *subframe) { symbol_mask_full = (1<frame_parms.symbols_per_tti)-1; LOG_D(PHY,"fh_if4p5_north_in: frame %d, subframe %d\n",*frame,*subframe); - do { + do { recv_IF4p5(ru, frame, subframe, &packet_type, &symbol_number); symbol_mask = symbol_mask | (1<north_in_cnt++; + // dump VCD output for first RU in list if (ru == RC.ru[0]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, *frame ); @@ -387,10 +395,9 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { // printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); subframe_tx = (timestamp_tx/fp->samples_per_tti)%10; frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); - + if (proc->first_tx != 0) { *subframe = subframe_tx; *frame = frame_tx; @@ -401,6 +408,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { AssertFatal(frame_tx == *frame, "frame_tx %d is not what we expect %d\n",frame_tx,*frame); } + ru->north_in_cnt++; } @@ -411,26 +419,28 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { uint32_t symbol_number,symbol_mask,symbol_mask_full; int subframe_tx,frame_tx; int ret; - symbol_number = 0; symbol_mask = 0; symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_tti))-1; LOG_D(PHY,"fh_if4p5_north_asynch_in: RU %d, frame %d, subframe %d\n",ru->idx,*frame,*subframe); - do { + + do { recv_IF4p5(ru, &frame_tx, &subframe_tx, &packet_type, &symbol_number); LOG_D(PHY,"income frame.subframe %d.%d, our frame.subframe.symbol_number %d.%d.%d (symbol mask %x)\n",frame_tx,subframe_tx,*frame,*subframe,symbol_number,symbol_mask); - if (ru->cmd == STOP_RU){ + + if (ru->cmd == STOP_RU) { LOG_E(PHY,"Got STOP_RU\n"); AssertFatal((ret=pthread_mutex_lock(&proc->mutex_ru))==0,"mutex_lock returns %d\n",ret); proc->instance_cnt_ru = -1; AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_ru))==0,"mutex_unlock returns %d\n",ret); ru->cmd=STOP_RU; return; - } + } + if ((subframe_select(fp,subframe_tx) == SF_DL) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n", - *subframe,subframe_select(fp,*subframe),frame_tx,subframe_tx,symbol_number); + *subframe,subframe_select(fp,*subframe),frame_tx,subframe_tx,symbol_number); if (proc->first_tx != 0) { *frame = frame_tx; @@ -438,25 +448,23 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { proc->first_tx = 0; symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_tti))-1; } else { - /* AssertFatal(frame_tx == *frame, - "frame_tx %d is not what we expect %d\n",frame_tx,*frame); - AssertFatal(subframe_tx == *subframe, - "In frame_tx %d : subframe_tx %d is not what we expect %d\n",frame_tx,subframe_tx,*subframe); - */ + /* AssertFatal(frame_tx == *frame, + "frame_tx %d is not what we expect %d\n",frame_tx,*frame); + AssertFatal(subframe_tx == *subframe, + "In frame_tx %d : subframe_tx %d is not what we expect %d\n",frame_tx,subframe_tx,*subframe); + */ *frame = frame_tx; *subframe = subframe_tx; } if (packet_type == IF4p5_PDLFFT) { symbol_mask = symbol_mask | (1<rx_fhaul); ru->north_in_cnt++; - proc->subframe_tx = subframe_tx; proc->frame_tx = frame_tx; @@ -464,6 +472,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { proc->timestamp_tx = ((((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * 10) + (uint64_t)subframe_tx) * (uint64_t)fp->samples_per_tti; LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,subframe_tx); + // dump VCD output for first RU in list if (ru == RC.ru[0]) { /*VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); @@ -473,7 +482,6 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_NORTH_ASYNCH_IN,subframe_tx); } - if (ru->feptx_ofdm) ru->feptx_ofdm(ru); if (ru->fh_south_out) ru->fh_south_out(ru); @@ -493,11 +501,14 @@ void fh_if4p5_north_out(RU_t *ru) { RU_proc_t *proc=&ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; const int subframe = proc->subframe_rx; - if (ru->idx==0){ - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_NORTH_OUT, proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_NORTH_OUT, proc->frame_rx ); + + if (ru->idx==0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_NORTH_OUT, proc->subframe_rx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_NORTH_OUT, proc->frame_rx ); } + LOG_D(PHY,"fh_if4p5_north_out: Sending IF4p5_PULFFT SFN.SF %d.%d\n",proc->frame_rx,proc->subframe_rx); + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { /// **** in TDD during DL send_IF4 of ULTICK to RCC **** /// send_IF4p5(ru, proc->frame_rx, proc->subframe_rx, IF4p5_PULTICK); @@ -537,7 +548,6 @@ static void *emulatedRF_thread(void *param) { pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); int policy; int ret; - struct sched_param sparam; memset(&sparam, 0, sizeof(sparam)); sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); @@ -568,12 +578,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { void *rxp[ru->nb_rx]; unsigned int rxs; int i; - - int resynch=0; - - openair0_timestamp ts=0,old_ts=0; + for (i=0; inb_rx; i++) rxp[i] = (void *)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; @@ -593,19 +600,20 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - ru->south_in_cnt++; LOG_D(PHY,"south_in_cnt %d\n",ru->south_in_cnt); if (ru->cmd==RU_FRAME_RESYNCH) { LOG_I(PHY,"Applying frame resynch %d => %d\n",*frame,ru->cmdval); + if (proc->frame_rx>ru->cmdval) ru->ts_offset += (proc->frame_rx - ru->cmdval)*fp->samples_per_tti*10; else ru->ts_offset -= (-proc->frame_rx + ru->cmdval)*fp->samples_per_tti*10; + *frame = ru->cmdval; ru->cmd=EMPTY; resynch=1; } - + proc->timestamp_rx = ts-ru->ts_offset; // AssertFatal(rxs == fp->samples_per_tti, @@ -618,19 +626,16 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { if (proc->first_rx == 1) { ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; - } - else if (resynch==0 && (proc->timestamp_rx - old_ts != fp->samples_per_tti)) { + } else if (resynch==0 && (proc->timestamp_rx - old_ts != fp->samples_per_tti)) { LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); proc->timestamp_rx = ts-ru->ts_offset; } - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; // synchronize first reception to frame 0 subframe 0 - if (ru->fh_north_asynch_in == NULL) { #ifdef PHY_TX_THREAD proc->timestamp_phy_tx = proc->timestamp_rx+((sf_ahead-1)*fp->samples_per_tti); @@ -638,23 +643,24 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { proc->frame_phy_tx = (proc->subframe_rx>(9-(sf_ahead-1))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; #endif LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n", - ru->idx, - 0, - (unsigned long long int)proc->timestamp_rx, - (int)ru->ts_offset,proc->frame_rx,proc->subframe_rx); - + ru->idx, + 0, + (unsigned long long int)proc->timestamp_rx, + (int)ru->ts_offset,proc->frame_rx,proc->subframe_rx); LOG_D(PHY,"south_in/rx_rf: RU %d/%d TS %llu (off %d), frame %d, subframe %d\n", - ru->idx, - 0, - (unsigned long long int)proc->timestamp_rx, - (int)ru->ts_offset,proc->frame_rx,proc->subframe_rx); + ru->idx, + 0, + (unsigned long long int)proc->timestamp_rx, + (int)ru->ts_offset,proc->frame_rx,proc->subframe_rx); + // dump VCD output for first RU in list if (ru == RC.ru[0]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); + if (ru->fh_north_asynch_in == NULL) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); } } } @@ -700,7 +706,6 @@ void tx_rf(RU_t *ru) { lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10); lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10); int sf_extension = 0; - if ((SF_type == SF_DL) || (SF_type == SF_S)) { @@ -780,17 +785,18 @@ void tx_rf(RU_t *ru) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); + proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + ru->nb_tx, + flags); ru->south_out_cnt++; LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt); int se = dB_fixed(signal_energy(txp[0],siglen+sf_extension)); if (SF_type == SF_S) LOG_D(PHY,"[TXPATH] RU %d tx_rf (en %d,len %d), writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,se,siglen+sf_extension, - (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx); + (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); // AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); @@ -818,9 +824,7 @@ void *ru_thread_asynch_rxtx( void *param ) { wait_sync("ru_thread_asynch_rxtx"); // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe LOG_I(PHY, "waiting for devices (ru_thread_asynch_rxtx)\n"); - wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); - LOG_I(PHY, "devices ok (ru_thread_asynch_rxtx)\n"); while (!oai_exit) { @@ -830,24 +834,25 @@ void *ru_thread_asynch_rxtx( void *param ) { subframe=0; frame=0; usleep(1000); - } - else { - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } + } else { + if (subframe==9) { + subframe=0; + frame++; + frame&=1023; + } else { + subframe++; + } + LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); + // asynchronous receive from north (RRU IF4/IF5) if (ru->fh_north_asynch_in) { - if (subframe_select(&ru->frame_parms,subframe)!=SF_UL) - ru->fh_north_asynch_in(ru,&frame,&subframe); - } - else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); + if (subframe_select(&ru->frame_parms,subframe)!=SF_UL) + ru->fh_north_asynch_in(ru,&frame,&subframe); + } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); } } + ru_thread_asynch_rxtx_status=0; return(&ru_thread_asynch_rxtx_status); } @@ -862,18 +867,17 @@ void wakeup_slaves(RU_proc_t *proc) { for (i=0; inum_slaves; i++) { RU_proc_t *slave_proc = proc->slave_proc[i]; - // wake up slave FH thread // lock the FH mutex and make sure the thread is ready clock_gettime(CLOCK_REALTIME,&wait); wait.tv_nsec += time_ns; - if(wait.tv_nsec >= 1000*1000*1000) - { + + if(wait.tv_nsec >= 1000*1000*1000) { wait.tv_nsec -= 1000*1000*1000; wait.tv_sec += 1; } - AssertFatal((ret=pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait))==0,"ERROR pthread_mutex_lock for RU %d slave %d (IC %d)\n",proc->ru->idx,slave_proc->ru->idx,slave_proc->instance_cnt_FH); + AssertFatal((ret=pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait))==0,"ERROR pthread_mutex_lock for RU %d slave %d (IC %d)\n",proc->ru->idx,slave_proc->ru->idx,slave_proc->instance_cnt_FH); int cnt_slave = ++slave_proc->instance_cnt_FH; slave_proc->frame_rx = proc->frame_rx; slave_proc->subframe_rx = proc->subframe_rx; @@ -884,9 +888,9 @@ void wakeup_slaves(RU_proc_t *proc) { if (cnt_slave == 0) { // the thread was presumably waiting where it should and can now be woken up if (pthread_cond_signal(&slave_proc->cond_FH) != 0) { - LOG_E( PHY, "ERROR pthread_cond_signal for RU %d, slave RU %d\n",proc->ru->idx,slave_proc->ru->idx); - exit_fun( "ERROR pthread_cond_signal" ); - break; + LOG_E( PHY, "ERROR pthread_cond_signal for RU %d, slave RU %d\n",proc->ru->idx,slave_proc->ru->idx); + exit_fun( "ERROR pthread_cond_signal" ); + break; } } else { LOG_W( PHY,"[RU] Frame %d, slave %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->ru->idx, cnt_slave); @@ -937,7 +941,7 @@ void *ru_thread_prach( void *param ) { NULL, NULL, NULL, - NULL, + NULL, proc->frame_prach, 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -976,7 +980,7 @@ void *ru_thread_prach_br( void *param ) { NULL, NULL, NULL, - NULL, + NULL, proc->frame_prach_br, 0, 1); @@ -994,18 +998,17 @@ int wakeup_synch(RU_t *ru) { int ret; struct timespec wait; int time_ns = 5000000L; - // wake up synch thread // lock the synch mutex and make sure the thread is readif (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) { clock_gettime(CLOCK_REALTIME,&wait); wait.tv_nsec += time_ns; - if(wait.tv_nsec >= 1000*1000*1000) - { + + if(wait.tv_nsec >= 1000*1000*1000) { wait.tv_nsec -= 1000*1000*1000; wait.tv_sec += 1; } - AssertFatal((ret=pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait)) == 0,"[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch ); + AssertFatal((ret=pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait)) == 0,"[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch ); ++ru->proc.instance_cnt_synch; // the thread can now be woken up @@ -1051,6 +1054,7 @@ void do_ru_synch(RU_t *ru) { ru->nb_rx); if (rxs != fp->samples_per_tti*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_tti*10,rxs); + // wakeup synchronization processing thread wakeup_synch(ru); ic=0; @@ -1077,79 +1081,79 @@ void do_ru_synch(RU_t *ru) { // read in rx_offset samples LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset); rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - ru->rx_offset, - ru->nb_rx); + &(proc->timestamp_rx), + rxp, + ru->rx_offset, + ru->nb_rx); // Verification of synchronization procedure ru->state = RU_CHECK_SYNC; - LOG_I(PHY,"Exiting synch routine\n"); } -int check_sync(RU_t *ru, RU_t *ru_master, int subframe){ +int check_sync(RU_t *ru, RU_t *ru_master, int subframe) { + if (fabs(ru_master->proc.t[subframe].tv_nsec - ru->proc.t[subframe].tv_nsec) > 500000) + return 0; - if (fabs(ru_master->proc.t[subframe].tv_nsec - ru->proc.t[subframe].tv_nsec) > 500000) - return 0; - return 1; + return 1; } void wakeup_L1s(RU_t *ru) { int i; PHY_VARS_eNB **eNB_list = ru->eNB_list; LOG_D(PHY,"wakeup_L1s (num %d) for RU %d (%d.%d)\n",ru->num_eNB,ru->idx, ru->proc.frame_rx,ru->proc.subframe_rx); - PHY_VARS_eNB *eNB=eNB_list[0]; L1_proc_t *proc = &eNB->proc; struct timespec t; LOG_D(PHY,"wakeup_L1s (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); - // call eNB function directly char string[20]; sprintf(string,"Incoming RU %d",ru->idx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx); - AssertFatal(0==pthread_mutex_lock(&proc->mutex_RU),""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 1 ); - //printf("wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n", // ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,ru->wait_cnt,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx]); // VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx); // VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx); clock_gettime(CLOCK_MONOTONIC,&ru->proc.t[ru->proc.subframe_rx]); - - if (proc->RU_mask[ru->proc.subframe_rx] == 0){ + + if (proc->RU_mask[ru->proc.subframe_rx] == 0) { //clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]); proc->t[ru->proc.subframe_rx] = ru->proc.t[ru->proc.subframe_rx]; //start_meas(&proc->ru_arrival_time); LOG_D(PHY,"RU %d starting timer for frame %d subframe %d\n",ru->idx, ru->proc.frame_rx,ru->proc.subframe_rx); } - - for (i=0;inum_RU;i++) { + + for (i=0; inum_RU; i++) { if (eNB->RU_list[i]->wait_cnt==1 && ru->proc.subframe_rx!=9) eNB->RU_list[i]->wait_cnt=0; + LOG_D(PHY,"RU %d has frame %d and subframe %d, state %s\n",eNB->RU_list[i]->idx,eNB->RU_list[i]->proc.frame_rx, eNB->RU_list[i]->proc.subframe_rx, ru_states[eNB->RU_list[i]->state]); + if (ru == eNB->RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) { - // AssertFatal((proc->RU_mask&(1<Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask); + // AssertFatal((proc->RU_mask&(1<Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask); proc->RU_mask[ru->proc.subframe_rx] |= (1<RU_list[i]->state == RU_SYNC || */ - (eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0)){ + } else if (/*eNB->RU_list[i]->state == RU_SYNC || */ + (eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0)) { proc->RU_mask[ru->proc.subframe_rx] |= (1<cnt %d, i->cnt %d\n",ru->idx,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.subframe_rx]); + if (ru->is_slave == 0 && ( (proc->RU_mask[ru->proc.subframe_rx]&(1<RU_list[i]->state == RU_RUN) { // This is master & the RRU has already been received if (check_sync(eNB->RU_list[i],eNB->RU_list[0],ru->proc.subframe_rx) == 0) - LOG_E(PHY,"RU %d is not SYNC, subframe %d, time %f this is master\n", eNB->RU_list[i]->idx, ru->proc.subframe_rx, fabs(eNB->RU_list[i]->proc.t[ru->proc.subframe_rx].tv_nsec - eNB->RU_list[0]->proc.t[ru->proc.subframe_rx].tv_nsec)); - }else if (ru->is_slave == 1 && ru->state == RU_RUN && ( (proc->RU_mask[ru->proc.subframe_rx]&(1<<0)) == 1)){ // master already received. TODO: we assume that RU0 is master. + LOG_E(PHY,"RU %d is not SYNC, subframe %d, time %f this is master\n", eNB->RU_list[i]->idx, ru->proc.subframe_rx, + fabs(eNB->RU_list[i]->proc.t[ru->proc.subframe_rx].tv_nsec - eNB->RU_list[0]->proc.t[ru->proc.subframe_rx].tv_nsec)); + } else if (ru->is_slave == 1 && ru->state == RU_RUN && ( (proc->RU_mask[ru->proc.subframe_rx]&(1<<0)) == 1)) { // master already received. TODO: we assume that RU0 is master. if (check_sync(ru,eNB->RU_list[0],ru->proc.subframe_rx) == 0) - LOG_E(PHY,"RU %d is not SYNC time, subframe %d, time %f\n", ru->idx, ru->proc.subframe_rx, fabs(ru->proc.t[ru->proc.subframe_rx].tv_nsec - eNB->RU_list[0]->proc.t[ru->proc.subframe_rx].tv_nsec)); + LOG_E(PHY,"RU %d is not SYNC time, subframe %d, time %f\n", ru->idx, ru->proc.subframe_rx, fabs(ru->proc.t[ru->proc.subframe_rx].tv_nsec - eNB->RU_list[0]->proc.t[ru->proc.subframe_rx].tv_nsec)); } } + //clock_gettime(CLOCK_MONOTONIC,&t); //LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.subframe_rx], t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec); - + if (proc->RU_mask[ru->proc.subframe_rx] == (1<num_RU)-1) { // all RUs have provided their information so continue on and wakeup eNB top LOG_D(PHY,"ru_mask is %d \n ", proc->RU_mask[ru->proc.subframe_rx]); LOG_D(PHY,"the number of RU is %d, the current ru is RU %d \n ", (1<num_RU)-1, ru->idx); @@ -1160,29 +1164,30 @@ void wakeup_L1s(RU_t *ru) { clock_gettime(CLOCK_MONOTONIC,&t); //stop_meas(&proc->ru_arrival_time); /* AssertFatal(t.tv_nsec < proc->t[ru->proc.subframe_rx].tv_nsec+5000000, - "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n", - ru->proc.subframe_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec, ru->idx); + "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n", + ru->proc.subframe_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec, ru->idx); */ // VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx); //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx); AssertFatal(0==pthread_mutex_unlock(&proc->mutex_RU),""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 0 ); - // unlock RUs that are waiting for eNB processing to be completed LOG_D(PHY,"RU %d wakeup eNB top for subframe %d\n", ru->idx,ru->proc.subframe_rx); + if (ru->wait_cnt == 0) { if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) - ru->eNB_top(eNB_list[0],proc->frame_rx,proc->subframe_rx,string,ru); + ru->eNB_top(eNB_list[0],proc->frame_rx,proc->subframe_rx,string,ru); else { - for (i=0;inum_eNB;i++) { - eNB_list[i]->proc.ru_proc = &ru->proc; - if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) - { - LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); - } - } + for (i=0; inum_eNB; i++) { + eNB_list[i]->proc.ru_proc = &ru->proc; + + if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) { + LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); + } + } } } + /* AssertFatal(0==pthread_mutex_lock(&ruproc->mutex_eNBs),""); LOG_D(PHY,"RU %d sending signal to unlock waiting ru_threads\n", ru->idx); @@ -1190,33 +1195,30 @@ void wakeup_L1s(RU_t *ru) { if (ruproc->instance_cnt_eNBs==-1) ruproc->instance_cnt_eNBs++; AssertFatal(0==pthread_mutex_unlock(&ruproc->mutex_eNBs),""); */ - } - else{ // not all RUs have provided their information + } else { // not all RUs have provided their information AssertFatal(0==pthread_mutex_unlock(&proc->mutex_RU),""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 0 ); } -// pthread_mutex_unlock(&proc->mutex_RU); -// LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx); -// ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); - ru->proc.emulate_rf_busy = 0; - + // pthread_mutex_unlock(&proc->mutex_RU); + // LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx); + // ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); + ru->proc.emulate_rf_busy = 0; } void wakeup_prach_ru(RU_t *ru) { int ret; struct timespec wait; int time_ns = 5000000L; - clock_gettime(CLOCK_REALTIME,&wait); wait.tv_nsec += time_ns; - if(wait.tv_nsec >= 1000*1000*1000) - { + + if(wait.tv_nsec >= 1000*1000*1000) { wait.tv_nsec -= 1000*1000*1000; wait.tv_sec += 1; } - AssertFatal((ret=pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait)) == 0,"[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach); + AssertFatal((ret=pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait)) == 0,"[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach); if (ru->proc.instance_cnt_prach==-1) { ++ru->proc.instance_cnt_prach; @@ -1242,17 +1244,15 @@ void wakeup_prach_ru_br(RU_t *ru) { int ret; struct timespec wait; int time_ns = 5000000L; - - clock_gettime(CLOCK_REALTIME,&wait); wait.tv_nsec += time_ns; - if(wait.tv_nsec >= 1000*1000*1000) - { + + if(wait.tv_nsec >= 1000*1000*1000) { wait.tv_nsec -= 1000*1000*1000; wait.tv_sec += 1; } - AssertFatal((ret=pthread_mutex_timedlock(&ru->proc.mutex_prach_br,&wait))==0,"[RU] ERROR pthread_mutex_lock for RU prach thread BR (IC %d)\n", ru->proc.instance_cnt_prach_br); + AssertFatal((ret=pthread_mutex_timedlock(&ru->proc.mutex_prach_br,&wait))==0,"[RU] ERROR pthread_mutex_lock for RU prach thread BR (IC %d)\n", ru->proc.instance_cnt_prach_br); if (ru->proc.instance_cnt_prach_br==-1) { ++ru->proc.instance_cnt_prach_br; @@ -1322,7 +1322,6 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->rx_bw = 1.5e6; } else AssertFatal(1==0,"Unknown N_RB_DL %d\n",fp->N_RB_DL); - if (fp->frame_type==TDD) cfg->duplex_mode = duplex_mode_TDD; else //FDD @@ -1430,30 +1429,33 @@ int setup_RU_buffers(RU_t *ru) { return(0); } -void* ru_stats_thread(void* param) { - - RU_t *ru = (RU_t*)param; - +void *ru_stats_thread(void *param) { + RU_t *ru = (RU_t *)param; wait_sync("ru_stats_thread"); - + while (!oai_exit) { sleep(1); + if (opp_enabled) { if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); + if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); + if (ru->fh_north_out) { - print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); - print_meas(&ru->compression,"compression",NULL,NULL); - print_meas(&ru->transport,"transport",NULL,NULL); - LOG_I(PHY,"ru->north_out_cnt = %d\n",ru->north_out_cnt); + print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); + print_meas(&ru->compression,"compression",NULL,NULL); + print_meas(&ru->transport,"transport",NULL,NULL); + LOG_I(PHY,"ru->north_out_cnt = %d\n",ru->north_out_cnt); } + if (ru->fh_south_out) LOG_I(PHY,"ru->south_out_cnt = %d\n",ru->south_out_cnt); + if (ru->fh_north_asynch_in) LOG_I(PHY,"ru->north_in_cnt = %d\n",ru->north_in_cnt); - } } - + return(NULL); } @@ -1486,7 +1488,6 @@ void *ru_thread_tx( void *param ) { LOG_D(PHY,"ru_thread_tx (ru %d): Waiting for TX processing\n",ru->idx); // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); - LOG_D(PHY,"ru_thread_tx: TX in %d.%d\n",ru->proc.frame_tx,ru->proc.subframe_tx); if (oai_exit) break; @@ -1501,6 +1502,7 @@ void *ru_thread_tx( void *param ) { // do outgoing fronthaul (south) if needed if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); } + LOG_D(PHY,"ru_thread_tx: releasing RU TX in %d.%d\n",proc->frame_tx,proc->subframe_tx); release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); @@ -1508,34 +1510,35 @@ void *ru_thread_tx( void *param ) { eNB = ru->eNB_list[i]; eNB_proc = &eNB->proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc; - AssertFatal((ret=pthread_mutex_lock(&eNB_proc->mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); + for (int j=0; jnum_RU; j++) { if (ru == eNB->RU_list[j]) { if ((eNB_proc->RU_mask_tx&(1< 0) LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx); + eNB_proc->RU_mask_tx |= (1<RU_list[j]->state==RU_SYNC ||*/ (eNB->RU_list[j]->is_slave==1 && eNB->RU_list[j]->wait_cnt>0 && ru!=eNB->RU_list[j] && ru->is_slave==0)) { eNB_proc->RU_mask_tx |= (1<RU_list[j]->state==RU_SYNC ||*/ (eNB->RU_list[j]->is_slave==1 && eNB->RU_list[j]->wait_cnt>0 && ru!=eNB->RU_list[j] && ru->is_slave==0)){ - eNB_proc->RU_mask_tx |= (1<RU_mask_tx); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_TX_RU, eNB_proc->RU_mask_tx); } + if (eNB_proc->RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - //printf("Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU); + //printf("Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU); AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); } else { // all RUs TX are finished so send the ready signal to eNB processing eNB_proc->RU_mask_tx = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_TX_RU, eNB_proc->RU_mask_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_TX_RU, eNB_proc->RU_mask_tx); AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); AssertFatal((ret=pthread_mutex_lock( &L1_proc->mutex_RUs))==0,"mutex_lock returns %d\n",ret); L1_proc->instance_cnt_RUs = 0; - LOG_D(PHY,"ru_thread_tx: Signaling RU TX done in %d.%d\n",proc->frame_tx,proc->subframe_tx); // the thread can now be woken up - LOG_D(PHY,"ru_thread_tx: clearing mask and Waking up L1 thread\n"); + LOG_D(PHY,"ru_thread_tx: clearing mask and Waking up L1 thread\n"); + if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); @@ -1544,8 +1547,9 @@ void *ru_thread_tx( void *param ) { AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex_RUs))==0,"mutex_unlock returns %d\n",ret); } } + //printf("ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n", - // eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx); + // eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx); } release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); @@ -1563,7 +1567,6 @@ void *ru_thread( void *param ) { cpu_set_t cpuset; CPU_ZERO(&cpuset); // set default return value - #if defined(PRE_SCD_THREAD) dlsch_ue_select_tbl_in_use = 1; #endif @@ -1574,105 +1577,100 @@ void *ru_thread( void *param ) { pthread_setname_np( pthread_self(),"ru thread"); LOG_I(PHY,"thread ru created id=%ld\n", syscall(__NR_gettid)); LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); - + if(get_softmodem_params()->emulate_rf) { fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); phy_init_RU(ru); - + if (setup_RU_buffers(ru)!=0) { printf("Exiting, cannot initialize RU Buffers\n"); exit(-1); } - + LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx); AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret); RC.ru_mask &= ~(1<idx); pthread_cond_signal(&RC.ru_cond); AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret); ru->state = RU_RUN; - } - else if (ru->has_ctrl_prt == 0){ + } else if (ru->has_ctrl_prt == 0) { // There is no control port: start everything here LOG_I(PHY, "RU %d has not ctrl port\n",ru->idx); - if (ru->if_south == LOCAL_RF){ + + if (ru->if_south == LOCAL_RF) { fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); ru->frame_parms.nb_antennas_rx = ru->nb_rx; phy_init_RU(ru); - - openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - + if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); } + AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret); RC.ru_mask &= ~(1<idx); pthread_cond_signal(&RC.ru_cond); AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret); } + AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret); RC.ru_mask &= ~(1<idx); pthread_cond_signal(&RC.ru_cond); AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret); - ru->state = RU_RUN; - - } - + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_FH1))==0,"mutex_lock returns %d\n",ret); proc->instance_cnt_FH1 = 0; pthread_cond_signal(&proc->cond_FH1); AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_FH1))==0,"mutex_unlock returns %d\n",ret); while (!oai_exit) { - if (ru->if_south != LOCAL_RF && ru->is_slave==1) { ru->wait_cnt = 100; - } - else { + } else { ru->wait_cnt = 0; ru->wait_check = 0; } - - + // wait to be woken up if (ru->function!=eNodeB_3GPP && ru->has_ctrl_prt == 1) { if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break; - } - else wait_sync("ru_thread"); - + } else wait_sync("ru_thread"); + if(!(get_softmodem_params()->emulate_rf)) { if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]); - else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN || ru->state == RU_CHECK_SYNC,"ru %d state = %s != RU_SYNC or RU_RUN or RU_CHECK_SYNC\n",ru->idx,ru_states[ru->state]); + else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN || + ru->state == RU_CHECK_SYNC,"ru %d state = %s != RU_SYNC or RU_RUN or RU_CHECK_SYNC\n",ru->idx,ru_states[ru->state]); + // Start RF device if any if (ru->start_rf) { - if (ru->start_rf(ru) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); - } - else LOG_D(PHY,"RU %d no rf device\n",ru->idx); + if (ru->start_rf(ru) != 0) + LOG_E(HW,"Could not start the RF device\n"); + else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); + } else LOG_D(PHY,"RU %d no rf device\n",ru->idx); } + // if an asnych_rxtx thread exists // wakeup the thread because the devices are ready at this point - + if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { AssertFatal((ret=pthread_mutex_lock(&proc->mutex_asynch_rxtx))==0,"mutex_lock returns %d\n",ret); proc->instance_cnt_asynch_rxtx=0; pthread_cond_signal(&proc->cond_asynch_rxtx); AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_asynch_rxtx))==0,"mutex_unlock returns %d\n",ret); } else LOG_D(PHY,"RU %d no asynch_south interface\n",ru->idx); - + // if this is a slave RRU, try to synchronize on the DL frequency if ((ru->is_slave == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); - + LOG_D(PHY,"Starting steady-state operation\n"); + // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) { - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. if (subframe==9) { @@ -1682,159 +1680,159 @@ void *ru_thread( void *param ) { } else { subframe++; } - + // synchronization on input FH interface, acquire signals/data and block if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); - -#ifdef PHY_TX_THREAD - if(first_phy_tx == 0) - { - phy_tx_end = 0; - phy_tx_txdataF_end = 0; - AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_phy_tx))==0,"[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx); - if (ru->proc.instance_cnt_phy_tx==-1) { - ++ru->proc.instance_cnt_phy_tx; - - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n"); - }else{ - LOG_E(PHY,"phy tx thread busy, skipping\n"); - ++ru->proc.instance_cnt_phy_tx; - } - AssertFatal((ret=pthread_mutex_unlock( &ru->proc.mutex_phy_tx ))==0,"mutex_unlock returns %d\n",ret); - } else { +#ifdef PHY_TX_THREAD + + if(first_phy_tx == 0) { + phy_tx_end = 0; + phy_tx_txdataF_end = 0; + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_phy_tx))==0,"[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx); + + if (ru->proc.instance_cnt_phy_tx==-1) { + ++ru->proc.instance_cnt_phy_tx; + // the thread can now be woken up + AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n"); + } else { + LOG_E(PHY,"phy tx thread busy, skipping\n"); + ++ru->proc.instance_cnt_phy_tx; + } + + AssertFatal((ret=pthread_mutex_unlock( &ru->proc.mutex_phy_tx ))==0,"mutex_unlock returns %d\n",ret); + } else { phy_tx_end = 1; phy_tx_txdataF_end = 1; } + first_phy_tx = 0; #endif - + if (ru->stop_rf && ru->cmd == STOP_RU) { ru->stop_rf(ru); ru->state = RU_IDLE; ru->cmd = EMPTY; LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); break; - } - else if (ru->cmd == STOP_RU) { + } else if (ru->cmd == STOP_RU) { ru->state = RU_IDLE; ru->cmd = EMPTY; LOG_I(PHY,"RU %d stopped\n",ru->idx); break; } + if (oai_exit == 1) break; - + if (ru->wait_cnt > 0) { - ru->wait_cnt--; LOG_D(PHY,"RU thread %d, frame %d, subframe %d, wait_cnt %d \n",ru->idx, frame, subframe, ru->wait_cnt); - + if (ru->if_south!=LOCAL_RF && ru->wait_cnt <=20 && subframe == 5 && frame != RC.ru[0]->proc.frame_rx && resynch_done == 0) { - // Send RRU_frame adjust + // Send RRU_frame adjust RRU_CONFIG_msg_t rru_config_msg; rru_config_msg.type = RRU_frame_resynch; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len - ((uint16_t*)&rru_config_msg.msg[0])[0] = RC.ru[0]->proc.frame_rx; + ((uint16_t *)&rru_config_msg.msg[0])[0] = RC.ru[0]->proc.frame_rx; ru->cmd=WAIT_RESYNCH; LOG_I(PHY,"Sending Frame Resynch %d to RRU %d\n", RC.ru[0]->proc.frame_rx,ru->idx); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU\n"); resynch_done=1; } + wakeup_L1s(ru); - } - else { - + } else { LOG_D(PHY,"RU thread %d, frame %d, subframe %d \n", ru->idx,frame,subframe); - + if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) { LOG_D(PHY,"Waking up prach for %d.%d\n",proc->frame_rx,proc->subframe_rx); wakeup_prach_ru(ru); } - - + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) wakeup_prach_ru_br(ru); + #endif - - // adjust for timing offset between RU - if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; - - // At this point, all information for subframe has been received on FH interface - // If this proc is to provide synchronization, do so - wakeup_slaves(proc); - + + // adjust for timing offset between RU + if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; + + // At this point, all information for subframe has been received on FH interface + // If this proc is to provide synchronization, do so + wakeup_slaves(proc); + // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru); - + if (ru->feprx) ru->feprx(ru); + // wakeup all eNB processes waiting for this RU AssertFatal((ret=pthread_mutex_lock(&proc->mutex_eNBs))==0,"mutex_lock returns %d\n",ret); - if (proc->instance_cnt_eNBs==0) proc->instance_cnt_eNBs--; + + if (proc->instance_cnt_eNBs==0) proc->instance_cnt_eNBs--; + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_eNBs))==0,"mutex_unlock returns %d\n",ret); - #if defined(PRE_SCD_THREAD) - new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; - dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; - memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; + dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; + memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd\n"); - - ru->proc.instance_pre_scd++; - - if (ru->proc.instance_pre_scd == 0) { - if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); - exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); - } - }else{ - LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", - frame,subframe,ru->proc.instance_pre_scd ); - } + ru->proc.instance_pre_scd++; - AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_pre_scd))==0,"[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); + if (ru->proc.instance_pre_scd == 0) { + if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); + exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); + } + } else { + LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", + frame,subframe,ru->proc.instance_pre_scd ); + } + AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_pre_scd))==0,"[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); #endif - // wakeup all eNB processes waiting for this RU - if (ru->num_eNB>0) wakeup_L1s(ru); - + + // wakeup all eNB processes waiting for this RU + if (ru->num_eNB>0) wakeup_L1s(ru); + #ifndef PHY_TX_THREAD - - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0) { - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); - - // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - - if(!(get_softmodem_params()->emulate_rf)) { - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - - if ((ru->fh_north_out) && (ru->state!=RU_CHECK_SYNC)) ru->fh_north_out(ru); - } - - proc->emulate_rf_busy = 0; - } - + + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0) { + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + + if(!(get_softmodem_params()->emulate_rf)) { + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if ((ru->fh_north_out) && (ru->state!=RU_CHECK_SYNC)) ru->fh_north_out(ru); + } + + proc->emulate_rf_busy = 0; + } + #else - struct timespec time_req, time_rem; - time_req.tv_sec = 0; - time_req.tv_nsec = 10000; - - while((!oai_exit)&&(phy_tx_end == 0)){ - nanosleep(&time_req,&time_rem); - continue; - } + struct timespec time_req, time_rem; + time_req.tv_sec = 0; + time_req.tv_nsec = 10000; + + while((!oai_exit)&&(phy_tx_end == 0)) { + nanosleep(&time_req,&time_rem); + continue; + } + #endif } // else wait_cnt == 0 } // ru->state = RU_RUN } // while !oai_exit - + printf( "Exiting ru_thread \n"); - + if (!(get_softmodem_params()->emulate_rf)) { if (ru->stop_rf != NULL) { if (ru->stop_rf(ru) != 0) @@ -1842,9 +1840,8 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); } } - - return NULL; + return NULL; } @@ -1856,7 +1853,6 @@ void *ru_thread_synch(void *arg) { int64_t avg; static int ru_thread_synch_status=0; int cnt=0; - thread_top_init("ru_thread_synch",0,5000000,10000000,10000000); wait_sync("ru_thread_synch"); // initialize variables for PSS detection @@ -1871,37 +1867,36 @@ void *ru_thread_synch(void *arg) { // run intial synch like UE LOG_I(PHY,"Running initial synchronization\n"); ru->rx_offset = ru_sync_time(ru, - &peak_val, - &avg); + &peak_val, + &avg); LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg)); cnt++; + //if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) { if (ru->rx_offset >= 0 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) { - LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset); - ru->in_synch = 1; -/* - LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1); - LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6); - LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1); - */ -//exit(-1); + LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset); + ru->in_synch = 1; + /* + LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1); + LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6); + LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1); + */ + //exit(-1); } // sync_pos > 0 - else //AssertFatal(cnt<1000,"Cannot find synch reference\n"); - { - if (cnt>200) { - LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1); - LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6); - LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1); - - exit(-1); - } - } + else { //AssertFatal(cnt<1000,"Cannot find synch reference\n"); + if (cnt>200) { + LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1); + LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6); + LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1); + exit(-1); + } + } } // ru->in_synch==0 + if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; } // oai_exit ru_sync_time_free(ru); - ru_thread_synch_status = 0; return &ru_thread_synch_status; } @@ -1992,13 +1987,11 @@ static void *eNB_thread_phy_tx( void *param ) { if (wait_on_condition(&proc->mutex_phy_tx,&proc->cond_phy_tx,&proc->instance_cnt_phy_tx,"eNB_phy_tx_thread") < 0) break; LOG_D(PHY,"Running eNB phy tx procedures\n"); - AssertFatal(ru->num_eNB == 1, "handle multiple L1 case\n"); L1_proc.subframe_tx = proc->subframe_phy_tx; L1_proc.frame_tx = proc->frame_phy_tx; phy_procedures_eNB_TX(eNB_list[0], &L1_proc, 1); phy_tx_txdataF_end = 1; - AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_rf_tx))==0,"[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx); if (ru->proc.instance_cnt_rf_tx==-1) { @@ -2096,26 +2089,23 @@ extern void kill_fep_thread(RU_t *ru); extern void kill_feptx_thread(RU_t *ru); extern void configure_ru(int idx, - void *arg); + void *arg); void reset_proc(RU_t *ru) { - int i=0; RU_proc_t *proc; - AssertFatal(ru != NULL, "ru is null\n"); proc = &ru->proc; - proc->ru = ru; proc->first_rx = 1; proc->first_tx = 1; proc->frame_offset = 0; proc->frame_tx_unwrap = 0; - for (i=0;i<10;i++) proc->symbol_mask[i]=0; + for (i=0; i<10; i++) proc->symbol_mask[i]=0; } -extern void* ru_thread_control( void* param ); +extern void *ru_thread_control( void *param ); void init_RU_proc(RU_t *ru) { int i=0,ret; @@ -2125,7 +2115,6 @@ void init_RU_proc(RU_t *ru) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_attr_t *attr_prach_br=NULL; #endif - #ifndef OCP_FRAMEWORK LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); #endif @@ -2138,11 +2127,8 @@ void init_RU_proc(RU_t *ru) { proc->instance_cnt_FH1 = -1; proc->instance_cnt_emulateRF = -1; proc->instance_cnt_asynch_rxtx = -1; - - proc->instance_cnt_ru = -1; - + proc->instance_cnt_ru = -1; proc->instance_cnt_eNBs = -1; - proc->first_rx = 1; proc->first_tx = 1; proc->frame_offset = 0; @@ -2159,7 +2145,6 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_mutex_init( &proc->mutex_eNBs, NULL); pthread_mutex_init( &proc->mutex_ru,NULL); - pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init( &proc->cond_FH1, NULL); @@ -2168,7 +2153,6 @@ void init_RU_proc(RU_t *ru) { pthread_cond_init( &proc->cond_synch,NULL); pthread_cond_init( &proc->cond_eNBs, NULL); pthread_cond_init( &proc->cond_ru_thread,NULL); - pthread_attr_init( &proc->attr_FH); pthread_attr_init( &proc->attr_FH1); pthread_attr_init( &proc->attr_emulateRF); @@ -2201,11 +2185,10 @@ void init_RU_proc(RU_t *ru) { attr_prach_br = &proc->attr_prach_br; #endif #endif - if (ru->function!=eNodeB_3GPP) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void*)ru ); - - pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); + if (ru->function!=eNodeB_3GPP) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void *)ru ); + pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void *)ru ); #if defined(PRE_SCD_THREAD) proc->instance_pre_scd = -1; pthread_mutex_init( &proc->mutex_pre_scd, NULL); @@ -2225,7 +2208,6 @@ void init_RU_proc(RU_t *ru) { if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void *)ru ); - if (ru->function == NGFI_RRU_IF4p5) { pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru ); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -2235,41 +2217,36 @@ void init_RU_proc(RU_t *ru) { if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void *)ru); if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) { - LOG_I(PHY,"Starting ru_thread_asynch_rxtx, ru->is_slave %d, ru->generate_dmrs_sync %d\n", - ru->is_slave,ru->generate_dmrs_sync); - //generate_ul_ref_sigs(); - //ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t)); - pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru ); + (ru->function == NGFI_RRU_IF5) || + (ru->function == NGFI_RRU_IF4p5)) { + LOG_I(PHY,"Starting ru_thread_asynch_rxtx, ru->is_slave %d, ru->generate_dmrs_sync %d\n", + ru->is_slave,ru->generate_dmrs_sync); + //generate_ul_ref_sigs(); + //ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t)); + pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void *)ru ); } - - - } - else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF + } else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); - pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); + pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru ); ru->state=RU_RUN; fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); ru->frame_parms.nb_antennas_rx = ru->nb_rx; phy_init_RU(ru); - - openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { + if (setup_RU_buffers(ru)!=0) { printf("Exiting, cannot initialize RU Buffers\n"); exit(-1); - } + } } if (get_thread_worker_conf() == WORKER_ENABLE) { init_fep_thread(ru,NULL); init_feptx_thread(ru,NULL); - } - if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void*)ru); - + } + + if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void *)ru); if (ru->function == eNodeB_3GPP) { usleep(10000); @@ -2445,153 +2422,153 @@ void set_function_spec_param(RU_t *ru) { int ret; switch (ru->if_south) { - case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) - if (ru->function == NGFI_RRU_IF5) { // IF5 RRU - ru->do_prach = 0; // no prach processing in RU - ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north - ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously - ru->feprx = NULL; // nothing (this is a time-domain signal) - ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) - ru->feptx_prec = NULL; // nothing (this is a time-domain signal) - ru->start_if = start_if; // need to start the if interface for if5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); + case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) + if (ru->function == NGFI_RRU_IF5) { // IF5 RRU + ru->do_prach = 0; // no prach processing in RU + ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north + ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously + ru->feprx = NULL; // nothing (this is a time-domain signal) + ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) + ru->feptx_prec = NULL; // nothing (this is a time-domain signal) + ru->start_if = start_if; // need to start the if interface for if5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + } else if (ru->function == NGFI_RRU_IF4p5) { + ru->do_prach = 1; // do part of prach processing in RU + ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north + ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) + ru->feptx_prec = NULL; + ru->start_if = start_if; // need to start the if interface for if4p5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + + malloc_IF4p5_buffer(ru); + } else if (ru->function == eNodeB_3GPP) { + ru->do_prach = 0; // no prach processing in RU + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding + ru->feptx_prec = feptx_prec; // this is fep with idft and precoding + ru->fh_north_in = NULL; // no incoming fronthaul from north + ru->fh_north_out = NULL; // no outgoing fronthaul to north + ru->start_if = NULL; // no if interface + ru->rfdevice.host_type = RAU_HOST; + } + + ru->fh_south_in = rx_rf; // local synchronous RF RX + ru->fh_south_out = tx_rf; // local synchronous RF TX + ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; + printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); + /* + if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise + fill_rf_config(ru,rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + } + + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + }*/ + break; + + case REMOTE_IF5: // the remote unit is IF5 RRU + ru->do_prach = 0; + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs + + if (ru->if_timing == synch_to_other) { + ru->fh_south_in = fh_slave_south_in; // synchronize to master + } else { + ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception + ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_asynch_in = NULL; // no asynchronous UL + } + + ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; + ru->start_if = start_if; // need to start if interface for IF5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - + if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); } - } else if (ru->function == NGFI_RRU_IF4p5) { - ru->do_prach = 1; // do part of prach processing in RU - ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north - ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) - ru->feptx_prec = NULL; - ru->start_if = start_if; // need to start the if interface for if4p5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + + break; + + case REMOTE_IF4p5: + ru->do_prach = 0; + ru->feprx = NULL; // DFTs + ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_ofdm = NULL; // no OFDM mod + ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception + ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission + ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other + ru->fh_north_out = NULL; + ru->fh_north_asynch_in = NULL; + ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; + ru->start_if = start_if; // need to start if interface for IF4p5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; + ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - + if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); } - + malloc_IF4p5_buffer(ru); - } else if (ru->function == eNodeB_3GPP) { - ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding - ru->feptx_prec = feptx_prec; // this is fep with idft and precoding - ru->fh_north_in = NULL; // no incoming fronthaul from north - ru->fh_north_out = NULL; // no outgoing fronthaul to north - ru->start_if = NULL; // no if interface - ru->rfdevice.host_type = RAU_HOST; - } - - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface - ru->stop_rf = stop_rf; - printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); - /* - if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - phy_init_RU(ru); - } - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - }*/ - break; - - case REMOTE_IF5: // the remote unit is IF5 RRU - ru->do_prach = 0; - ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs - - if (ru->if_timing == synch_to_other) { - ru->fh_south_in = fh_slave_south_in; // synchronize to master - } else { - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - } - - ru->start_rf = NULL; // no local RF - ru->stop_rf = NULL; - ru->start_if = start_if; // need to start if interface for IF5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - - break; - - case REMOTE_IF4p5: - ru->do_prach = 0; - ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation - ru->feptx_ofdm = NULL; // no OFDM mod - ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception - ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission - ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other - ru->fh_north_out = NULL; - ru->fh_north_asynch_in = NULL; - ru->start_rf = NULL; // no local RF - ru->stop_rf = NULL; - ru->start_if = start_if; // need to start if interface for IF4p5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - malloc_IF4p5_buffer(ru); - break; - - default: - LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); - break; + break; + + default: + LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); + break; } // switch on interface type } - + //extern void RCconfig_RU(void); void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t time_source,int send_dmrssync) { - int ru_id; RU_t *ru; PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; @@ -2618,31 +2595,36 @@ void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t ti ru->rf_config_file = rf_config_file; ru->idx = ru_id; ru->ts_offset = 0; + if (ru->is_slave == 1) { - ru->in_synch = 0; - ru->generate_dmrs_sync = 0; + ru->in_synch = 0; + ru->generate_dmrs_sync = 0; + } else { + ru->in_synch = 1; + ru->generate_dmrs_sync=send_dmrssync; } - else { - ru->in_synch = 1; - ru->generate_dmrs_sync=send_dmrssync; - } - ru->cmd = EMPTY; + + ru->cmd = EMPTY; ru->south_out_cnt= 0; // use eNB_list[0] as a reference for RU frame parameters // NOTE: multiple CC_id are not handled here yet! ru->openair0_cfg.clock_source = clock_source; ru->openair0_cfg.time_source = time_source; + //ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0; if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1)) ru->generate_dmrs_sync = 1; else ru->generate_dmrs_sync = 0; + if (ru->generate_dmrs_sync == 1) { generate_ul_ref_sigs(); - ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t)); + ru->dmrssync = (int16_t *)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t)); } + ru->wakeup_L1_sleeptime = 2000; ru->wakeup_L1_sleep_cnt_max = 3; + if (ru->num_eNB > 0) { LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); @@ -2661,68 +2643,70 @@ void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t ti eNB0 = ru->eNB_list[0]; LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); LOG_D(PHY, "eNB0:%p\n", eNB0); - if (eNB0) - { - if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) - AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); - if (eNB0) { - LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); - memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + if (eNB0) { + if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) + AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); - // attach all RU to all eNBs in its list/ - LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); - for (i=0;inum_eNB;i++) { - eNB0 = ru->eNB_list[i]; - eNB0->RU_list[eNB0->num_RU++] = ru; - } - } + if (eNB0) { + LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); + memcpy((void *)&ru->frame_parms,(void *)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + // attach all RU to all eNBs in its list/ + LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); + + for (i=0; inum_eNB; i++) { + eNB0 = ru->eNB_list[i]; + eNB0->RU_list[eNB0->num_RU++] = ru; + } } + } + // LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); set_function_spec_param(ru); LOG_I(PHY,"Starting ru_thread %d, is_slave %d, send_dmrs %d\n",ru_id,ru->is_slave,ru->generate_dmrs_sync); - init_RU_proc(ru); } // for ru_id - + // sleep(1); LOG_D(HW,"[lte-softmodem.c] RU threads created\n"); } void stop_ru(RU_t *ru) { - #if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD) int *status; #endif - printf("Stopping RU %p processing threads\n",(void*)ru); + printf("Stopping RU %p processing threads\n",(void *)ru); #if defined(PRE_SCD_THREAD) - if(ru){ + + if(ru) { ru->proc.instance_pre_scd = 0; pthread_cond_signal( &ru->proc.cond_pre_scd ); - pthread_join(ru->proc.pthread_pre_scd, (void**)&status ); + pthread_join(ru->proc.pthread_pre_scd, (void **)&status ); pthread_mutex_destroy(&ru->proc.mutex_pre_scd ); pthread_cond_destroy(&ru->proc.cond_pre_scd ); } + #endif #ifdef PHY_TX_THREAD - if(ru){ - ru->proc.instance_cnt_phy_tx = 0; - pthread_cond_signal(&ru->proc.cond_phy_tx); - pthread_join( ru->proc.pthread_phy_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_phy_tx ); - pthread_cond_destroy( &ru->proc.cond_phy_tx ); - ru->proc.instance_cnt_rf_tx = 0; - pthread_cond_signal(&ru->proc.cond_rf_tx); - pthread_join( ru->proc.pthread_rf_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_rf_tx ); - pthread_cond_destroy( &ru->proc.cond_rf_tx ); + + if(ru) { + ru->proc.instance_cnt_phy_tx = 0; + pthread_cond_signal(&ru->proc.cond_phy_tx); + pthread_join( ru->proc.pthread_phy_tx, (void **)&status ); + pthread_mutex_destroy( &ru->proc.mutex_phy_tx ); + pthread_cond_destroy( &ru->proc.cond_phy_tx ); + ru->proc.instance_cnt_rf_tx = 0; + pthread_cond_signal(&ru->proc.cond_rf_tx); + pthread_join( ru->proc.pthread_rf_tx, (void **)&status ); + pthread_mutex_destroy( &ru->proc.mutex_rf_tx ); + pthread_cond_destroy( &ru->proc.cond_rf_tx ); } + #endif } -void stop_RU(int nb_ru) -{ +void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); kill_RU_proc(RC.ru[inst]); @@ -2844,8 +2828,9 @@ void RCconfig_RU(void) { if (RC.nb_L1_inst >0) RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; else - RC.ru[j]->num_eNB = 0; - for (i=0;inum_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + RC.ru[j]->num_eNB = 0; + + for (i=0; inum_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; RC.ru[j]->has_ctrl_prt = 1; @@ -2869,98 +2854,97 @@ void RCconfig_RU(void) { } if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = eNodeB_3GPP; + if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = eNodeB_3GPP; RC.ru[j]->state = RU_RUN; - printf("Setting function for RU %d to eNodeB_3GPP\n",j); - } - else { - RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); + printf("Setting function for RU %d to eNodeB_3GPP\n",j); + } else { + RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); + RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - // Check if control port set - if (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ){ - printf("Removing control port for RU %d\n",j); + // Check if control port set + if (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) { + printf("Removing control port for RU %d\n",j); + RC.ru[j]->has_ctrl_prt = 0; + } else { + RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); + RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); + printf(" Control port %u \n",RC.ru[j]->eth_params.my_portc); + } - RC.ru[j]->has_ctrl_prt = 0; + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } - else { - RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); - printf(" Control port %u \n",RC.ru[j]->eth_params.my_portc); - - } - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - - printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - - printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); - } printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr)); + if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; else RC.ru[j]->is_slave=0; + printf("RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr)); + if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1; else RC.ru[j]->ota_sync_enable=0; - } - RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; - RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); - RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; - /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ + } + + RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; + RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); + RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; + /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr); - for (i=0;inum_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; + + for (i=0; inum_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; } //strcmp(local_rf, "yes") == 0 else { - printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); - - RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - } + printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); + RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); + RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); + RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); + RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); + RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); + + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + } + if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; else RC.ru[j]->is_slave=0; } /* strcmp(local_rf, "yes") != 0 */ From 3ad36982dd98f5222f53e85ff636071cc0829a88 Mon Sep 17 00:00:00 2001 From: laurent Date: Tue, 8 Oct 2019 18:43:42 +0200 Subject: [PATCH 056/134] one cppcheck only --- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 946f6b3ee1..14117307b8 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -581,7 +581,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); #ifdef DEBUG_ULSCH_DECODING - printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n", + printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d)...\n", r, G, Kr*3, ulsch_harq->Qm, From c107789e4ccda46c084efd8d967f2124b4854c5f Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 9 Oct 2019 07:30:10 -0700 Subject: [PATCH 057/134] [to test] CU/DU split supported --- openair2/RRC/LTE/rrc_eNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index f7c4b1f06b..7891183323 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6498,7 +6498,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( /* CDRX: (under test) activated when RRC Connection Reconfiguration was sent */ int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); if (UE_id_mac == -1) { - LOG_E(rrc, "Can't find UE_id(MAC) of UE rnti %x\n", ue_context_pP->ue_context.rnti); + LOG_E(RRC, "Can't find UE_id(MAC) of UE rnti %x\n", ue_context_pP->ue_context.rnti); return; } From 206f17b2a4f4633d4621c4c4c5ac985586529ba9 Mon Sep 17 00:00:00 2001 From: LouisAdrien Date: Thu, 10 Oct 2019 08:10:16 +0200 Subject: [PATCH 058/134] [under test] Fix CDRX starts at RRCReconfComplete again; new comments --- openair2/ENB_APP/enb_config.c | 1 - openair2/F1AP/f1ap_du_rrc_message_transfer.c | 4 +- openair2/LAYER2/MAC/config.c | 11 ++-- openair2/RRC/LTE/rrc_eNB.c | 55 ++++++++++---------- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index a957e11bcd..df0adfb917 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -387,7 +387,6 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - //RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate // In the configuration file it is in seconds. For RRC it has to be in milliseconds RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = (*ENBParamList.paramarray[i][ENB_RRC_INACTIVITY_THRES_IDX].uptr) * 1000; RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index ea22ce7672..ee8177f642 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -750,7 +750,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: LOG_I(F1AP, "[MSG] RRC UL rrcConnectionReconfigurationComplete\n"); - /* CDRX: (under test) activated when RRC Connection Reconfiguration was sent */ + /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ int UE_id_mac = find_UE_id(instance, rnti); if (UE_id_mac == -1) { @@ -762,7 +762,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; - // UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is sent (under test) + UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received LOG_I(F1AP, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); } /* End of CDRX processing */ diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 621dafe603..ad7bc2fbcd 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -990,7 +990,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, //----------------------------------------------------------------------------- /* -* Configure local DRX timers and thresholds following the drx_configuration input +* Configure local CDRX timers and thresholds following the drx_configuration input */ void eNB_Config_Local_DRX( module_id_t Mod_id, @@ -1022,20 +1022,19 @@ void eNB_Config_Local_DRX( /* Check drx_Configuration */ if (drx_Configuration == NULL) { - LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + LOG_W(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters for CDRX\n"); return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { - LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n"); + LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters for CDRX\n"); return; } /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - LOG_I(MAC, "Initial cdrx_waiting_ack state: %s\n", UE_scheduling_control->cdrx_waiting_ack ? "TRUE" : "FALSE"); - UE_scheduling_control->cdrx_configured = TRUE; // will be set to true - UE_scheduling_control->cdrx_waiting_ack = TRUE; // For debugging only + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when receiving RRC Reconfiguration Complete + UE_scheduling_control->cdrx_waiting_ack = TRUE; // waiting for RRC Reconfiguration Complete message UE_scheduling_control->in_active_time = FALSE; UE_scheduling_control->dci0_ongoing_timer = 0; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 7891183323..c839ebc22c 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3235,13 +3235,13 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); } } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - LOG_I(RRC, "CDRX not implemented for TDD and LTE-M\n"); + LOG_E(RRC, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); } + /* End of CDRX configuration */ } - /* End of CDRX configuration */ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -3935,44 +3935,44 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ // Need to check if UE is a BR UE rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; int UE_id = find_UE_id(module_id, rnti); - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); if (UE_id != -1) { - if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && + eNB_MAC_INST *mac = RC.mac[module_id]; + UE_list_t *UE_list = &(mac->UE_list); + + if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) + // CDRX can be only configured in case of FDD and non BR UE (09/04/19) + + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); - - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + /* Process the IE drx_Config */ + if (cc_id < MAX_NUM_CCs) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } + } else { + LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); + } } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - mac_MainConfig->drx_Config = NULL; + LOG_E(RRC, "CDRX not implemented for TDD and LTE-M\n"); } } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); - mac_MainConfig->drx_Config = NULL; } - } else { // No CDRX with the CU/DU split in this version - LOG_E(RRC, "CU/DU split activated\n"); - mac_MainConfig->drx_Config = NULL; + /* End of CDRX configuration */ } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) @@ -6495,8 +6495,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX: (under test) activated when RRC Connection Reconfiguration was sent */ + /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + if (UE_id_mac == -1) { LOG_E(RRC, "Can't find UE_id(MAC) of UE rnti %x\n", ue_context_pP->ue_context.rnti); return; @@ -6506,7 +6507,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; - // UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is sent (under test) + UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is received LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } /* End of CDRX processing */ From 34f0bdac3ac70291d26ba1e5e2f583aff6fd4172 Mon Sep 17 00:00:00 2001 From: DUFRENE Louis Adrien TGI/OLS Date: Mon, 28 Oct 2019 14:44:16 +0100 Subject: [PATCH 059/134] [to build] Monolithic: move RRC features in do_drxconfig --- .gitignore | 3 ++ openair2/F1AP/f1ap_du_rrc_message_transfer.c | 3 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 14 +++++++ openair2/RRC/LTE/rrc_eNB.c | 42 +++++--------------- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index d7126a6224..7b227ecca8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ log/ lte_build_oai/ targets/bin/ cmake_targets/nas_sim_tools/build/ + +# vscode +.vscode \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index ee8177f642..f323c82c03 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -646,8 +646,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, - const f1ap_ul_rrc_message_t *msg) -{ + const f1ap_ul_rrc_message_t *msg) { const rnti_t rnti = msg->rnti; F1AP_F1AP_PDU_t pdu; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index f38720f56c..5907a0807b 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -630,6 +630,17 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { + // CDRX not implemented for TDD + if (rrc_inst->carrier[CC_id].sib1->tdd_Config != NULL) { + LOG_E(RRC, "[do_DrxConfig] CDRX not implemented for TDD and LTE-M\n"); + return NULL; + } + + if (CC_id >= MAX_NUM_CCs) { + LOG_E(RRC, "[do_DrxConfig] Invalid CC_id for DRX configuration\n"); + return NULL; + } + LTE_DRX_Config_t *drxConfig = NULL; BIT_STRING_t *featureGroupIndicators = NULL; bool ueSupportCdrxShortFlag = false; @@ -647,6 +658,9 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); } else LOG_W(RRC,"[do_DrxConfig] No UEcap pointer\n"); + /* Check if UE support CE mode A */ + // TODO + if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { return NULL; } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index c839ebc22c..6b9eec4230 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3207,39 +3207,19 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ - // Need to check if UE is a BR UE - int UE_id = find_UE_id(module_id, rnti); + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - if (UE_id != -1) { - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); - - if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && - (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - - if (mac_MainConfig->drx_Config == NULL) { - LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - } else { - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - } - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - LOG_E(RRC, "CDRX not implemented for TDD and LTE-M\n"); - } - } else { // UE_id invalid - LOG_E(RRC, "Invalid UE_id found!\n"); + if (mac_MainConfig->drx_Config == NULL) { + LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); } + + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + /* End of CDRX configuration */ } From eddc13d235b3fb0292d48766362166d37a60acdc Mon Sep 17 00:00:00 2001 From: LAD Date: Tue, 29 Oct 2019 03:05:36 -0700 Subject: [PATCH 060/134] [to build] Check coverage extension through UE capabilities --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 108 ++++++++++++++++++++++----- openair2/RRC/LTE/rrc_eNB.c | 13 ++-- 2 files changed, 96 insertions(+), 25 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 5907a0807b..4d53ffa573 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -630,14 +630,91 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { - // CDRX not implemented for TDD - if (rrc_inst->carrier[CC_id].sib1->tdd_Config != NULL) { - LOG_E(RRC, "[do_DrxConfig] CDRX not implemented for TDD and LTE-M\n"); + /* Need UE capabilities */ + if (!UEcap) { + LOG_E(RRC,"[do_DrxConfig] No UEcap pointer\n"); + return NULL; + } + + /* Check CC id */ + if (CC_id >= MAX_NUM_CCs) { + LOG_E(RRC, "[do_DrxConfig] Invalid CC_id for DRX configuration\n"); return NULL; } - if (CC_id >= MAX_NUM_CCs) { - LOG_E(RRC, "[do_DrxConfig] Invalid CC_id for DRX configuration\n"); + /* CDRX not implemented for TDD */ + if (rrc_inst->carrier[CC_id].sib1->tdd_Config) { + LOG_E(RRC, "[do_DrxConfig] CDRX not implemented for TDD\n"); + return NULL; + } + + /* Check the UE capabilities, CDRX not implemented for Coverage Extension */ + LTE_UE_EUTRA_Capability_v920_IEs_t *cap_920 = NULL; + LTE_UE_EUTRA_Capability_v940_IEs_t *cap_940 = NULL; + LTE_UE_EUTRA_Capability_v1020_IEs_t *cap_1020 = NULL; + LTE_UE_EUTRA_Capability_v1060_IEs_t *cap_1060 = NULL; + LTE_UE_EUTRA_Capability_v1090_IEs_t *cap_1090 = NULL; + LTE_UE_EUTRA_Capability_v1130_IEs_t *cap_1130 = NULL; + LTE_UE_EUTRA_Capability_v1170_IEs_t *cap_1170 = NULL; + LTE_UE_EUTRA_Capability_v1180_IEs_t *cap_1180 = NULL; + LTE_UE_EUTRA_Capability_v11a0_IEs_t *cap_11a0 = NULL; + LTE_UE_EUTRA_Capability_v1250_IEs_t *cap_1250 = NULL; + LTE_UE_EUTRA_Capability_v1260_IEs_t *cap_1260 = NULL; + LTE_UE_EUTRA_Capability_v1270_IEs_t *cap_1270 = NULL; + LTE_UE_EUTRA_Capability_v1280_IEs_t *cap_1280 = NULL; + LTE_UE_EUTRA_Capability_v1310_IEs_t *cap_1310 = NULL; + LTE_CE_Parameters_r13_t *CE_param = NULL; + long *ce_a_param = NULL; + + cap_920 = UEcap->nonCriticalExtension; + if (cap_920) { + cap_940 = cap_920->nonCriticalExtension; + if (cap_940) { + cap_1020 = cap_940->nonCriticalExtension; + if (cap_1020) { + cap_1060 = cap_1020->nonCriticalExtension; + if (cap_1060) { + cap_1090 = cap_1060->nonCriticalExtension; + if (cap_1090) { + cap_1130 = cap_1090->nonCriticalExtension; + if (cap_1130) { + cap_1170 = cap_1130->nonCriticalExtension; + if (cap_1170) { + cap_1180 = cap_1170->nonCriticalExtension; + if (cap_1180) { + cap_11a0 = cap_1180->nonCriticalExtension; + if (cap_11a0) { + cap_1250 = cap_11a0->nonCriticalExtension; + if (cap_1250) { + cap_1260 = cap_1250->nonCriticalExtension; + if (cap_1260) { + cap_1270 = cap_1260->nonCriticalExtension; + if (cap_1270) { + cap_1280 = cap_1270->nonCriticalExtension; + if (cap_1280) { + cap_1310 = cap_1280->nonCriticalExtension; + if (cap_1310) { + CE_param = cap_1310->ce_Parameters_r13; + if (CE_param) { + ce_a_param = CE_param->ce_ModeA_r13; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + if (ce_a_param) { + LOG_E(RRC,"[do_DrxConfig] Coverage Extension not supported by CDRX\n"); return NULL; } @@ -647,19 +724,14 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, bool ueSupportCdrxLongFlag = false; /* Check the UE capabilities for short and long CDRX cycles support */ - if (UEcap) { - featureGroupIndicators = UEcap->featureGroupIndicators; - if (featureGroupIndicators) { - if (featureGroupIndicators->size > 1 || (featureGroupIndicators->size == 1 && featureGroupIndicators->bits_unused < 4)) { - ueSupportCdrxShortFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x10) > 0); - ueSupportCdrxLongFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x08) > 0); - LOG_I(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); - } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); - } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); - } else LOG_W(RRC,"[do_DrxConfig] No UEcap pointer\n"); - - /* Check if UE support CE mode A */ - // TODO + featureGroupIndicators = UEcap->featureGroupIndicators; + if (featureGroupIndicators) { + if (featureGroupIndicators->size > 1 || (featureGroupIndicators->size == 1 && featureGroupIndicators->bits_unused < 4)) { + ueSupportCdrxShortFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x10) > 0); + ueSupportCdrxLongFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x08) > 0); + LOG_I(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); + } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); + } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { return NULL; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 6b9eec4230..75c5d60efb 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3213,13 +3213,12 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE if (mac_MainConfig->drx_Config == NULL) { - LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - } - - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - + LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + } /* End of CDRX configuration */ } From d1f54a98dccd9bedc01a12eaaf62e97b0841f2a5 Mon Sep 17 00:00:00 2001 From: LAD Date: Tue, 29 Oct 2019 03:41:56 -0700 Subject: [PATCH 061/134] [to test] Check CE from UECap and TDD from RRC config --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/LTE/rrc_eNB.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 4d53ffa573..78642b4ab9 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -643,7 +643,7 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } /* CDRX not implemented for TDD */ - if (rrc_inst->carrier[CC_id].sib1->tdd_Config) { + if (configuration->frame_type[CC_id] == 1) { LOG_E(RRC, "[do_DrxConfig] CDRX not implemented for TDD\n"); return NULL; } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 75c5d60efb..983a566733 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3205,7 +3205,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; - if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) { /* CDRX Configuration */ LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); From 3187127bd7b004b56ea009d77d51af5271977e42 Mon Sep 17 00:00:00 2001 From: LAD Date: Tue, 29 Oct 2019 07:22:44 -0700 Subject: [PATCH 062/134] [to test] Improvements added to F1AP interface (no UE management messaging) --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 44 ++++---------------- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 21 +++++----- openair2/RRC/LTE/rrc_eNB.c | 31 +++++++------- 3 files changed, 37 insertions(+), 59 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index f323c82c03..0d843c157c 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -405,45 +405,19 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { + LOG_I(F1AP, "MAC Main Configuration is present\n"); + mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; /* CDRX Configuration */ - // Need to check if UE is a BR UE - int UE_id = find_UE_id(ctxt.module_id, ctxt.rnti); - - if (UE_id != -1) { - eNB_RRC_INST *rrc_inst = RC.rrc[ctxt.module_id]; - uint8_t cc_id = ue_context_p->ue_context.primaryCC_id; - eNB_MAC_INST *mac = RC.mac[ctxt.module_id]; - UE_list_t *UE_list = &(mac->UE_list); - - if (rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL && UE_list->UE_template[cc_id][UE_id].rach_resource_type == 0) { - // CDRX can be only configured in case of FDD and non BR UE (27/09/19) - - LOG_D(F1AP, "Processing the DRX configuration in DU RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - if (cc_id < MAX_NUM_CCs) { - LTE_UE_EUTRA_Capability_t *UEcap = ue_context_p->ue_context.UE_Capability; - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - - if (mac_MainConfig->drx_Config == NULL) { - LOG_E(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - } else { - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); - LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - } - } else { - LOG_E(F1AP, "Invalid CC_id for DRX configuration\n"); - } - } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - LOG_I(F1AP, "CDRX not implemented for TDD and LTE-M\n"); - } - } else { // UE_id invalid - LOG_E(F1AP, "Invalid UE_id found!\n"); - } + if (mac_MainConfig->drx_Config == NULL) { + LOG_W(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); + } else { + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); + LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); /* End of CDRX configuration */ + } } LTE_MeasGapConfig_t *measGapConfig = NULL; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 78642b4ab9..3d40f0286c 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -630,24 +630,29 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, LTE_UE_EUTRA_Capability_t *UEcap) //----------------------------------------------------------------------------- { - /* Need UE capabilities */ - if (!UEcap) { - LOG_E(RRC,"[do_DrxConfig] No UEcap pointer\n"); - return NULL; - } - /* Check CC id */ if (CC_id >= MAX_NUM_CCs) { LOG_E(RRC, "[do_DrxConfig] Invalid CC_id for DRX configuration\n"); return NULL; } + /* No CDRX configuration */ + if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { + return NULL; + } + /* CDRX not implemented for TDD */ if (configuration->frame_type[CC_id] == 1) { LOG_E(RRC, "[do_DrxConfig] CDRX not implemented for TDD\n"); return NULL; } + /* Need UE capabilities */ + if (!UEcap) { + LOG_E(RRC,"[do_DrxConfig] No UEcap pointer\n"); + return NULL; + } + /* Check the UE capabilities, CDRX not implemented for Coverage Extension */ LTE_UE_EUTRA_Capability_v920_IEs_t *cap_920 = NULL; LTE_UE_EUTRA_Capability_v940_IEs_t *cap_940 = NULL; @@ -733,10 +738,6 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); - if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { - return NULL; - } - drxConfig = (LTE_DRX_Config_t *) malloc(sizeof(LTE_DRX_Config_t)); if (drxConfig == NULL) return NULL; memset(drxConfig, 0, sizeof(LTE_DRX_Config_t)); diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 983a566733..a7f80f9f1c 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3202,25 +3202,25 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB mac_MainConfig->drx_Config = NULL; + + /* CDRX Configuration */ rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) { - /* CDRX Configuration */ - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - /* Process the IE drx_Config */ - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - if (mac_MainConfig->drx_Config == NULL) { LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { /* Set timers and thresholds values in local MAC context of UE */ eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - } - /* End of CDRX configuration */ + } } + /* End of CDRX configuration */ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); @@ -6473,24 +6473,27 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer - if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ - int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; + + if (NODE_IS_MONOLITHIC(RC.rrc[module_id]->node_type)) { + int UE_id_mac = find_UE_id(module_id, rnti); if (UE_id_mac == -1) { - LOG_E(RRC, "Can't find UE_id(MAC) of UE rnti %x\n", ue_context_pP->ue_context.rnti); + LOG_E(RRC, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); return; } - UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); + UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is received LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } - /* End of CDRX processing */ } + /* End of CDRX processing */ T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), From 940ce3fe9367b526fb368bfa524af5a66f9c7fa2 Mon Sep 17 00:00:00 2001 From: LouisAdrien Date: Tue, 29 Oct 2019 16:33:57 +0100 Subject: [PATCH 063/134] [tested] comment update --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 6 +++--- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/LTE/rrc_eNB.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 0d843c157c..e6bd03bdf7 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -405,7 +405,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) { - LOG_I(F1AP, "MAC Main Configuration is present\n"); + LOG_D(F1AP, "MAC Main Configuration is present\n"); mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; @@ -415,7 +415,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } else { /* Set timers and thresholds values in local MAC context of UE */ eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); - LOG_D(F1AP, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + LOG_D(F1AP, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); /* End of CDRX configuration */ } } @@ -736,7 +736,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { UE_scheduling_control->cdrx_waiting_ack = FALSE; UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received - LOG_I(F1AP, "CDRX configuration after first RRC Connection Reconfiguration Complete reception\n"); + LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } /* End of CDRX processing */ diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 3d40f0286c..c2212a6c16 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -734,7 +734,7 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, if (featureGroupIndicators->size > 1 || (featureGroupIndicators->size == 1 && featureGroupIndicators->bits_unused < 4)) { ueSupportCdrxShortFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x10) > 0); ueSupportCdrxLongFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x08) > 0); - LOG_I(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); + LOG_D(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index a7f80f9f1c..0be703b0ec 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3217,7 +3217,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t } else { /* Set timers and thresholds values in local MAC context of UE */ eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + LOG_D(RRC, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); } } /* End of CDRX configuration */ From a3c337cc9fd1e4d4d3e70ea4080cbdd6d8c212b3 Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 30 Oct 2019 07:36:44 -0700 Subject: [PATCH 064/134] [to test] Add MAC itti loop and DRX config support --- openair2/COMMON/mac_messages_def.h | 3 ++ openair2/COMMON/mac_messages_types.h | 14 ++++++ openair2/F1AP/f1ap_du_rrc_message_transfer.c | 6 ++- openair2/LAYER2/MAC/config.c | 31 ++++++------- openair2/LAYER2/MAC/mac_proto.h | 7 ++- openair2/LAYER2/MAC/main.c | 49 ++++++++++++++++++-- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 1 + openair2/RRC/LTE/rrc_eNB.c | 18 ++++--- targets/COMMON/create_tasks.c | 16 ++++--- 9 files changed, 109 insertions(+), 36 deletions(-) diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h index f69186e4b8..09b3f2aab4 100644 --- a/openair2/COMMON/mac_messages_def.h +++ b/openair2/COMMON/mac_messages_def.h @@ -45,3 +45,6 @@ MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDat MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind) MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req) + +/* RRC configures DRX context (MAC timers) of a UE */ +MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req) \ No newline at end of file diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index 3bbea66d0d..e227296d05 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -29,6 +29,8 @@ #ifndef MAC_MESSAGES_TYPES_H_ #define MAC_MESSAGES_TYPES_H_ +#include + //-------------------------------------------------------------------------------------------// // Defines to access message fields. #define RRC_MAC_IN_SYNC_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_in_sync_ind @@ -48,6 +50,8 @@ #define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind #define RRC_MAC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req +#define RRC_MAC_DRX_CONFIG_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_drx_config_req + // Some constants from "LAYER2/MAC/defs.h" #define BCCH_SDU_SIZE (512) #define BCCH_SDU_MBMS_SIZE (512) @@ -145,4 +149,14 @@ typedef struct RrcMacPcchDataReq_s { uint8_t sdu[PCCH_SDU_SIZE]; uint8_t enb_index; } RrcMacPcchDataReq; + +/* RRC configures DRX context (MAC timers) of a UE */ +typedef struct rrc_mac_drx_config_req_s { + /* UE RNTI to configure */ + rnti_t rnti; + + /* DRX configuration from MacMainConfig to configure UE's local timers */ + LTE_DRX_Config_t * drx_Configuration; +} rrc_mac_drx_config_req_t; + #endif /* MAC_MESSAGES_TYPES_H_ */ diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index e6bd03bdf7..583ccfe649 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -410,14 +410,16 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; /* CDRX Configuration */ + /* if (mac_MainConfig->drx_Config == NULL) { LOG_W(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { - /* Set timers and thresholds values in local MAC context of UE */ + //// Set timers and thresholds values in local MAC context of UE eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); LOG_D(F1AP, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); - /* End of CDRX configuration */ } + */ + /* End of CDRX configuration */ } LTE_MeasGapConfig_t *measGapConfig = NULL; diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ad7bc2fbcd..84b5720bc0 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -992,27 +992,24 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, /* * Configure local CDRX timers and thresholds following the drx_configuration input */ -void eNB_Config_Local_DRX( - module_id_t Mod_id, - rnti_t rnti, - LTE_DRX_Config_t *const drx_Configuration -) +void eNB_Config_Local_DRX(instance_t Mod_id, + rrc_mac_drx_config_req_t *rrc_mac_drx_config_req) //----------------------------------------------------------------------------- { UE_list_t *UE_list_mac = NULL; - int UE_id = -1; UE_sched_ctrl_t *UE_scheduling_control = NULL; + int UE_id = -1; + rnti_t rnti = rrc_mac_drx_config_req->rnti; + LTE_DRX_Config_t *const drx_Configuration = rrc_mac_drx_config_req->drx_Configuration; + UE_list_mac = &(RC.mac[Mod_id]->UE_list); UE_id = find_UE_id(Mod_id, rnti); /* Check UE_id */ if (UE_id == -1) { - LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", - __FILE__, - __LINE__, - __FUNCTION__); + LOG_E(MAC, "[eNB_Config_Local_DRX] UE_id == -1\n"); return; } @@ -1022,13 +1019,13 @@ void eNB_Config_Local_DRX( /* Check drx_Configuration */ if (drx_Configuration == NULL) { - LOG_W(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters for CDRX\n"); + LOG_W(MAC, "[eNB_Config_Local_DRX] drx_Configuration parameter is NULL, cannot configure local UE parameters for CDRX\n"); return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { - LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters for CDRX\n"); + LOG_I(MAC, "[eNB_Config_Local_DRX] No drx_Configuration present, don't configure local UE parameters for CDRX\n"); return; } @@ -1090,7 +1087,7 @@ void eNB_Config_Local_DRX( UE_scheduling_control->on_duration_timer_thres = 200; break; default: - LOG_E(MAC, "Error in local DRX configuration, the on duration timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the on duration timer value specified is unknown\n"); break; } @@ -1166,7 +1163,7 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_inactivity_timer_thres = 0; break; default: - LOG_E(MAC, "Error in local DRX configuration, the drx inactivity timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx inactivity timer value specified is unknown\n"); break; } @@ -1229,7 +1226,7 @@ void eNB_Config_Local_DRX( UE_scheduling_control->short_drx_cycle_duration = 640; break; default: - LOG_E(MAC, "Error in local DRX configuration, the short drx timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the short drx timer value specified is unknown\n"); break; } @@ -1305,7 +1302,7 @@ void eNB_Config_Local_DRX( UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560; break; default: - LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Invalid long_DRX value in DRX local configuration\n"); break; } @@ -1336,7 +1333,7 @@ void eNB_Config_Local_DRX( memset(UE_scheduling_control->drx_retransmission_timer_thres, 33, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; default: - LOG_E(MAC, "Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); + LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); break; } } diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 695005cd1f..bb35bffc32 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -31,6 +31,7 @@ #include "LAYER2/MAC/mac.h" #include "PHY/defs_common.h" // for PRACH_RESOURCES_t and lte_subframe_t +#include "openair2/COMMON/mac_messages_types.h" /** \addtogroup _mac * @{ @@ -1318,9 +1319,13 @@ int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); /* DRX Configuration */ /* Configure local DRX timers and thresholds in UE context, following the drx_configuration input */ -void eNB_Config_Local_DRX(module_id_t Mod_id, rnti_t rnti, LTE_DRX_Config_t *drx_Configuration); +void eNB_Config_Local_DRX(instance_t Mod_id, rrc_mac_drx_config_req_t *rrc_mac_drx_config_req); /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); #endif /** @}*/ + +/* MAC ITTI messaging related functions */ +/* Main loop of MAC itti message handling */ +void *mac_enb_task(void *arg); \ No newline at end of file diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 8fb8d44e0a..64cb03774b 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -34,15 +34,12 @@ #include "mac_proto.h" #include "mac_extern.h" #include "assertions.h" -//#include "PHY_INTERFACE/phy_extern.h" -//#include "PHY/defs_eNB.h" -//#include "SCHED/sched_eNB.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "RRC/LTE/rrc_defs.h" #include "common/utils/LOG/log.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - #include "common/ran_context.h" +#include "intertask_interface.h" extern RAN_CONTEXT_t RC; @@ -223,3 +220,47 @@ int l2_init_eNB(void) return (1); } + +//----------------------------------------------------------------------------- +/* + * Main loop of MAC itti message handling + */ +void *mac_enb_task(void *arg) +//----------------------------------------------------------------------------- +{ + MessageDef *received_msg = NULL; + int result; + + itti_mark_task_ready(TASK_MAC_ENB); // void function 10/2019 + LOG_I(MAC,"Starting main loop of MAC message task\n"); + + while (1) { + itti_receive_msg(TASK_MAC_ENB, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case RRC_MAC_DRX_CONFIG_REQ: + LOG_I(MAC, "MAC Task Received RRC_MAC_DRX_CONFIG_REQ\n"); + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.rrc_mac_drx_config_req); + break; + + case TERMINATE_MESSAGE: + LOG_W(MAC, " *** Exiting MAC thread\n"); + itti_exit_task(); + break; + + default: + LOG_E(MAC, "MAC instance received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), + ITTI_MSG_NAME(received_msg)); + break; + } // end switch + + result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + received_msg = NULL; + } // end while + + return NULL; +} \ No newline at end of file diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index c2212a6c16..41eea1f7e6 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -621,6 +621,7 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, return((enc_rval.encoded+7)/8); } #endif + //----------------------------------------------------------------------------- /* * Generate the configuration structure for CDRX feature diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 0be703b0ec..5522652a26 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -2967,6 +2967,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; + MessageDef *message_p = NULL; /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */ eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; @@ -3215,8 +3216,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t if (mac_MainConfig->drx_Config == NULL) { LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { - /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); + /* Send DRX configuration to MAC task to configure timers of local UE context */ + message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_MAC_DRX_CONFIG_REQ); + RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = rnti; + RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; + itti_send_msg_to_task(TASK_MAC_ENB, module_id, message_p); LOG_D(RRC, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); } } @@ -3732,8 +3736,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LTE_C_RNTI_t *cba_RNTI = NULL; int measurements_enabled; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, - uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; - LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; #ifdef CBA // Contention Based Access uint8_t *cba_RNTI_buf; @@ -3916,6 +3918,9 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { /* CDRX Configuration */ + /* + uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; // Need to check if UE is a BR UE rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; @@ -3931,14 +3936,14 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - /* Process the IE drx_Config */ + ///// Process the IE drx_Config / if (cc_id < MAX_NUM_CCs) { mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE if (mac_MainConfig->drx_Config == NULL) { LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); } else { - /* Set timers and thresholds values in local MAC context of UE */ + ////// Set timers and thresholds values in local MAC context of UE / eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); } @@ -3951,6 +3956,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt } else { // UE_id invalid LOG_E(RRC, "Invalid UE_id found!\n"); } + */ /* End of CDRX configuration */ } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index cfc2bc2215..2f7ff9d3a7 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -26,11 +26,11 @@ # include "common/ran_context.h" #ifdef OPENAIR2 - #include "sctp_eNB_task.h" - #include "x2ap_eNB.h" - #include "s1ap_eNB.h" - #include "udp_eNB_task.h" - #include "gtpv1u_eNB_task.h" + #include "sctp_eNB_task.h" + #include "x2ap_eNB.h" + #include "s1ap_eNB.h" + #include "udp_eNB_task.h" + #include "gtpv1u_eNB_task.h" #if ENABLE_RAL #include "lteRALue.h" #include "lteRALenb.h" @@ -40,6 +40,7 @@ # include "f1ap_cu_task.h" # include "f1ap_du_task.h" # include "enb_app.h" +# include "openair2/LAYER2/MAC/mac_proto.h" extern RAN_CONTEXT_t RC; @@ -63,7 +64,6 @@ int create_tasks(uint32_t enb_nb) { AssertFatal(rc >= 0, "Create task for SCTP failed\n"); } - if (EPC_MODE_ENABLED && !NODE_IS_DU(type)) { rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL); AssertFatal(rc >= 0, "Create task for S1AP failed\n"); @@ -91,5 +91,9 @@ int create_tasks(uint32_t enb_nb) { AssertFatal(rc >= 0, "Create task for DU F1AP failed\n"); } + LOG_I(MAC,"Creating MAC eNB Task\n"); + rc = itti_create_task(TASK_MAC_ENB, mac_enb_task, NULL); + AssertFatal(rc >= 0, "Create task for MAC eNB failed\n"); + return 0; } From d812ffd616630d4e9124d60e5cc23b80b150a3a9 Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 30 Oct 2019 23:50:07 -0700 Subject: [PATCH 065/134] [tested] MAC itti ok. Add procedure to DU part (not tested, but need dedicated F1AP implementation). --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 583ccfe649..15ecfd2173 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -48,6 +48,7 @@ #include "rrc_eNB_UE_context.h" #include "asn1_msg.h" +#include "intertask_interface.h" // undefine C_RNTI from // openair1/PHY/LTE_TRANSPORT/transport_common.h which @@ -410,15 +411,18 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; /* CDRX Configuration */ - /* if (mac_MainConfig->drx_Config == NULL) { LOG_W(F1AP, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { - //// Set timers and thresholds values in local MAC context of UE - eNB_Config_Local_DRX(ctxt.module_id, ctxt.rnti, mac_MainConfig->drx_Config); + MessageDef *message_p = NULL; + + /* Send DRX configuration to MAC task to configure timers of local UE context */ + message_p = itti_alloc_new_message(TASK_DU_F1, RRC_MAC_DRX_CONFIG_REQ); + RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = ctxt.rnti; + RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; + itti_send_msg_to_task(TASK_MAC_ENB, ctxt.module_id, message_p); LOG_D(F1AP, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); } - */ /* End of CDRX configuration */ } From 2a7ac81b0b92d1471a0bf0651d83b7ace7da94d2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 6 Nov 2019 12:30:50 +0100 Subject: [PATCH 066/134] hotfix: better CQI requests, especially for TDD In TDD mode, CQI requests are not possible in special subframes (at least for some TDD configurations, see 36.213 7.2.3 that says "a DL subframe is valid if it does not contain a DwPTS field if the length is less than 7680 Ts"). In the code, we simply disable CQI requests in special subframes, no matter what the length of DwPTS. A problem can arise if the DCI0 for a given UE are sent only in those special subframes. In this case the UE will never report CQI and the eNB will use low MCS for this UE, impacting performances. Another, related, problem is when there are several UEs. There again one UE might always get its DCI0 in special subframes and thus never report CQI. There again, performance issues. This commit is an attempt to improve the situation. It does two things. 1 - tag the UE as schedulable in the function UE_is_to_be_scheduled if the cqi_req_timer is expired 2 - use cqi_req_timer as a criterium when ordering UEs for UL scheduling The value chosen for the expiration of the cqi_req_timer in UE_is_to_be_scheduled is quite high (300) because as the code is today we may overschedule the UE for short bursts until we receive a CQI from the UE. [TODO: fix the code properly to avoid this behavior.] Note: the fairRR scheduler has not been analyzed and this commit may not fix anything in case the fairRR scheduler is used. --- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 8 +++++--- openair2/LAYER2/MAC/pre_processor.c | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 63f838f652..6750998b9f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2523,6 +2523,7 @@ UE_is_to_be_scheduled(module_id_t module_idP, { UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; UE_sched_ctrl_t *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; + int rrc_status; // do not schedule UE if UL is not working if (UE_sched_ctl->ul_failure_timer > 0 || UE_sched_ctl->ul_out_of_sync > 0) @@ -2535,13 +2536,14 @@ UE_is_to_be_scheduled(module_id_t module_idP, UE_id, ue_rnti); + rrc_status = mac_eNB_get_rrc_status(module_idP, ue_rnti); + if (UE_template->scheduled_ul_bytes < UE_template->estimated_ul_buffer || UE_template->ul_SR > 0 || // uplink scheduling request (UE_sched_ctl->ul_inactivity_timer > 19 && UE_sched_ctl->ul_scheduled == 0) || // every 2 frames when RRC_CONNECTED (UE_sched_ctl->ul_inactivity_timer > 10 && - UE_sched_ctl->ul_scheduled == 0 && - mac_eNB_get_rrc_status(module_idP, - ue_rnti) < RRC_CONNECTED)) { // every Frame when not RRC_CONNECTED + UE_sched_ctl->ul_scheduled == 0 && rrc_status < RRC_CONNECTED) || // every Frame when not RRC_CONNECTED + (UE_sched_ctl->cqi_req_timer > 300 && rrc_status >= RRC_CONNECTED)) { // cqi req timer expired long ago (do not put too low value) LOG_D(MAC, "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 estimated size %d, SR %d)\n", module_idP, UE_id, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 0dc11b0e45..40f9334bfa 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -2024,6 +2024,14 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) { UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) return 1; + if (UE_list->UE_sched_ctrl[UE_id1].cqi_req_timer > + UE_list->UE_sched_ctrl[UE_id2].cqi_req_timer) + return -1; + + if (UE_list->UE_sched_ctrl[UE_id1].cqi_req_timer < + UE_list->UE_sched_ctrl[UE_id2].cqi_req_timer) + return 1; + return 0; } From c2460cc4d230719d391eca8b3b3138c819c91de9 Mon Sep 17 00:00:00 2001 From: yilmazt Date: Thu, 7 Nov 2019 19:17:58 +0300 Subject: [PATCH 067/134] executables are compiling --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 17 ++++--- .../nr_dl_channel_estimation.c | 18 +++---- openair1/SIMULATION/NR_PHY/dlsim.c | 4 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 21 +++------ openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 47 +++++++++---------- 5 files changed, 49 insertions(+), 58 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 3b79d425ad..8935e4e884 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -280,10 +280,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t harq_pid, uint8_t is_crnti) { - uint32_t A,E; uint32_t G; - uint32_t ret,offset; + uint32_t ret, offset; int32_t no_iteration_ldpc, length_dec; uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0; uint8_t crc_type; @@ -301,10 +300,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, int16_t z [68*384]; int8_t l [68*384]; - uint8_t kc; - uint8_t Ilbrm = 0; - uint32_t Tbslbrm = 950984; - double Coderate = 0.0; + uint8_t kc = 0; + uint8_t Ilbrm = 0; + uint32_t Tbslbrm = 950984; + double Coderate = 0.0; // ------------------------------------------------------------------ uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs; @@ -521,7 +520,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :", r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); @@ -607,7 +606,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int k=0;k>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -695,7 +694,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_ULSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr = %u bytes\n", r, Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index e9b93719c1..657f89b68c 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -199,12 +199,12 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned char symbol, - int dmrss, - uint8_t ssb_index, - uint8_t n_hf) + uint8_t eNB_offset, + unsigned char Ns, + unsigned char symbol, + int dmrss, + uint8_t ssb_index, + uint8_t n_hf) { int pilot[200] __attribute__((aligned(16))); unsigned char aarx,p; @@ -212,10 +212,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int ch_offset,symbol_offset; - int slot_pbch; - fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; + //int slot_pbch; + //fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) - uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; + //uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index e3e8eef767..640ea0331e 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -84,7 +84,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, co ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif - ){mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} + ){mac_rlc_status_resp_t mac_rlc_status_resp = {0}; return mac_rlc_status_resp;} tbs_size_t mac_rlc_data_req( const module_id_t module_idP, const rnti_t rntiP, @@ -862,7 +862,7 @@ int main(int argc, char **argv) if (errors_scrambling > 0) { if (n_trials == 1) - printf("errors_scrambling = %d (trial %d)\n", errors_scrambling, trial); + printf("errors_scrambling = %u (trial %d)\n", errors_scrambling, trial); } if (errors_bit > 0) { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index f196293ea0..b134e6aa2e 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -33,30 +33,23 @@ #ifndef __LAYER2_NR_MAC_DEFS_H__ #define __LAYER2_NR_MAC_DEFS_H__ - - #include #include #include - #include "platform_types.h" - #include "NR_DRX-Config.h" #include "NR_SchedulingRequestConfig.h" #include "NR_BSR-Config.h" #include "NR_TAG-Config.h" #include "NR_PHR-Config.h" #include "NR_RNTI-Value.h" - #include "NR_MIB.h" #include "NR_MAC-CellGroupConfig.h" #include "NR_PhysicalCellGroupConfig.h" #include "NR_SpCellConfig.h" - #include "NR_ServingCellConfig.h" #include "fapi_nr_ue_interface.h" #include "NR_IF_Module.h" - #include "PHY/defs_nr_common.h" #define NB_NR_UE_MAC_INST 1 @@ -71,13 +64,13 @@ typedef enum { typedef struct { //// MAC config - NR_DRX_Config_t *drx_Config; - NR_SchedulingRequestConfig_t *schedulingRequestConfig; - NR_BSR_Config_t *bsr_Config; - NR_TAG_Config_t *tag_Config; - NR_PHR_Config_t *phr_Config; - NR_RNTI_Value_t *cs_RNTI; - NR_MIB_t *mib; + NR_DRX_Config_t *drx_Config; + NR_SchedulingRequestConfig_t *schedulingRequestConfig; + NR_BSR_Config_t *bsr_Config; + NR_TAG_Config_t *tag_Config; + NR_PHR_Config_t *phr_Config; + NR_RNTI_Value_t *cs_RNTI; + NR_MIB_t *mib; /// Type0-PDCCH seach space fapi_nr_dl_config_dci_dl_pdu_rel15_t type0_pdcch_dci_config; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 6b9e79d510..fad52fe6e1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -82,6 +82,8 @@ uint8_t table_9_2_2_1[16][8]={ {1,0, 14,4, 0,3,6,9}, {1,0, 14,26,0,3,0,0} }; + + int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, @@ -217,17 +219,17 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, return 0; } -int8_t nr_ue_decode_mib( - UE_nr_rxtx_proc_t *proc, - module_id_t module_id, - int cc_id, - uint8_t gNB_index, - uint8_t extra_bits, // 8bits 38.212 c7.1.1 - uint32_t ssb_length, - uint32_t ssb_index, - void *pduP, - uint16_t cell_id ){ +int8_t nr_ue_decode_mib(UE_nr_rxtx_proc_t *proc, + module_id_t module_id, + int cc_id, + uint8_t gNB_index, + uint8_t extra_bits, // 8bits 38.212 c7.1.1 + uint32_t ssb_length, + uint32_t ssb_index, + void *pduP, + uint16_t cell_id) +{ LOG_I(MAC,"[L2][MAC] decode mib\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -435,18 +437,16 @@ int8_t nr_ue_decode_mib( mac->type0_pdcch_dci_config.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; mac->type0_pdcch_dci_config.coreset.pdcch_dmrs_scrambling_id = cell_id; - - // type0-pdcch search space float big_o; float big_m; uint32_t temp; - SFN_C_TYPE sfn_c; // only valid for mux=1 - uint32_t n_c; - uint32_t number_of_search_space_per_slot; - uint32_t first_symbol_index; - uint32_t search_space_duration; // element of search space - uint32_t coreset_duration; // element of coreset + SFN_C_TYPE sfn_c = SFN_C_MOD_2_EQ_0; // only valid for mux=1 + uint32_t n_c = 0; + uint32_t number_of_search_space_per_slot = 0; + uint32_t first_symbol_index = 0; + uint32_t search_space_duration; // element of search space + uint32_t coreset_duration; // element of coreset // 38.213 table 10.1-1 @@ -496,7 +496,7 @@ int8_t nr_ue_decode_mib( // 38.213 Table 13-13 AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n"); // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot -// sfn_c = SFN_C_EQ_SFN_SSB; + //sfn_c = SFN_C_EQ_SFN_SSB; n_c = get_ssb_slot(ssb_index); switch(ssb_index & 0x3){ // ssb_index(i) mod 4 case 0: @@ -518,7 +518,7 @@ int8_t nr_ue_decode_mib( // 38.213 Table 13-14 AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n"); // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot -// sfn_c = SFN_C_EQ_SFN_SSB; + //sfn_c = SFN_C_EQ_SFN_SSB; n_c = get_ssb_slot(ssb_index); switch(ssb_index & 0x7){ // ssb_index(i) mod 8 case 0: @@ -560,7 +560,7 @@ int8_t nr_ue_decode_mib( // 38.213 Table 13-15 AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n"); // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot -// sfn_c = SFN_C_EQ_SFN_SSB; + //sfn_c = SFN_C_EQ_SFN_SSB; n_c = get_ssb_slot(ssb_index); switch(ssb_index & 0x3){ // ssb_index(i) mod 4 case 0: @@ -597,8 +597,8 @@ int8_t nr_ue_decode_mib( mac->type0_pdcch_ss_n_c = n_c; // fill in the elements in config request inside P5 message - mac->phy_config.Mod_id = module_id; - mac->phy_config.CC_id = cc_id; + mac->phy_config.Mod_id = module_id; + mac->phy_config.CC_id = cc_id; mac->phy_config.config_req.pbch_config.system_frame_number = frame; // after calculation mac->phy_config.config_req.pbch_config.subcarrier_spacing_common = mac->mib->subCarrierSpacingCommon; @@ -620,7 +620,6 @@ int8_t nr_ue_decode_mib( } - // TODO: change to UE parameter, scs: 15KHz, slot duration: 1ms uint32_t get_ssb_frame(uint32_t test){ return test; From c4255f0dd4cc5f60386514104dc6ad44dd9dcd1a Mon Sep 17 00:00:00 2001 From: "masayuki.harada" Date: Thu, 7 Nov 2019 16:54:08 +0900 Subject: [PATCH 068/134] Fix cqi_req clear timing, and schedule PUSCH when CQI has not been received for a long time in fairRR scheduler. --- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 5b4eca635c..2006059d15 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -2092,7 +2092,8 @@ void ulsch_scheduler_pre_ue_select_fairRR( UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) { + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) || + ((UE_sched_ctl->cqi_req_timer>300)&&(UE_sched_ctl->ul_scheduled==0)) ) { first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; ue_first_num[CC_id]++; @@ -2200,7 +2201,8 @@ void ulsch_scheduler_pre_ue_select_fairRR( if ( (bytes_to_schedule > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) || ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) ) { + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) || + ((UE_sched_ctl->cqi_req_timer>300)&&(UE_sched_ctl->ul_scheduled==0)) ) { hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); @@ -2782,19 +2784,25 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, if (status < RRC_CONNECTED) cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer>30) { + else if (UE_sched_ctrl->cqi_received == 1){ + LOG_D(MAC,"Clearing CQI request timer\n"); + UE_sched_ctrl->cqi_req_flag = 0; + UE_sched_ctrl->cqi_received = 0; + UE_sched_ctrl->cqi_req_timer = 0; + cqi_req = 0; + }else if (UE_sched_ctrl->cqi_req_timer>30) { cqi_req = 1; // To be safe , do not ask CQI in special SFs:36.213/7.2.3 CQI definition if (cc->tdd_Config) { switch (cc->tdd_Config->subframeAssignment) { case 1: - if( sched_subframeP == 1 || sched_subframeP == 6 ) cqi_req=0; + if( subframeP == 1 || subframeP == 6 ) cqi_req=0; break; case 3: - if( sched_subframeP == 1 ) cqi_req=0; + if( subframeP == 1 ) cqi_req=0; break; @@ -2805,7 +2813,6 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, } if(cqi_req == 1) { - UE_sched_ctrl->cqi_req_timer=0; UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; } } else @@ -2884,6 +2891,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, //store for possible retransmission UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + UE_template->cqi_req[harq_pid] = cqi_req; UE_sched_ctrl->ul_scheduled |= (1<head) @@ -3054,6 +3062,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, //store for possible retransmission UE_template->nb_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; UE_template->first_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb; + cqi_req = UE_template->cqi_req[harq_pid]; UE_sched_ctrl->ul_scheduled |= (1< Date: Thu, 7 Nov 2019 21:57:57 +0900 Subject: [PATCH 069/134] Fix scheduling PUSCH when CQI has not been received for a long time in fairRR scheduler. --- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 2006059d15..98d1ffb576 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -1995,6 +1995,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( int format_flag; nfapi_hi_dci0_request_body_t *HI_DCI0_req; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + int rrc_status; for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) { //save ulsch dci number @@ -2090,10 +2091,11 @@ void ulsch_scheduler_pre_ue_select_fairRR( } UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) || - ((UE_sched_ctl->cqi_req_timer>300)&&(UE_sched_ctl->ul_scheduled==0)) ) { + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) || + ((UE_sched_ctl->cqi_req_timer>300)&&((rrc_status >= RRC_CONNECTED))) ) { first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; ue_first_num[CC_id]++; @@ -2198,11 +2200,12 @@ void ulsch_scheduler_pre_ue_select_fairRR( int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes; if (bytes_to_schedule < 0) bytes_to_schedule = 0; + rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); if ( (bytes_to_schedule > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) || ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) || - ((UE_sched_ctl->cqi_req_timer>300)&&(UE_sched_ctl->ul_scheduled==0)) ) { + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) || + ((UE_sched_ctl->cqi_req_timer>300)&&((rrc_status >= RRC_CONNECTED))) ) { hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); From ccd1b3be53d13bde798245e1efac3715db5eb616 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 7 Nov 2019 17:58:48 +0100 Subject: [PATCH 070/134] CI: preparing release notes for patch --> also adding TDD monolithic test at 20MHz with default scheduler --> putting IF4.p5 TDD scenarios with default scheduler Signed-off-by: Raphael Defosseux --- README.txt | 1 + ...and40_test_20mhz_tm1_default_scheduler.xml | 150 ++++++++++++++++++ .../if4p5_usrp210_band40_test_20mhz.xml | 2 +- 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml diff --git a/README.txt b/README.txt index c65502325f..59f48445e2 100644 --- a/README.txt +++ b/README.txt @@ -43,6 +43,7 @@ openairinterface5g RELEASE NOTES: +v1.1.1 -> November 2019. Bug fix in the TDD Fair Round-Robin scheduler v1.1.0 -> July 2019. This version adds the following implemented features: * Experimental support of LTE-M - Single LTE-M UE attachment, legacy-LTE UE attachment is disabled diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml new file mode 100644 index 0000000000..fd018f7a9c --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml @@ -0,0 +1,150 @@ + + + test-20-tm1-defSched + Test-20MHz-TM1-default-scheduler + tasks + + 030201 + 040101 + 030125 040301 040522 040627 040626 040628 040629 040630 040667 040666 040668 040669 040670 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (TDD/Band40/20MHz/info) + -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --MACRLCs.[0].scheduler_mode default + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (20MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(balanced) + -u -b 27.5M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(single-ue) + -u -b 27.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 27.5M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (20MHz - DL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (20MHz - DL/TCP)(30 sec) + -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (20MHz - UL/7Mbps/UDP)(30 sec)(balanced) + -u -b 7M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (20MHz - UL/7Mbps/UDP)(30 sec)(single-ue) + -u -b 7M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/7Mbps/UDP)(30 sec)(unbalanced) + -u -b 7M -t 30 -i 1 -R + 50 + unbalanced + + + + Iperf + iperf (20MHz - UL/TCP)(30 sec)(single-ue) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/TCP)(30 sec) + -t 30 -i 1 -fm -R + 50 + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml index 15d641efeb..cb54ba31ee 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml @@ -43,7 +43,7 @@ Initialize_eNB Initialize RCC (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf + -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf --MACRLCs.[0].scheduler_mode default 1 From ca2e8d3553484f16adeb9fb871bb209932b1ca34 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 7 Nov 2019 23:10:17 +0100 Subject: [PATCH 071/134] CI: tuning on TDD scenarios Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml | 4 ++-- ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml index 9c98ba4a8e..2a035396c5 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml @@ -25,7 +25,7 @@ test-05-tm2 Test-05MHz-TM2 tasks - 2 + 3 030201 040101 @@ -36,7 +36,7 @@ Initialize_eNB Initialize eNB (TDD/Band40/5MHz) - -O ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf + -O ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf --MACRLCs.[0].scheduler_mode default diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml index 79fc0b305c..648be0bfb5 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml @@ -27,7 +27,7 @@ 030201 040101 - 030124 040301 040521 040622 040621 040623 040624 040625 040662 040661 040663 040664 040665 040401 040201 030201 + 030124 040301 040521 040622 040621 040623 040662 040401 040201 030201 From cd14e5d3dcb2e59bbb3c37887cc52b00ee992e00 Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 13 Nov 2019 00:53:34 -0800 Subject: [PATCH 072/134] Clean code for monolithic case. Remove support for CU/DU. --- openair2/RRC/LTE/rrc_eNB.c | 68 ++++++++++++----------------------- targets/COMMON/create_tasks.c | 8 +++-- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 5522652a26..7807e6cd1a 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3201,18 +3201,17 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf500; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_infinity mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB - - mac_MainConfig->drx_Config = NULL; /* CDRX Configuration */ + mac_MainConfig->drx_Config = NULL; rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); /* Process the IE drx_Config */ - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + if (mac_MainConfig->drx_Config == NULL) { LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { @@ -3916,49 +3915,28 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB - if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { - /* CDRX Configuration */ - /* - uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; - LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; - // Need to check if UE is a BR UE - rnti_t rnti = ue_context_pP->ue_id_rnti; - module_id_t module_id = ctxt_pP->module_id; - int UE_id = find_UE_id(module_id, rnti); - - if (UE_id != -1) { - eNB_MAC_INST *mac = RC.mac[module_id]; - UE_list_t *UE_list = &(mac->UE_list); - - if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && - (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { - // CDRX can be only configured in case of FDD and non BR UE (09/04/19) - - LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); - - ///// Process the IE drx_Config / - if (cc_id < MAX_NUM_CCs) { - mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE - - if (mac_MainConfig->drx_Config == NULL) { - LOG_E(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); - } else { - ////// Set timers and thresholds values in local MAC context of UE / - eNB_Config_Local_DRX(module_id, rnti, mac_MainConfig->drx_Config); - LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); - } - } else { - LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); - } - } else { // CDRX not implemented for TDD and LTE-M (09/04/19) - LOG_E(RRC, "CDRX not implemented for TDD and LTE-M\n"); - } - } else { // UE_id invalid - LOG_E(RRC, "Invalid UE_id found!\n"); + /* CDRX Configuration */ + mac_MainConfig->drx_Config = NULL; + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ + if (NODE_IS_MONOLITHIC(rrc_inst->node_type)) { + mac_MainConfig->drx_Config = do_DrxConfig(cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + + if (mac_MainConfig->drx_Config == NULL) { + LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); + } else { + /* Send DRX configuration to MAC task to configure timers of local UE context */ + message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_MAC_DRX_CONFIG_REQ); + RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = rnti; + RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; + itti_send_msg_to_task(TASK_MAC_ENB, module_id, message_p); + LOG_D(RRC, "DRX configured in MAC Main Configuration for RRC Connection Reconfiguration\n"); } - */ - /* End of CDRX configuration */ } + /* End of CDRX configuration */ #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 2f7ff9d3a7..cbbd30b62c 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -91,9 +91,11 @@ int create_tasks(uint32_t enb_nb) { AssertFatal(rc >= 0, "Create task for DU F1AP failed\n"); } - LOG_I(MAC,"Creating MAC eNB Task\n"); - rc = itti_create_task(TASK_MAC_ENB, mac_enb_task, NULL); - AssertFatal(rc >= 0, "Create task for MAC eNB failed\n"); + if (!NODE_IS_CU(type)) { + LOG_I(MAC,"Creating MAC eNB Task\n"); + rc = itti_create_task(TASK_MAC_ENB, mac_enb_task, NULL); + AssertFatal(rc >= 0, "Create task for MAC eNB failed\n"); + } return 0; } From cc15b2231b86e3c4a2480c37bd0448fb7bb825ff Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 13 Nov 2019 01:21:56 -0800 Subject: [PATCH 073/134] Compilation fix --- openair2/RRC/LTE/rrc_eNB.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 7807e6cd1a..3d0a5453d6 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3684,6 +3684,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; + MessageDef *message_p = NULL; /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */ eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; @@ -3919,6 +3920,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt mac_MainConfig->drx_Config = NULL; rnti_t rnti = ue_context_pP->ue_id_rnti; module_id_t module_id = ctxt_pP->module_id; + uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); /* Process the IE drx_Config */ From ba17176c7c9bc1fadf4115f84463b6a4bee93869 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 21 Nov 2019 15:31:36 +0100 Subject: [PATCH 074/134] CI: putting back flexran-ctl in build/testing --> now on develop branch of this repo Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 2 +- ci-scripts/buildOnVM.sh | 6 +++++- ci-scripts/main.py | 4 ++-- ci-scripts/oai-ci-vm-tool | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 128a5fecfc..d201405255 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -131,8 +131,8 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] ]) { sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" + sh "git checkout develop >> ../git_clone.log 2>&1" } - sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies" sh "zip -r -qq flexran.zip ." } } diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 4583b2f30a..5142e3f265 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -168,8 +168,12 @@ function build_on_vm { echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS + echo "echo \"mkdir build\"" >> $VM_CMDS + echo "mkdir build" >> $VM_CMDS + echo "echo \"cd build\"" >> $VM_CMDS + echo "cd build" >> $VM_CMDS echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS - echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel14.txt 2>&1" >> $VM_CMDS + echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.Rel14.txt 2>&1" >> $VM_CMDS fi if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] then diff --git a/ci-scripts/main.py b/ci-scripts/main.py index bb00d806dd..1110a0b527 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -371,7 +371,7 @@ class SSHConnection(): self.open(lIpAddr, lUserName, lPassWord) self.command('mkdir -p ' + lSourcePath, '\$', 5) self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # Raphael: here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) @@ -524,7 +524,7 @@ class SSHConnection(): self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 07ecb54a0f..7ef779b121 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -210,7 +210,7 @@ function variant__v8__ue_ethernet { function variant__v10__flexran_rtc { ARCHIVES_LOC=flexran NB_PATTERN_FILES=1 - BUILD_OPTIONS="cmake . && make -j2" + BUILD_OPTIONS="cmake .. && make -j2" VARIANT_INFO="non-OSA" } function variant__v20__l1_sim { From 424bf5c53e879af7d66aaa50e0cd969eeb570dbd Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 4 Dec 2019 04:24:22 +0100 Subject: [PATCH 075/134] CI: adding a dummy build scenario for deactivated jobs Signed-off-by: Raphael Defosseux --- .../enb_usrp210_band13_test_10mhz_tm1.xml | 1 + ci-scripts/xml_files/simple_dummy_build.xml | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 ci-scripts/xml_files/simple_dummy_build.xml diff --git a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml index 1f4a82710c..d72722aa8c 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml @@ -24,6 +24,7 @@ test-10-tm1 Test-10MHz-TM1 tasks + 2 030201 040102 diff --git a/ci-scripts/xml_files/simple_dummy_build.xml b/ci-scripts/xml_files/simple_dummy_build.xml new file mode 100644 index 0000000000..75e5f6339a --- /dev/null +++ b/ci-scripts/xml_files/simple_dummy_build.xml @@ -0,0 +1,41 @@ + + + build-tab + Build + wrench + + 010101 + + + + + + Build_eNB + Build Master eNB (USRP) + -w USRP -c --eNB + 0 + 0 + + + From a78b5da529e9b4810e87f8f25bccd7ea03941dde Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 6 Dec 2019 08:40:21 +0100 Subject: [PATCH 076/134] fixes an issue with clock source - command line paramter --clock-source can only be set at UE (removed this option from gNB) - at gNB use clock_source from RU section in config file - in both cases if clock_source is present in usrp_args, it will override clock_source --- executables/nr-ru.c | 3 +++ executables/nr-softmodem.c | 1 - executables/nr-softmodem.h | 1 - executables/nr-uesoftmodem.c | 2 +- executables/nr-uesoftmodem.h | 2 +- targets/ARCH/COMMON/common_lib.h | 2 ++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 17 ++++++++++++----- targets/RT/USER/lte-softmodem.h | 2 +- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 1abcd3b7a1..135eb39f81 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -2252,6 +2252,9 @@ void RCconfig_RU(void) LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); } } + else { + RC.ru[j]->openair0_cfg.clock_source = unset; + } if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 931e2c1cd4..027ad0f9b2 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -106,7 +106,6 @@ int config_sync_var=-1; #endif volatile int oai_exit = 0; -static clock_source_t clock_source = internal; static int wait_for_sync = 0; unsigned int mmapped_dma=0; diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 5d259eb251..8334c99134 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -23,7 +23,6 @@ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ - {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index d8a916d13f..e0880c42a9 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -116,7 +116,7 @@ volatile int start_eNB = 0; volatile int start_UE = 0; volatile int oai_exit = 0; -static clock_source_t clock_source = internal; +static clock_source_t clock_source = unset; int single_thread_flag=1; static double snr_dB=20; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 717924e191..2434a1c23c 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -65,7 +65,7 @@ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ - {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ + {"clock-source", CONFIG_HLP_EXCCLK, 0, iptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 9192020b40..7052d6d40b 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -135,6 +135,8 @@ typedef struct { /*! \brief Clock source types */ typedef enum { + //! this means the paramter has not been set + unset=-1, //! This tells the underlying hardware to use the internal reference internal=0, //! This tells the underlying hardware to use the external reference diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e0e10fd899..70652c6f62 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1145,27 +1145,34 @@ extern "C" { device->priv = s; if (args.find("clock_source")==std::string::npos) { - LOG_I(HW, "Using clock_source == '%d'\n", openair0_cfg[0].clock_source); - if (openair0_cfg[0].clock_source == internal) { //in UHD 3.14 we could use //s->usrp->set_sync_source("clock_source=internal","time_source=internal"); s->usrp->set_time_source("internal"); s->usrp->set_clock_source("internal"); + LOG_D(HW,"Setting time and clock source to internal\n"); } else if (openair0_cfg[0].clock_source == external ) { //s->usrp->set_sync_source("clock_source=external","time_source=external"); s->usrp->set_time_source("external"); s->usrp->set_clock_source("external"); + LOG_D(HW,"Setting time and clock source to external\n"); } else if (openair0_cfg[0].clock_source==gpsdo) { s->usrp->set_clock_source("gpsdo"); s->usrp->set_time_source("gpsdo"); + LOG_D(HW,"Setting time and clock source to gpsdo\n"); + } + else { + LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n"); } - } else { - LOG_W(HW, "clock_source already specified in device arguments! Ignoring command line parameter\n"); } - + else { + if (openair0_cfg[0].clock_source != unset) { + LOG_W(HW,"Clock source set in both usrp_args and in clock_source, ingnoring the latter!\n"); + } + } + if (s->usrp->get_clock_source(0) == "gpsdo") { s->use_gps = 1; if (sync_to_gps(device)==EXIT_SUCCESS) { diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index f0cbbeceed..26a70843e6 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -146,7 +146,7 @@ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ - {"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \ + {"clock-source", CONFIG_HLP_CLK, 0, iptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \ } From 3566ef991eaa5395864c2f1966f5065389808d82 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 10 Dec 2019 10:53:01 +0100 Subject: [PATCH 077/134] programming pin 5 of GPIO to "Shutdown LNA" (high -> TX, low -> RX) --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 70652c6f62..d59980c310 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -319,8 +319,11 @@ static int trx_usrp_start(openair0_device *device) { s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); //set control register to ATR s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0x7f); - //set ATR register + //set pins 4 (RX_TX_Switch) and 6 (Shutdown PA) to 1 when the radio is only receiving (ATR_RX) s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f); + // set pin 5 (Shutdown LNA) to 1 when the radio is transmitting and receiveing (ATR_XX) + // (we use full duplex here, because our RX is on all the time - this might need to change later) + s->usrp->set_gpio_attr("FP0", "ATR_XX", (1<<5), 0x7f); // init recv and send streaming uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); LOG_I(HW,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); From 84f928e7de63d97e463a5e1b347889e2c82a20d3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 19 Sep 2019 17:53:08 +0200 Subject: [PATCH 078/134] CI: adding initial testing for MBMS: -- OAI eNB + OAI UE in USRP setting and in noS1 configuration Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 129 +++++++++++++++--- ...srp210_band7_test_05mhz_tm1_mbms_no_s1.xml | 82 +++++++++++ 2 files changed, 189 insertions(+), 22 deletions(-) create mode 100644 ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 1110a0b527..f6cece95c9 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -133,11 +133,13 @@ class SSHConnection(): self.eNB_serverId = '' self.eNBLogFiles = ['', '', ''] self.eNBOptions = ['', '', ''] + self.eNBmbmsEnables = [False, False, False] self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' self.iperf_packetloss_threshold = '' self.iperf_profile = '' + self.iperf_options = '' self.nbMaxUEtoAttach = -1 self.UEDevices = [] self.UEDevicesStatus = [] @@ -817,6 +819,17 @@ class SSHConnection(): self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2); else: self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "no";/\' ' + ci_full_config_file, '\$', 2); + self.eNBmbmsEnables[int(self.eNB_instance)] = False + self.command('grep enable_enb_m2 ' + ci_full_config_file, '\$', 2); + result = re.search('yes', str(self.ssh.before)) + if result is not None: + self.eNBmbmsEnables[int(self.eNB_instance)] = True + logging.debug('\u001B[1m MBMS is enabled on this eNB\u001B[0m') + result = re.search('noS1', str(self.Initialize_eNB_args)) + eNBinNoS1 = False + if result is not None: + eNBinNoS1 = True + logging.debug('\u001B[1m eNB is in noS1 configuration \u001B[0m') # Launch eNB with the modified config file self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) @@ -830,6 +843,7 @@ class SSHConnection(): time.sleep(6) doLoop = True loopCounter = 10 + enbDidSync = False while (doLoop): loopCounter = loopCounter - 1 if (loopCounter == 0): @@ -868,11 +882,27 @@ class SSHConnection(): time.sleep(6) else: doLoop = False - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) - logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') + enbDidSync = True time.sleep(10) + if enbDidSync and eNBinNoS1: + self.command('ifconfig oaitun_enb1', '\$', 4) + result = re.search('inet addr', str(self.ssh.before)) + if result is not None: + logging.debug('\u001B[1m oaitun_enb1 interface is mounted and configured\u001B[0m') + else: + logging.error('\u001B[1m oaitun_enb1 interface is either NOT mounted or NOT configured\u001B[0m') + if self.eNBmbmsEnables[int(self.eNB_instance)]: + self.command('ifconfig oaitun_enm1', '\$', 4) + result = re.search('inet addr', str(self.ssh.before)) + if result is not None: + logging.debug('\u001B[1m oaitun_enm1 interface is mounted and configured\u001B[0m') + else: + logging.error('\u001B[1m oaitun_enm1 interface is either NOT mounted or NOT configured\u001B[0m') + self.close() + self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) + logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') def InitializeUE_common(self, device_id, idx): try: @@ -1053,6 +1083,15 @@ class SSHConnection(): logging.debug(str(self.ssh.before)) logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') tunnelInterfaceStatus = False + if self.eNBmbmsEnables[0]: + self.command('ifconfig oaitun_uem1', '\$', 4) + result = re.search('inet addr', str(self.ssh.before)) + if result is not None: + logging.debug('\u001B[1m oaitun_uem1 interface is mounted and configured\u001B[0m') + tunnelInterfaceStatus = tunnelInterfaceStatus and True + else: + logging.error('\u001B[1m oaitun_uem1 interface is either NOT mounted or NOT configured\u001B[0m') + tunnelInterfaceStatus = False else: tunnelInterfaceStatus = True @@ -1066,7 +1105,10 @@ class SSHConnection(): self.UEDevicesStatus = [] self.UEDevicesStatus.append(UE_STATUS_DETACHED) else: - self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' + if self.eNBmbmsEnables[0]: + self.htmlUEFailureMsg = 'oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' + else: + self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') logging.error('\033[91mInitialize OAI UE Failed! \033[0m') self.AutoTerminateUEandeNB() @@ -2629,17 +2671,18 @@ class SSHConnection(): iClientIPAddr = self.eNBIPAddress iClientUser = self.eNBUserName iClientPasswd = self.eNBPassword - # Starting the iperf server - self.open(iServerIPAddr, iServerUser, iServerPasswd) - # args SHALL be "-c client -u any" - # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 - # -B 10.0.1.1 -u -s -i 1 -fm - server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) - server_options = server_options.replace('-c','-B') - self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) - self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) - time.sleep(0.5) - self.close() + if self.iperf_options != 'sink': + # Starting the iperf server + self.open(iServerIPAddr, iServerUser, iServerPasswd) + # args SHALL be "-c client -u any" + # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 + # -B 10.0.1.1 -u -s -i 1 -fm + server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) + server_options = server_options.replace('-c','-B') + self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) + self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) + time.sleep(0.5) + self.close() # Starting the iperf client modified_options = self.Iperf_ComputeModifiedBW(0, 1) @@ -2655,14 +2698,22 @@ class SSHConnection(): logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') clientStatus = -2 else: - clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) + if self.iperf_options == 'sink': + clientStatus = 0 + status_queue.put(0) + status_queue.put('OAI-UE') + status_queue.put('10.0.1.2') + status_queue.put('Sink Test : no check') + else: + clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) self.close() # Stopping the iperf server - self.open(iServerIPAddr, iServerUser, iServerPasswd) - self.command('killall --signal SIGKILL iperf', '\$', 5) - time.sleep(0.5) - self.close() + if self.iperf_options != 'sink': + self.open(iServerIPAddr, iServerUser, iServerPasswd) + self.command('killall --signal SIGKILL iperf', '\$', 5) + time.sleep(0.5) + self.close() if (clientStatus == -1): if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): os.remove('iperf_server_' + self.testCase_id + '.log') @@ -2670,9 +2721,10 @@ class SSHConnection(): self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) # copying on the EPC server for logCollection - copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') + if (clientStatus == -1): + copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') if (copyin_res == 0): self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') @@ -2964,6 +3016,7 @@ class SSHConnection(): ulschFailure = 0 cdrxActivationMessageCount = 0 dropNotEnoughRBs = 0 + mbmsRequestMsg = 0 self.htmleNBFailureMsg = '' isRRU = False isSlave = False @@ -3082,6 +3135,10 @@ class SSHConnection(): result = re.search('dropping, not enough RBs', str(line)) if result is not None: dropNotEnoughRBs += 1 + if self.eNBmbmsEnables[int(self.eNB_instance)]: + result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line)) + if result is not None: + mbmsRequestMsg += 1 enb_log_file.close() logging.debug(' File analysis completed') if uciStatMsgCount > 0: @@ -3125,6 +3182,11 @@ class SSHConnection(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' + if self.eNBmbmsEnables[int(self.eNB_instance)]: + if mbmsRequestMsg > 0: + rrcMsg = 'eNB requested ' + str(mbmsRequestMsg) + ' times the RLC for MBMS USER-PLANE' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' if X2HO_inNbProcedures > 0: rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') @@ -3196,6 +3258,7 @@ class SSHConnection(): mib_found = False frequency_found = False plmn_found = False + mbms_messages = 0 self.htmlUEFailureMsg = '' for line in ue_log_file.readlines(): result = re.search('Exiting OAI softmodem', str(line)) @@ -3235,6 +3298,10 @@ class SSHConnection(): result = re.search('No cell synchronization found, abandoning', str(line)) if result is not None: no_cell_sync_found = True + if self.eNBmbmsEnables[0]: + result = re.search('TRIED TO PUSH MBMS DATA', str(line)) + if result is not None: + mbms_messages += 1 result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P\d{1,3}), N_RB_DL (?P\d{1,3}), PHICH DURATION (?P\d), PHICH RESOURCE (?P.{1,4}), TX_ANT (?P\d)", str(line)) if result is not None and (not mib_found): try: @@ -3328,6 +3395,14 @@ class SSHConnection(): statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmlUEFailureMsg += statMsg + '\n' + if self.eNBmbmsEnables[0]: + if mbms_messages > 0: + statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + else: + statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' + logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' if foundSegFault: logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') return ENB_PROCESS_SEG_FAULT @@ -3421,6 +3496,7 @@ class SSHConnection(): logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m') self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!' self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) + self.eNBmbmsEnables[int(self.eNB_instance)] = False return if self.eNB_serverId != '0': self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/') @@ -3429,11 +3505,13 @@ class SSHConnection(): if (logStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', logStatus) self.preamtureExit = True + self.eNBmbmsEnables[int(self.eNB_instance)] = False return else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.eNBmbmsEnables[int(self.eNB_instance)] = False def TerminateHSS(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) @@ -4381,6 +4459,13 @@ def GetParametersFromXML(action): if SSH.iperf_profile != 'balanced' and SSH.iperf_profile != 'unbalanced' and SSH.iperf_profile != 'single-ue': logging.debug('ERROR: test-case has wrong profile ' + SSH.iperf_profile) SSH.iperf_profile = 'balanced' + SSH.iperf_options = test.findtext('iperf_options') + if (SSH.iperf_options is None): + SSH.iperf_options = 'check' + else: + if SSH.iperf_options != 'check' and SSH.iperf_options != 'sink': + logging.debug('ERROR: test-case has wrong option ' + SSH.iperf_options) + SSH.iperf_options = 'check' if action == 'IdleSleep': string_field = test.findtext('idle_sleep_time_in_sec') diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml new file mode 100644 index 0000000000..b841d3bab4 --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml @@ -0,0 +1,82 @@ + + + test-05-tm1-mbms-nos1-tunnel + Test-05MHz-MBMS-TM1-noS1-tunnel + tasks + 2 + + 030201 090109 + 030103 000001 090103 000002 040605 000001 090109 030201 + + + + + IdleSleep + Sleep + 10 + + + + IdleSleep + Sleep + 15 + + + + IdleSleep + Sleep + 60 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz/MBMS) + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_OAI_UE + Initialize OAI UE (FDD/Band7/5MHz/MBMS) + -C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1 + + + + Terminate_OAI_UE + Terminate OAI UE + + + + Iperf + iperf (5MHz - DL/1.5Mbps/UDP/MBMS-sink)(20 sec) + -c 10.0.2.2 -u -b 1.5M -t 20 -i 1 -fm -B 10.0.2.1 + 50 + sink + + + From 58734eb019d6b8016f1ea6f951d81e84054729cd Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 1 Oct 2019 15:23:49 +0200 Subject: [PATCH 079/134] MBMS Scheduler code cleanup MCH channel level calculation reformulated according to DLSCH ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c | 6 +-- openair1/SCHED/prach_procedures.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 60 ++++++------------------- 3 files changed, 18 insertions(+), 50 deletions(-) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c index 973891d034..dd49697d49 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c @@ -265,16 +265,16 @@ void mch_channel_level(int **dl_ch_estimates_ext, for (i=0; i<(nre>>2); i++) { #if defined(__x86_64__) || defined(__i386__) - avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); + avg128 = _mm_add_epi32(avg128,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),log2_approx(nre>>2)-1)); #elif defined(__arm__) #endif } - avg[aarx] = (((int*)&avg128)[0] + + avg[aarx] = (((((int*)&avg128)[0] + ((int*)&avg128)[1] + ((int*)&avg128)[2] + - ((int*)&avg128)[3])/nre; + ((int*)&avg128)[3])/(nre>>factor2(nre)))*(1<<(log2_approx(nre>>2)-1-factor2(nre)))); // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index 15d2c4fafc..eb62f1ed00 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -166,7 +166,7 @@ void prach_procedures(PHY_VARS_eNB *eNB { if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) { - LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", + LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", eNB->Mod_id, eNB->CC_id, frame, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index b1e9717a9e..d2b4779cf2 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -81,14 +81,12 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, } } -uint32_t bytes_in_buffer=0; -uint8_t msi_active=0; -uint8_t msi_pmch_stop=0; -uint8_t msi_pmch_stop2=0; - +static uint32_t bytes_in_buffer=0; +static uint8_t msi_pmch_stop=0; +//static uint8_t msi_active=0; +//static uint8_t msi_pmch_stop2=0; uint16_t mbms_rab_id = 2047; - -uint8_t msi_sfs=0; +static uint8_t msi_sfs=0; //MSI_ELEMENT * ptr =NULL; @@ -534,60 +532,30 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, //l=0; for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment + ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; - //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0x2; //100 - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) - //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; //100 - -// ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x0; // last subframeP of this mtch (only one mtch now) -// ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0x2; //100 - - //while((++l)*TBS<=bytes_in_buffer && l<=cc->pmch_Config[0]->sf_AllocEnd_r9){ - // if(l>=6 && l<=cc->pmch_Config[0]->sf_AllocEnd_r9){ - // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; //we limite till 256 TOFIX - // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = l; - // } - //} - //ptr = (MSI_ELEMENT *) msi_ptr; - if( msi_sfs != 0 ) msi_pmch_stop = msi_sfs-1; else msi_pmch_stop = msi_sfs; - //msi_pmch_stop = bytes_in_buffer/TBS; - //if(bytes_in_buffer%TBS) - //msi_pmch_stop++; - // - //msi_pmch_stop = 20; + if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9) + LOG_W(MAC,"e-MBMS Buffer Overflow\n"); + if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) & stop_sf limited to 256 //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop; ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); }else{ ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; //100 + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; msi_pmch_stop=0; } -// do{ -// if(l>=0 && l<=cc->pmch_Config[0]->sf_AllocEnd_r9){ -// ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; //we limite till 256 TOFIX -// ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = l; -// } -// }while((l++)*TBS<=bytes_in_buffer); -// - // if(((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB !=0x7 && ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB != 0xFF ) - // msi_active=1; - // else - // msi_active=1; - //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = l; - // l++; - // } + + + msi_ptr += sizeof(MSI_ELEMENT); } From 7d86b936cec1b4a42250fff0648a699196927110 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Thu, 3 Oct 2019 15:52:19 +0200 Subject: [PATCH 080/134] Added NFAPI MCH scheduling support M3AP ASN1 source spec updated ACKNOWLEDGEMENT: 1. This commit was developed at Vicomtech (https://www.vicomtech.org) under UE project CDN-X-ALL: "CDN edge-cloud computing for efficient cache and reliable streaming aCROSS Aggregated unicast-multicast LinkS" 2. Project funded by Fed4FIRE+ OC5 (https://www.fed4fire.eu) Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/pmch.c | 4 +- openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c | 12 +- openair1/SCHED/fapi_l1.c | 72 +- openair1/SCHED/fapi_l1.h | 5 + openair1/SCHED/phy_procedures_lte_eNb.c | 16 +- openair2/LAYER2/MAC/eNB_scheduler.c | 6 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 813 ++++++++++ .../LAYER2/MAC/eNB_scheduler_primitives.c | 33 + openair2/LAYER2/MAC/mac_proto.h | 20 + .../M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 | 1387 +++++++---------- 10 files changed, 1541 insertions(+), 827 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index 7d1c6a7525..f48ee629a1 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -102,9 +102,11 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a) eNB->common_vars.txdataF, AMP); + AssertFatal(eNB->dlsch_MCH->harq_processes[0]->pdu != NULL, "attempt to encode a NULL harq PDU\n"); AssertFatal(dlsch_encoding(eNB, - a, + // a, + eNB->dlsch_MCH->harq_processes[0]->pdu, 1, eNB->dlsch_MCH, proc->frame_tx, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c index dd49697d49..3c724cb8aa 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c @@ -319,17 +319,21 @@ void mch_channel_level_khz_1dot25(int **dl_ch_estimates_ext, for (i=0; i<(nre>>2); i++) { #if defined(__x86_64__) || defined(__i386__) - avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); + //avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); + avg128 = _mm_add_epi32(avg128,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),log2_approx(nre>>2)-1)); #elif defined(__arm__) #endif } - avg[aarx] = (((int*)&avg128)[0] + + // avg[aarx] = (((int*)&avg128)[0] + + // ((int*)&avg128)[1] + + // ((int*)&avg128)[2] + + // ((int*)&avg128)[3])/nre; + avg[aarx] = (((((int*)&avg128)[0] + ((int*)&avg128)[1] + ((int*)&avg128)[2] + - ((int*)&avg128)[3])/nre; - + ((int*)&avg128)[3])/(nre>>factor2(nre)))*(1<<(log2_approx(nre>>2)-1-factor2(nre)))); //printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 14babd829c..46a3add522 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -139,6 +139,54 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, // adjust transmit amplitude here based on NFAPI info } + +void handle_nfapi_mch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t *sdu){ + + nfapi_dl_config_mch_pdu_rel8_t *rel8 = &dl_config_pdu->mch_pdu.mch_pdu_rel8; + + LTE_eNB_DLSCH_t *dlsch = eNB->dlsch_MCH; + LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms; + + // dlsch->rnti = M_RNTI; + dlsch->harq_processes[0]->mcs = rel8->modulation; + // dlsch->harq_processes[0]->Ndi = ndi; + dlsch->harq_processes[0]->rvidx = 0;//rvidx; + dlsch->harq_processes[0]->Nl = 1; + dlsch->harq_processes[0]->TBS = TBStable[get_I_TBS(dlsch->harq_processes[0]->mcs)][frame_parms->N_RB_DL-1]; + // dlsch->harq_ids[subframe] = 0; + dlsch->harq_processes[0]->nb_rb = frame_parms->N_RB_DL; + + switch(frame_parms->N_RB_DL) { + case 6: + dlsch->harq_processes[0]->rb_alloc[0] = 0x3f; + break; + + case 25: + dlsch->harq_processes[0]->rb_alloc[0] = 0x1ffffff; + break; + + case 50: + dlsch->harq_processes[0]->rb_alloc[0] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc[1] = 0x3ffff; + break; + + case 100: + dlsch->harq_processes[0]->rb_alloc[0] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc[1] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc[2] = 0xffffffff; + dlsch->harq_processes[0]->rb_alloc[3] = 0xf; + break; + } + + dlsch->harq_ids[proc->frame_tx%2][proc->subframe_tx] = 0; + + dlsch->harq_processes[0]->pdu = sdu; + + dlsch->active = 1; +} + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) extern uint32_t localRIV2alloc_LUT6[32]; extern uint32_t localRIV2alloc_LUT25[512]; @@ -839,8 +887,30 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { break; - case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + case NFAPI_DL_CONFIG_MCH_PDU_TYPE:{ // handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu); + //AssertFatal(1==0,"OK\n"); + nfapi_dl_config_mch_pdu_rel8_t *mch_pdu_rel8 = &dl_config_pdu->mch_pdu.mch_pdu_rel8; + uint16_t pdu_index = mch_pdu_rel8->pdu_index; + uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus; + uint16_t invalid_pdu = pdu_index == -1; + uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data; + LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_MCH_PDU_TYPE SFN/SF:%04d%d TX:%d/%d RX:%d/%d pdu_index:%d sdu:%p\n", + __FUNCTION__, i, + NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf), + proc->frame_tx, proc->subframe_tx, + proc->frame_rx, proc->subframe_rx, + pdu_index, sdu); + if (sdu) { //sdu != NULL) + if (NFAPI_MODE!=NFAPI_MODE_VNF) + handle_nfapi_mch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, sdu); + } else { + dont_send=1; + LOG_E(MAC,"%s() NFAPI_DL_CONFIG_MCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, + NFAPI_SFNSF2DEC(TX_req->sfn_sf), tx_pdus); + } + do_oai=1; + } break; case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: { diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 3bd469b685..05ec813917 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -53,6 +53,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); + +void handle_nfapi_mch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t *sdu); + void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index d524c9270c..1a26af566a 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -47,6 +47,8 @@ #include "intertask_interface.h" +#define MBMS_NFAPI_SCHEDULER + nfapi_ue_release_request_body_t release_rntis; int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) { @@ -117,6 +119,16 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr return(subframe_select(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe)); } +#ifdef MBMS_NFAPI_SCHEDULER +void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { + int subframe = proc->subframe_tx; + // This is DL-Cell spec pilots in Control region + generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1); + if(eNB->dlsch_MCH->active==1) + generate_mch (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/); + eNB->dlsch_MCH->active = 0; +} +#else void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) MCH_PDU *mch_pduP=NULL; @@ -151,14 +163,16 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { if (mch_pduP) { fill_eNB_dlsch_MCH (eNB, mch_pduP->mcs, 1, 0); eNB->dlsch_MCH->harq_ids[proc->frame_tx%2][subframe] = 0; + eNB->dlsch_MCH->harq_processes[0]->pdu=(uint8_t *) mch_pduP->payload; // Generate PMCH - generate_mch (eNB, proc, (uint8_t *) mch_pduP->payload); + generate_mch (eNB, proc, NULL/*(uint8_t *) mch_pduP->payload*/); } else { LOG_D (PHY, "[eNB/RN] Frame %d subframe %d: MCH not generated \n", proc->frame_tx, subframe); } #endif } +#endif void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 76fae02374..29fd6eeb80 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -940,7 +940,11 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { if (cc[CC_id].MBMS_flag > 0) { start_meas(&RC.mac[module_idP]->schedule_mch); - mbsfn_status[CC_id] = schedule_MBMS(module_idP, CC_id, frameP, subframeP); + int(*schedule_mch)(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframe) = NULL; + schedule_mch = schedule_MBMS_NFAPI; + if(schedule_mch){ + mbsfn_status[CC_id] = schedule_mch(module_idP, CC_id, frameP, subframeP); + } stop_meas(&RC.mac[module_idP]->schedule_mch); } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index d2b4779cf2..13bf54bb88 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -34,6 +34,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_extern.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -92,6 +93,818 @@ static uint8_t msi_sfs=0; //MSI_ELEMENT * ptr =NULL; +int +schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, + sub_frame_t subframeP) +{ + + nfapi_dl_config_request_body_t *dl_req; + //nfapi_dl_config_request_pdu_t *dl_config_pdu; + + int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; + int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); + int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + if(RC.mac[module_idP]->common_channels[CC_id]. + pmch_Config[0] == NULL ) + + return 0; + + + + + int mch_scheduling_period = + 8 << (RC.mac[module_idP]->common_channels[CC_id]. + pmch_Config[0]->mch_SchedulingPeriod_r9); + unsigned char mcch_sdu_length; + unsigned char header_len_mcch = 0, header_len_msi = + 0, header_len_mtch = 0, header_len_mtch_temp = + 0, header_len_mcch_temp = 0, header_len_msi_temp = 0; + int ii = 0, msi_pos = 0; + int mcch_mcs = -1; + uint16_t TBS, j = -1, padding = 0, post_padding = 0; + mac_rlc_status_resp_t rlc_status; + int num_mtch; + int msi_length, i, k; + //uint8_t l =0; + unsigned char sdu_lcids[11], num_sdus = 0, offset = 0; + uint16_t sdu_lengths[11], sdu_length_total = 0; + unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only + + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; + + cc->MCH_pdu.Pdu_size = 0; + + for (i = 0; i < cc->num_active_mbsfn_area; i++) { + // assume, that there is always a mapping + if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) { + return 0; + } + + mbsfn_period = + 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); + mcch_period = + 32 << (cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_RepetitionPeriod_r9); + msi_pos = 0; + ii = 0; + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n", + module_idP, CC_id, frameP, subframeP, i, + cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern, + mbsfn_period, mcch_period); + + + switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; + + case 1: + mcch_mcs = 7; + break; + + case 2: + mcch_mcs = 13; + break; + + case 3: + mcch_mcs = 19; + break; + } + + // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) + if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP + if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + + // Find the first subframeP in this MCH to transmit MSI + if (frameP % mch_scheduling_period == + cc->mbsfn_SubframeConfig[j]-> + radioframeAllocationOffset) { + while (ii == 0) { + ii = cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & (0x80 >> msi_pos); + msi_pos++; + } + + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", + module_idP, CC_id, frameP, subframeP, i, j, + cc->mbsfn_SubframeConfig[j]-> + subframeAllocation.choice.oneFrame.buf[0], + msi_pos); + } + // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframeP) { + case 1: + if (cc->tdd_Config == NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == + MBSFN_FDD_SF1) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF1) == + MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 2: + if (cc->tdd_Config == NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == + MBSFN_FDD_SF2) { + if (msi_pos == 2) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF2) == + MBSFN_FDD_SF2)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 3: + if (cc->tdd_Config != NULL) { // TDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == + MBSFN_TDD_SF3) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF3) == + MBSFN_TDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } else { // FDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == + MBSFN_FDD_SF3) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF3) == + MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 4: + if (cc->tdd_Config != NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == + MBSFN_TDD_SF4) { + if (msi_pos == 2) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF4) == + MBSFN_TDD_SF4)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 6: + if (cc->tdd_Config == NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == + MBSFN_FDD_SF6) { + if (msi_pos == 4) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF6) == + MBSFN_FDD_SF6)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 7: + if (cc->tdd_Config != NULL) { // TDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == + MBSFN_TDD_SF7) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF7) == + MBSFN_TDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } else { // FDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == + MBSFN_FDD_SF7) { + if (msi_pos == 5) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF7) == + MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 8: + if (cc->tdd_Config != NULL) { //TDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == + MBSFN_TDD_SF8) { + if (msi_pos == 4) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF8) == + MBSFN_TDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } else { // FDD + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == + MBSFN_FDD_SF8) { + if (msi_pos == 6) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_FDD_SF8) == + MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + + case 9: + if (cc->tdd_Config != NULL) { + if ((cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == + MBSFN_TDD_SF9) { + if (msi_pos == 5) { + msi_flag = 1; + } + + if ((frameP % mcch_period == + cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_Offset_r9) + && + ((cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.sf_AllocInfo_r9. + buf[0] & MBSFN_TDD_SF9) == + MBSFN_TDD_SF9)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } + + break; + } // end switch + + // sf allocation is non-overlapping + if ((msi_flag == 1) || (mcch_flag == 1) + || (mtch_flag == 1)) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + module_idP, CC_id, frameP, subframeP, i, j, + msi_flag, mcch_flag, mtch_flag); + break; + } + } else { // four-frameP format + } + } + } // end of for loop + + cc->msi_active = 0; + cc->mcch_active = 0; + cc->mtch_active = 0; + + // Calculate the mcs + if ((msi_flag == 1) || (mcch_flag == 1)) { + cc->MCH_pdu.mcs = mcch_mcs; + } else if (mtch_flag == 1) { // only MTCH in this subframeP + cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; + } + + + uint8_t num_sf_alloc=0; + for( int iii=0; iii < 6; iii++) + num_sf_alloc += ( 0x39 & (0x80>>iii)) == (0x80 >> iii); + num_sf_alloc = 1; + + // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC + + // there is MSI (MCH Scheduling Info) + if (msi_flag == 1) { + // Create MSI here + uint16_t msi_control_element[29], *msi_ptr; + + msi_ptr = &msi_control_element[0]; + //((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH + + //if (mcch_flag == 1) { + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; + //} else { // no mcch for this MSP + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047 + // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; + //} + + //msi_ptr += sizeof(MSI_ELEMENT); + + //Header for MTCHs + num_mtch = cc->mbms_SessionList[0]->list.count; + + TBS = + get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); + //l=0; + + for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment + + ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; + + if( msi_sfs != 0 ) + msi_pmch_stop = msi_sfs-1; + else + msi_pmch_stop = msi_sfs; + + if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9) + LOG_W(MAC,"e-MBMS Buffer Overflow\n"); + + if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) & stop_sf limited to 256 + //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop; + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); + msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); + }else{ + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; + msi_pmch_stop=0; + } + + + + msi_ptr += sizeof(MSI_ELEMENT); + } + + msi_length = msi_ptr - msi_control_element; + + if (msi_length < 128) { + header_len_msi = 2; + } else { + header_len_msi = 3; + } + + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes TBS %d, bytes in buffer %d stop_sf_LSB %d msi_sfs %d cc->pmch_Config[0]->sf_AllocEnd_r9 %ld\n", + module_idP, CC_id, frameP, msi_length,TBS, bytes_in_buffer,msi_pmch_stop,msi_sfs,cc->pmch_Config[0]->sf_AllocEnd_r9); + + msi_sfs = 0; + + //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" ); + + // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length); + // Store MSI data to mch_buffer[0] + memcpy((char *) &mch_buffer[sdu_length_total], + msi_control_element, msi_length); + + sdu_lcids[num_sdus] = MCH_SCHDL_INFO; + sdu_lengths[num_sdus] = msi_length; + sdu_length_total += sdu_lengths[num_sdus]; + LOG_D(MAC, "[eNB %d] CC_id %d Create %d bytes for MSI\n", + module_idP, CC_id, sdu_lengths[num_sdus]); + num_sdus++; + cc->msi_active = 1; + } + // there is MCCH + if (mcch_flag == 1) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", + module_idP, CC_id, frameP, subframeP, i, j); + + mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], + i); // this is the mbsfn sync area index + + mcch_sdu_length+=1; //RLC ? + + if (mcch_sdu_length > 0) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", + module_idP, CC_id, frameP, subframeP, mcch_sdu_length); + + header_len_mcch = 2; + + if (cc->tdd_Config != NULL) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } else { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } + + cc->mcch_active = 1; + + memcpy((char *) &mch_buffer[sdu_length_total]+1, + &cc->MCCH_pdu.payload[0], mcch_sdu_length); + sdu_lcids[num_sdus] = MCCH_LCHANID; + sdu_lengths[num_sdus] = mcch_sdu_length; + + if (sdu_lengths[num_sdus] > 128) { + header_len_mcch = 3; + } + + sdu_length_total += sdu_lengths[num_sdus]; + LOG_D(MAC, + "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n", + module_idP, CC_id, sdu_lengths[num_sdus]); + num_sdus++; + } + } + + TBS = + get_TBS_DL(/*cc->pmch_Config[0]->dataMCS_r9*/cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // do not let mcch and mtch multiplexing when relaying is active + // for sync area 1, so not transmit data + //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { +#endif + + // there is MTCHs, loop if there are more than 1 + if (mtch_flag == 1 ) { + // Calculate TBS + /* if ((msi_flag==1) || (mcch_flag==1)) { + TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL); + } + else { // only MTCH in this subframeP + TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL); + } + + // get MTCH data from RLC (like for DTCH) + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j); + + header_len_mtch = 3; + LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + Mod_id,CC_id,frame,MTCH,TBS, + TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); + + rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG, + TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); + printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); + + */ + + // get MTCH data from RLC (like for DTCH) + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", + module_idP, CC_id, frameP, subframeP, i, j); + + header_len_mtch = 3; + LOG_D(MAC, + "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + module_idP, CC_id, frameP, MTCH, TBS, + TBS - header_len_mcch - header_len_msi - sdu_length_total - + header_len_mtch); + + mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9; + + rlc_status = + mac_rlc_status_ind(module_idP, 0, frameP, subframeP, + module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, + cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, + //MTCH, + TBS - header_len_mcch - header_len_msi - + sdu_length_total - header_len_mtch +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 +#endif + ); + bytes_in_buffer = rlc_status.bytes_in_buffer; + + + msi_sfs = rlc_status.bytes_in_buffer/TBS+(rlc_status.bytes_in_buffer%TBS?1:0); + + LOG_D(MAC, + "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS %d pmch_stop %d msi_sfs %d\n", + MTCH, frameP, subframeP, rlc_status.bytes_in_buffer,TBS,msi_pmch_stop,msi_sfs); + + if (rlc_status.bytes_in_buffer > 0 || msi_pmch_stop > 0 /*msi_pmch_stop>=num_sf_alloc*/ ) { + //if(rlc_status.bytes_in_buffer > 0){ + LOG_I(MAC, + "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d) rlc_status.bytes_in_buffer %d\n", + module_idP, CC_id, frameP, + TBS - header_len_mcch - header_len_msi - + sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer); + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, 0, //not used + (char *) + &mch_buffer[sdu_length_total] +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, + 0 +#endif + ); + + //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]); + LOG_I(MAC, + "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_sfs %d sdu_lengths[num_sdus] %d\n", + module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs, sdu_lengths[num_sdus]); + cc->mtch_active = 1; + sdu_lcids[num_sdus] = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9/*MTCH*/; + sdu_length_total += sdu_lengths[num_sdus]; + + if (msi_pmch_stop != 0) + msi_pmch_stop--; + + + if (sdu_lengths[num_sdus] < 128) { + header_len_mtch = 2; + } + + num_sdus++; + //} + } + else { + // LOG_E(MAC, + // "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_buffer %d msi_sfs %ld msi_buffer_act %ld sdu_lengths[num_sdus] %d\n", + // module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs,msi_buffer_act, sdu_lengths[num_sdus]); + + header_len_mtch = 0; + } + } +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // } +#endif + + // FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs + if ((sdu_length_total + header_len_msi + header_len_mcch + + header_len_mtch) > 0) { + // Adjust the last subheader + /* if ((msi_flag==1) || (mcch_flag==1)) { + RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs; + } + else if (mtch_flag == 1) { // only MTCH in this subframeP + RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9; + } + */ + header_len_mtch_temp = header_len_mtch; + header_len_mcch_temp = header_len_mcch; + header_len_msi_temp = header_len_msi; + + if (header_len_mtch > 0) { + header_len_mtch = 1; // remove Length field in the subheader for the last PDU + } else if (header_len_mcch > 0) { + header_len_mcch = 1; + } else { + header_len_msi = 1; + } + + // Calculate the padding + if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - + sdu_length_total) < 0) { + LOG_E(MAC, "Error in building MAC PDU, TBS %d < PDU %d \n", + TBS, + header_len_mtch + header_len_mcch + header_len_msi + + sdu_length_total); + return 0; + } else + if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - + sdu_length_total) <= 2) { + padding = + (TBS - header_len_mtch - header_len_mcch - header_len_msi - + sdu_length_total); + post_padding = 0; + } else { // using post_padding, give back the Length field of subheader for the last PDU + padding = 0; + + if (header_len_mtch > 0) { + header_len_mtch = header_len_mtch_temp; + } else if (header_len_mcch > 0) { + header_len_mcch = header_len_mcch_temp; + } else { + header_len_msi = header_len_msi_temp; + } + + post_padding = + TBS - sdu_length_total - header_len_msi - header_len_mcch - + header_len_mtch; + } + + // Generate the MAC Header for MCH + // here we use the function for DLSCH because DLSCH & MCH have the same Header structure + offset = generate_dlsch_header((unsigned char *) cc->MCH_pdu.payload, num_sdus, sdu_lengths, sdu_lcids, 255, // no drx + 31, // no timing advance + NULL, // no contention res id + padding, post_padding); + + cc->MCH_pdu.Pdu_size = TBS; + cc->MCH_pdu.sync_area = i; + cc->MCH_pdu.msi_active = cc->msi_active; + cc->MCH_pdu.mcch_active = cc->mcch_active; + cc->MCH_pdu.mtch_active = cc->mtch_active; + LOG_D(MAC, + " MCS for this sf is %d (mcch active %d, mtch active %d)\n", + cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active, + cc->MCH_pdu.mtch_active); + LOG_D(MAC, + "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", + module_idP, CC_id, sdu_length_total, num_sdus, + sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding, + cc->MCH_pdu.mcs, TBS, header_len_mtch, header_len_mcch, + header_len_msi); + // copy SDU to mch_pdu after the MAC Header + memcpy(&cc->MCH_pdu.payload[offset], mch_buffer, sdu_length_total); + + // filling remainder of MCH with random data if necessery + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + cc->MCH_pdu.payload[offset + sdu_length_total + j] = + (char) (taus() & 0xff); + } + + /* Tracing of PDU is done on UE side */ + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xffff, // M_RNTI = 6 in wirehsark + RC.mac[module_idP]->frame, + RC.mac[module_idP]->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n", + module_idP, CC_id, frameP, TBS); + } + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + // dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + // memset((void *) dl_config_pdu, + // 0, + // sizeof(nfapi_dl_config_request_pdu_t)); + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + fill_nfapi_mch_config( + dl_req, + TBS, + 0, + 0xfffd, + 0, + get_Qm(cc->MCH_pdu.mcs), + cc->MCH_pdu.mcs, + 6000, //equal to RS power + 0 //mbsfn_area_id + ); + + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, + (frameP * 10) + subframeP, + TBS, + eNB->pdu_index[CC_id], + (uint8_t*)cc->MCH_pdu.payload); + + + /* + for (j=0;jMCH_pdu.payload[j+offset]); + printf(" \n"); */ + return 1; + } else { + cc->MCH_pdu.Pdu_size = 0; + cc->MCH_pdu.sync_area = 0; + cc->MCH_pdu.msi_active = 0; + cc->MCH_pdu.mcch_active = 0; + cc->MCH_pdu.mtch_active = 0; + // for testing purpose, fill with random data + //for (j=0;j<(TBS-sdu_length_total-offset);j++) + // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); + return 0; + } + + //this is for testing + /* + if (mtch_flag == 1) { + // LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]); + return 1; + } + else + return 0; + */ +} int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 6750998b9f..12df50a048 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1605,6 +1605,39 @@ fill_nfapi_uci_acknak(module_id_t module_idP, return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); } +//------------------------------------------------------------------------------ + +void +fill_nfapi_mch_config(nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint16_t resource_block_coding, + uint8_t modulation, + uint16_t transmission_power, + uint8_t mbsfn_area_id){ + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mch_pdu)); + dl_config_pdu->mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG; + dl_config_pdu->mch_pdu.mch_pdu_rel8.length = length; + dl_config_pdu->mch_pdu.mch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->mch_pdu.mch_pdu_rel8.rnti = rnti; + dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->mch_pdu.mch_pdu_rel8.modulation = modulation; + dl_config_pdu->mch_pdu.mch_pdu_rel8.transmission_power = transmission_power; + dl_config_pdu->mch_pdu.mch_pdu_rel8.mbsfn_area_id = mbsfn_area_id; + dl_req->number_pdu++; +} + +//------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------ void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 695005cd1f..4f6f9cd75b 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -86,6 +86,15 @@ void schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframe); +/** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0; +@param Mod_id Instance ID of eNB +@param frame Frame index +@param subframe Subframe number on which to act +*/ +int schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, + sub_frame_t subframe); + + /** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping @param Mod_id Instance ID of eNB @param mbsfn_sync_area index of mbsfn sync area @@ -1217,6 +1226,17 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, frame_t frameP, sub_frame_t subframeP, uint8_t cce_idx); +void +fill_nfapi_mch_config(nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint16_t resource_block_coding, + uint8_t modulation, + uint16_t transmission_power, + uint8_t mbsfn_area_id); + void fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, nfapi_dl_config_request_body_t * dl_req, uint16_t length, int16_t pdu_index, diff --git a/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 b/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 index 009eebb13e..b5878c27be 100644 --- a/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 +++ b/openair3/M3AP/MESSAGES/ASN1/R14/m3ap-14.0.0.asn1 @@ -3,679 +3,566 @@ -- Elementary Procedure definitions -- -- ************************************************************** - M3AP-PDU-Descriptions { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-PDU-Descriptions (0) } -DEFINITIONS AUTOMATIC TAGS ::= - +DEFINITIONS AUTOMATIC TAGS ::= BEGIN - -- ************************************************************** -- -- IE parameter types from other modules. -- -- ************************************************************** - IMPORTS - Criticality, - ProcedureCode + Criticality, + ProcedureCode FROM M3AP-CommonDataTypes - - MBMSSessionStartRequest, - MBMSSessionStartResponse, - MBMSSessionStartFailure, - MBMSSessionStopRequest, - MBMSSessionStopResponse, - MBMSSessionUpdateRequest, - MBMSSessionUpdateResponse, - MBMSSessionUpdateFailure, - MCEConfigurationUpdate, - MCEConfigurationUpdateAcknowledge, - MCEConfigurationUpdateFailure, - M3SetupRequest, - M3SetupResponse, - M3SetupFailure, - ErrorIndication, - Reset, - ResetAcknowledge, - PrivateMessage - + MBMSSessionStartRequest, + MBMSSessionStartResponse, + MBMSSessionStartFailure, + MBMSSessionStopRequest, + MBMSSessionStopResponse, + MBMSSessionUpdateRequest, + MBMSSessionUpdateResponse, + MBMSSessionUpdateFailure, + MCEConfigurationUpdate, + MCEConfigurationUpdateAcknowledge, + MCEConfigurationUpdateFailure, + M3SetupRequest, + M3SetupResponse, + M3SetupFailure, + ErrorIndication, + Reset, + ResetAcknowledge, + PrivateMessage FROM M3AP-PDU-Contents - - id-mBMSsessionStart, - id-mBMSsessionStop, - id-mBMSsessionUpdate, - id-mCEConfigurationUpdate, - id-m3Setup, - id-errorIndication, - id-Reset, - id-privateMessage + id-mBMSsessionStart, + id-mBMSsessionStop, + id-mBMSsessionUpdate, + id-mCEConfigurationUpdate, + id-m3Setup, + id-errorIndication, + id-Reset, + id-privateMessage FROM M3AP-Constants; - - -- ************************************************************** -- -- Interface Elementary Procedure Class -- -- ************************************************************** - M3AP-ELEMENTARY-PROCEDURE ::= CLASS { - &InitiatingMessage , - &SuccessfulOutcome OPTIONAL, - &UnsuccessfulOutcome OPTIONAL, - &procedureCode ProcedureCode UNIQUE, - &criticality Criticality DEFAULT ignore + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore } WITH SYNTAX { - INITIATING MESSAGE &InitiatingMessage - [SUCCESSFUL OUTCOME &SuccessfulOutcome] - [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] - PROCEDURE CODE &procedureCode - [CRITICALITY &criticality] + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] } - -- ************************************************************** -- -- Interface PDU Definition -- -- ************************************************************** - M3AP-PDU ::= CHOICE { - initiatingMessage InitiatingMessage, - successfulOutcome SuccessfulOutcome, - unsuccessfulOutcome UnsuccessfulOutcome, - ... + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... } - InitiatingMessage ::= SEQUENCE { - procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), - criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value M3AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) } - SuccessfulOutcome ::= SEQUENCE { - procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), - criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value M3AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) } - UnsuccessfulOutcome ::= SEQUENCE { - procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), - criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), - value M3AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) + procedureCode M3AP-ELEMENTARY-PROCEDURE.&procedureCode ({M3AP-ELEMENTARY-PROCEDURES}), + criticality M3AP-ELEMENTARY-PROCEDURE.&criticality ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value M3AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({M3AP-ELEMENTARY-PROCEDURES}{@procedureCode}) } - - -- ************************************************************** -- -- Interface Elementary Procedure List --- +-- -- ************************************************************** - M3AP-ELEMENTARY-PROCEDURES M3AP-ELEMENTARY-PROCEDURE ::= { - M3AP-ELEMENTARY-PROCEDURES-CLASS-1 | - M3AP-ELEMENTARY-PROCEDURES-CLASS-2 , - ... + M3AP-ELEMENTARY-PROCEDURES-CLASS-1 | + M3AP-ELEMENTARY-PROCEDURES-CLASS-2 , + ... } - M3AP-ELEMENTARY-PROCEDURES-CLASS-1 M3AP-ELEMENTARY-PROCEDURE ::= { - mBMSsessionStart | - mBMSsessionStop | - mBMSsessionUpdate | - reset | - m3Setup | - mCEConfigurationUpdate , - ... + mBMSsessionStart | + mBMSsessionStop | + mBMSsessionUpdate | + reset | + m3Setup | + mCEConfigurationUpdate , + ... } - M3AP-ELEMENTARY-PROCEDURES-CLASS-2 M3AP-ELEMENTARY-PROCEDURE ::= { - errorIndication | - privateMessage , - ... - + errorIndication | + privateMessage , + ... } - - -- ************************************************************** -- -- Interface Elementary Procedures -- -- ************************************************************** - mBMSsessionStart M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE MBMSSessionStartRequest - SUCCESSFUL OUTCOME MBMSSessionStartResponse - UNSUCCESSFUL OUTCOME MBMSSessionStartFailure - PROCEDURE CODE id-mBMSsessionStart - CRITICALITY reject + INITIATING MESSAGE MBMSSessionStartRequest + SUCCESSFUL OUTCOME MBMSSessionStartResponse + UNSUCCESSFUL OUTCOME MBMSSessionStartFailure + PROCEDURE CODE id-mBMSsessionStart + CRITICALITY reject } - mBMSsessionStop M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE MBMSSessionStopRequest - SUCCESSFUL OUTCOME MBMSSessionStopResponse - PROCEDURE CODE id-mBMSsessionStop - CRITICALITY reject + INITIATING MESSAGE MBMSSessionStopRequest + SUCCESSFUL OUTCOME MBMSSessionStopResponse + PROCEDURE CODE id-mBMSsessionStop + CRITICALITY reject } - mBMSsessionUpdate M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE MBMSSessionUpdateRequest - SUCCESSFUL OUTCOME MBMSSessionUpdateResponse - UNSUCCESSFUL OUTCOME MBMSSessionUpdateFailure - PROCEDURE CODE id-mBMSsessionUpdate - CRITICALITY reject -} - + INITIATING MESSAGE MBMSSessionUpdateRequest + SUCCESSFUL OUTCOME MBMSSessionUpdateResponse + UNSUCCESSFUL OUTCOME MBMSSessionUpdateFailure + PROCEDURE CODE id-mBMSsessionUpdate + CRITICALITY reject +} errorIndication M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE ErrorIndication - PROCEDURE CODE id-errorIndication - CRITICALITY ignore + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-errorIndication + CRITICALITY ignore } - reset M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE Reset - SUCCESSFUL OUTCOME ResetAcknowledge - PROCEDURE CODE id-Reset - CRITICALITY reject + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-Reset + CRITICALITY reject } - -privateMessage M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE PrivateMessage - PROCEDURE CODE id-privateMessage - CRITICALITY ignore +privateMessage M3AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore } - mCEConfigurationUpdate M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE MCEConfigurationUpdate - SUCCESSFUL OUTCOME MCEConfigurationUpdateAcknowledge - UNSUCCESSFUL OUTCOME MCEConfigurationUpdateFailure - PROCEDURE CODE id-mCEConfigurationUpdate - CRITICALITY reject + INITIATING MESSAGE MCEConfigurationUpdate + SUCCESSFUL OUTCOME MCEConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME MCEConfigurationUpdateFailure + PROCEDURE CODE id-mCEConfigurationUpdate + CRITICALITY reject } - - m3Setup M3AP-ELEMENTARY-PROCEDURE ::= { - INITIATING MESSAGE M3SetupRequest - SUCCESSFUL OUTCOME M3SetupResponse - UNSUCCESSFUL OUTCOME M3SetupFailure - PROCEDURE CODE id-m3Setup - CRITICALITY reject + INITIATING MESSAGE M3SetupRequest + SUCCESSFUL OUTCOME M3SetupResponse + UNSUCCESSFUL OUTCOME M3SetupFailure + PROCEDURE CODE id-m3Setup + CRITICALITY reject } - -END +END -- ************************************************************** -- -- PDU definitions for M3AP. -- -- ************************************************************** - M3AP-PDU-Contents { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-PDU-Contents (1) } DEFINITIONS AUTOMATIC TAGS ::= - BEGIN - -- ************************************************************** -- -- IE parameter types from other modules. -- -- ************************************************************** - IMPORTS - - Absolute-Time-ofMBMS-Data, - Cause, - CriticalityDiagnostics, - Global-MCE-ID, - MBMS-E-RAB-QoS-Parameters, - MBMS-Service-associatedLogicalM3-ConnectionItem, - MBMS-Service-Area, - MBMSServiceArea1, - MBMS-Session-Duration, - MBMS-Session-ID, - MCE-MBMS-M3AP-ID, - MCEname, - MinimumTimeToMBMSDataTransfer, - MME-MBMS-M3AP-ID, - TimeToWait, - TMGI, - TNL-Information, - Reestablishment, - MBMS-Cell-List - + Absolute-Time-ofMBMS-Data, + Cause, + CriticalityDiagnostics, + Global-MCE-ID, + MBMS-E-RAB-QoS-Parameters, + MBMS-Service-associatedLogicalM3-ConnectionItem, + MBMS-Service-Area, + MBMSServiceArea1, + MBMS-Session-Duration, + MBMS-Session-ID, + MCE-MBMS-M3AP-ID, + MCEname, + MinimumTimeToMBMSDataTransfer, + MME-MBMS-M3AP-ID, + TimeToWait, + TMGI, + TNL-Information, + Reestablishment, + MBMS-Cell-List FROM M3AP-IEs - - PrivateIE-Container{}, - ProtocolExtensionContainer{}, - ProtocolIE-Container{}, - ProtocolIE-ContainerList{}, - ProtocolIE-ContainerPair{}, - ProtocolIE-ContainerPairList{}, - ProtocolIE-Single-Container{}, - M3AP-PRIVATE-IES, - M3AP-PROTOCOL-EXTENSION, - M3AP-PROTOCOL-IES, - M3AP-PROTOCOL-IES-PAIR + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerList{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-ContainerPairList{}, + ProtocolIE-Single-Container{}, + M3AP-PRIVATE-IES, + M3AP-PROTOCOL-EXTENSION, + M3AP-PROTOCOL-IES, + M3AP-PROTOCOL-IES-PAIR FROM M3AP-Containers - - id-AllocationAndRetentionPriority, - id-MCE-MBMS-M3AP-ID, - id-MME-MBMS-M3AP-ID, - id-TMGI, - id-MBMS-Session-ID, - id-MBMS-E-RAB-QoS-Parameters, - id-MBMS-Session-Duration, - id-MBMS-Service-Area, - id-TNL-Information, - id-Alternative-TNL-Information, - id-CriticalityDiagnostics, - id-Cause, - id-MBMS-Service-Area-List, - id-MBMS-Service-Area-List-Item, - id-TimeToWait, - id-ResetType, - id-MBMS-Service-associatedLogicalM3-ConnectionItem, - id-MBMS-Service-associatedLogicalM3-ConnectionListResAck, - id-MBMSServiceAreaList, - id-MinimumTimeToMBMSDataTransfer, - id-Time-ofMBMS-DataStop, - id-Time-ofMBMS-DataTransfer, - id-Global-MCE-ID, - id-MCEname, - id-Reestablishment, - id-MBMS-Cell-List, - maxnoofMBMSServiceAreaIdentitiesPerMCE, - maxnooferrors, - maxNrOfIndividualM3ConnectionsToReset - + id-AllocationAndRetentionPriority, + id-MCE-MBMS-M3AP-ID, + id-MME-MBMS-M3AP-ID, + id-TMGI, + id-MBMS-Session-ID, + id-MBMS-E-RAB-QoS-Parameters, + id-MBMS-Session-Duration, + id-MBMS-Service-Area, + id-TNL-Information, +id-Alternative-TNL-Information, + id-CriticalityDiagnostics, + id-Cause, + id-MBMS-Service-Area-List, + id-MBMS-Service-Area-List-Item, + id-TimeToWait, + id-ResetType, + id-MBMS-Service-associatedLogicalM3-ConnectionItem, + id-MBMS-Service-associatedLogicalM3-ConnectionListResAck, + id-MBMSServiceAreaList, + id-MinimumTimeToMBMSDataTransfer, + id-Time-ofMBMS-DataStop, + id-Time-ofMBMS-DataTransfer, + id-Global-MCE-ID, + id-MCEname, + id-Reestablishment, + id-MBMS-Cell-List, + maxnoofMBMSServiceAreaIdentitiesPerMCE, + maxnooferrors, + maxNrOfIndividualM3ConnectionsToReset FROM M3AP-Constants; - -- ************************************************************** -- -- MBMS SESSION START REQUEST -- -- ************************************************************** - MBMSSessionStartRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{MBMSSessionStartRequest-IEs}}, - ... + protocolIEs ProtocolIE-Container {{MBMSSessionStartRequest-IEs}}, + ... } - MBMSSessionStartRequest-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| - { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| - { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| - { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| - { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| - { ID id-MBMS-Service-Area CRITICALITY reject TYPE MBMS-Service-Area PRESENCE mandatory}| - { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| - { ID id-TNL-Information CRITICALITY reject TYPE TNL-Information PRESENCE mandatory}| - { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| - { ID id-Reestablishment CRITICALITY ignore TYPE Reestablishment PRESENCE optional}| - { ID id-Alternative-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| - { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| + { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| + { ID id-MBMS-Service-Area CRITICALITY reject TYPE MBMS-Service-Area PRESENCE mandatory}| + { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY reject TYPE TNL-Information PRESENCE mandatory}| + { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| + { ID id-Reestablishment CRITICALITY ignore TYPE Reestablishment PRESENCE optional}| + { ID id-Alternative-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, + ... } - -- ************************************************************** -- -- MBMS SESSION START RESPONSE --- +-- -- ************************************************************** - MBMSSessionStartResponse ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{ MBMSSessionStartResponse-IEs}}, - ... + protocolIEs ProtocolIE-Container {{ MBMSSessionStartResponse-IEs}}, + ... } - MBMSSessionStartResponse-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... } - - -- ************************************************************** -- -- MBMS SESSION START FAILURE -- -- ************************************************************** - MBMSSessionStartFailure ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{ MBMSSessionStartFailure-IEs}}, - ... + protocolIEs ProtocolIE-Container {{ MBMSSessionStartFailure-IEs}}, + ... } - MBMSSessionStartFailure-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... } - - -- ************************************************************** -- -- MBMS SESSION STOP REQUEST -- -- ************************************************************** - MBMSSessionStopRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{MBMSSessionStopRequest-IEs}}, - ... + protocolIEs ProtocolIE-Container {{MBMSSessionStopRequest-IEs}}, + ... } - MBMSSessionStopRequest-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| - { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| - { ID id-Time-ofMBMS-DataStop CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-Time-ofMBMS-DataStop CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}, + ... } - -- ************************************************************** --- +-- -- MBMS SESSION STOP RESPONSE -- -- ************************************************************** - MBMSSessionStopResponse ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{ MBMSSessionStopResponse-IEs}}, - ... + protocolIEs ProtocolIE-Container {{ MBMSSessionStopResponse-IEs}}, + ... } - MBMSSessionStopResponse-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... } - -- ************************************************************** -- -- MBMS SESSION UPDATE REQUEST -- -- ************************************************************** - MBMSSessionUpdateRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{MBMSSessionUpdateRequest-IEs}}, - ... + protocolIEs ProtocolIE-Container {{MBMSSessionUpdateRequest-IEs}}, + ... } - MBMSSessionUpdateRequest-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| - { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| - { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| - { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| - { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| - { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| - { ID id-MBMS-Service-Area CRITICALITY ignore TYPE MBMS-Service-Area PRESENCE optional}| - { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| - { ID id-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| - { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| - { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY reject TYPE MME-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-MCE-MBMS-M3AP-ID CRITICALITY reject TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory}| + { ID id-TMGI CRITICALITY reject TYPE TMGI PRESENCE mandatory}| + { ID id-MBMS-Session-ID CRITICALITY ignore TYPE MBMS-Session-ID PRESENCE optional}| + { ID id-MBMS-E-RAB-QoS-Parameters CRITICALITY reject TYPE MBMS-E-RAB-QoS-Parameters PRESENCE mandatory}| + { ID id-MBMS-Session-Duration CRITICALITY reject TYPE MBMS-Session-Duration PRESENCE mandatory}| + { ID id-MBMS-Service-Area CRITICALITY ignore TYPE MBMS-Service-Area PRESENCE optional}| + { ID id-MinimumTimeToMBMSDataTransfer CRITICALITY reject TYPE MinimumTimeToMBMSDataTransfer PRESENCE mandatory}| + { ID id-TNL-Information CRITICALITY ignore TYPE TNL-Information PRESENCE optional}| + { ID id-Time-ofMBMS-DataTransfer CRITICALITY ignore TYPE Absolute-Time-ofMBMS-Data PRESENCE optional}| + { ID id-MBMS-Cell-List CRITICALITY reject TYPE MBMS-Cell-List PRESENCE optional}, + ... } - -- ************************************************************** -- -- MBMS SESSION UPDATE RESPONSE -- -- ************************************************************** - MBMSSessionUpdateResponse ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateResponse-IEs}}, - ... + protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateResponse-IEs}}, + ... } - MBMSSessionUpdateResponse-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... } - -- ************************************************************** -- -- MBMS SESSION UPDATE FAILURE -- -- ************************************************************** - MBMSSessionUpdateFailure ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateFailure-IEs}}, - ... + protocolIEs ProtocolIE-Container {{ MBMSSessionUpdateFailure-IEs}}, + ... } - MBMSSessionUpdateFailure-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE mandatory } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... } - -- ************************************************************** -- -- ERROR INDICATION -- -- ************************************************************** - ErrorIndication ::= SEQUENCE { - protocolIEs ProtocolIE-Container {{ErrorIndication-IEs}}, - ... + protocolIEs ProtocolIE-Container {{ErrorIndication-IEs}}, + ... } - ErrorIndication-IEs M3AP-PROTOCOL-IES ::= { - { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE optional } | - { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE optional } | - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } | - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , - ... + { ID id-MME-MBMS-M3AP-ID CRITICALITY ignore TYPE MME-MBMS-M3AP-ID PRESENCE optional } | + { ID id-MCE-MBMS-M3AP-ID CRITICALITY ignore TYPE MCE-MBMS-M3AP-ID PRESENCE optional } | + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional } | + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional } , + ... } - - -- ************************************************************** -- -- Reset -- -- ************************************************************** - Reset ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ResetIEs} }, - ... + protocolIEs ProtocolIE-Container { {ResetIEs} }, + ... } - ResetIEs M3AP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| - { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, - ... + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... } - ResetType ::= CHOICE { - m3-Interface ResetAll, - partOfM3-Interface MBMS-Service-associatedLogicalM3-ConnectionListRes, - ... + m3-Interface ResetAll, + partOfM3-Interface MBMS-Service-associatedLogicalM3-ConnectionListRes, + ... } - - - ResetAll ::= ENUMERATED { - reset-all, - ... + reset-all, + ... } - -MBMS-Service-associatedLogicalM3-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM3-ConnectionItemRes } } - -MBMS-Service-associatedLogicalM3-ConnectionItemRes M3AP-PROTOCOL-IES ::= { - { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY reject TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE mandatory }, - ... +MBMS-Service-associatedLogicalM3-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { +{ MBMS-Service-associatedLogicalM3-ConnectionItemRes } } +MBMS-Service-associatedLogicalM3-ConnectionItemRes M3AP-PROTOCOL-IES ::= { + { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY reject TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE +mandatory }, + ... } - - -- ************************************************************** -- -- Reset Acknowledge -- -- ************************************************************** - ResetAcknowledge ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, - ... + protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, + ... } - ResetAcknowledgeIEs M3AP-PROTOCOL-IES ::= { - { ID id-MBMS-Service-associatedLogicalM3-ConnectionListResAck CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionListResAck PRESENCE optional }| - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... + { ID id-MBMS-Service-associatedLogicalM3-ConnectionListResAck CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionListResAck PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... } - -MBMS-Service-associatedLogicalM3-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container { { MBMS-Service-associatedLogicalM3-ConnectionItemResAck } } - -MBMS-Service-associatedLogicalM3-ConnectionItemResAck M3AP-PROTOCOL-IES ::= { - { ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE mandatory }, - ... +MBMS-Service-associatedLogicalM3-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxNrOfIndividualM3ConnectionsToReset)) OF ProtocolIE-Single-Container +{ { MBMS-Service-associatedLogicalM3-ConnectionItemResAck } } +MBMS-Service-associatedLogicalM3-ConnectionItemResAck M3AP-PROTOCOL-IES ::= { +{ ID id-MBMS-Service-associatedLogicalM3-ConnectionItem CRITICALITY ignore TYPE MBMS-Service-associatedLogicalM3-ConnectionItem PRESENCE +mandatory }, + ... } - -- ************************************************************** -- -- PRIVATE MESSAGE -- -- ************************************************************** - PrivateMessage ::= SEQUENCE { - privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, - ... + privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, + ... } - PrivateMessage-IEs M3AP-PRIVATE-IES ::= { - ... + ... } - - -- ************************************************************** -- -- M3 SETUP ELEMENTARY PROCEDURE -- -- ************************************************************** - -- ************************************************************** -- -- M3 Setup Request -- -- ************************************************************** - M3SetupRequest ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {M3SetupRequestIEs} }, - ... + protocolIEs ProtocolIE-Container { {M3SetupRequestIEs} }, + ... } - M3SetupRequestIEs M3AP-PROTOCOL-IES ::= { - { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE mandatory}| - { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| - { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE optional}, - ... + { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE mandatory}| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| + { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE mandatory}, + ... } - - MBMSServiceAreaListItem ::= SEQUENCE (SIZE(1..maxnoofMBMSServiceAreaIdentitiesPerMCE)) OF MBMSServiceArea1 - - -- ************************************************************** -- -- M3 Setup Response -- --- ************************************************************** - +-- ************************************************************** M3SetupResponse ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {M3SetupResponseIEs} }, - ... + protocolIEs ProtocolIE-Container { {M3SetupResponseIEs} }, + ... } - - M3SetupResponseIEs M3AP-PROTOCOL-IES ::= { - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, - ... + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... } - -- ************************************************************** -- -- M3 Setup Failure -- -- ************************************************************** - M3SetupFailure ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {M3SetupFailureIEs} }, - ... + protocolIEs ProtocolIE-Container { {M3SetupFailureIEs} }, + ... } - M3SetupFailureIEs M3AP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| - { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, - ... + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... } - -- ************************************************************** -- -- MCE CONFIGURATION UPDATE ELEMENTARY PROCEDURE -- -- ************************************************************** - -- ************************************************************** -- --- MCE Configuration Update +-- MCE Configuration Update -- -- ************************************************************** - MCEConfigurationUpdate ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateIEs} }, - ... + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateIEs} }, + ... } - MCEConfigurationUpdateIEs M3AP-PROTOCOL-IES ::= { - { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE optional}| - { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| - { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE optional}, - ... + { ID id-Global-MCE-ID CRITICALITY reject TYPE Global-MCE-ID PRESENCE optional}| + { ID id-MCEname CRITICALITY ignore TYPE MCEname PRESENCE optional}| + { ID id-MBMSServiceAreaList CRITICALITY reject TYPE MBMSServiceAreaListItem PRESENCE optional}, + ... } - -- ************************************************************** -- -- MCE Configuration Update Acknowledge -- -- ************************************************************** - MCEConfigurationUpdateAcknowledge ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateAcknowledgeIEs} }, - ... + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateAcknowledgeIEs} }, + ... } - - MCEConfigurationUpdateAcknowledgeIEs M3AP-PROTOCOL-IES ::= { - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, - ... + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... } - -- ************************************************************** -- -- MCE Configuration Update Failure -- -- ************************************************************** - MCEConfigurationUpdateFailure ::= SEQUENCE { - protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateFailureIEs} }, - ... + protocolIEs ProtocolIE-Container { {MCEConfigurationUpdateFailureIEs} }, + ... } - MCEConfigurationUpdateFailureIEs M3AP-PROTOCOL-IES ::= { - { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| - { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| - { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, - ... + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory}| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional}, + ... } - END -- ************************************************************** @@ -683,634 +570,496 @@ END -- Information Element Definitions -- -- ************************************************************** - M3AP-IEs { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-IEs (2) } - -DEFINITIONS AUTOMATIC TAGS ::= - -BEGIN - +DEFINITIONS AUTOMATIC TAGS ::= +BEGIN IMPORTS - id-AllocationAndRetentionPriority, - maxnooferrors, - maxnoofCellsforMBMS - + id-AllocationAndRetentionPriority, + maxnooferrors, + maxnoofCellsforMBMS FROM M3AP-Constants - - Criticality, - ProcedureCode, - ProtocolIE-ID, - TriggeringMessage + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage FROM M3AP-CommonDataTypes - - ProtocolExtensionContainer{}, - ProtocolIE-Single-Container{}, - M3AP-PROTOCOL-EXTENSION, - M3AP-PROTOCOL-IES + ProtocolExtensionContainer{}, + ProtocolIE-Single-Container{}, + M3AP-PROTOCOL-EXTENSION, + M3AP-PROTOCOL-IES FROM M3AP-Containers; - -- A - -Absolute-Time-ofMBMS-Data ::= BIT STRING (SIZE (64)) - +Absolute-Time-ofMBMS-Data ::= BIT STRING (SIZE (64)) AllocationAndRetentionPriority ::= SEQUENCE { - priorityLevel PriorityLevel, - pre-emptionCapability Pre-emptionCapability, - pre-emptionVulnerability Pre-emptionVulnerability, - iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL } - AllocationAndRetentionPriority-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } -- B - -BitRate ::= INTEGER (0..10000000000) - +BitRate ::= INTEGER (0..10000000000) -- C - Cause ::= CHOICE { - radioNetwork CauseRadioNetwork, - transport CauseTransport, - nAS CauseNAS, - protocol CauseProtocol, - misc CauseMisc, - ... + radioNetwork CauseRadioNetwork, + transport CauseTransport, + nAS CauseNAS, + protocol CauseProtocol, + misc CauseMisc, + ... } - CauseMisc ::= ENUMERATED { - control-processing-overload, - not-enough-user-plane-processing-resources, - hardware-failure, - om-intervention, - unspecified, - ... + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, +unspecified, + ... } - CauseNAS ::= ENUMERATED { - unspecified, - ... + unspecified, + ... } - CauseProtocol ::= ENUMERATED { - transfer-syntax-error, - abstract-syntax-error-reject, - abstract-syntax-error-ignore-and-notify, - message-not-compatible-with-receiver-state, - semantic-error, - abstract-syntax-error-falsely-constructed-message, - unspecified, - ... + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... } - CauseRadioNetwork ::= ENUMERATED { - unknown-or-already-allocated-MME-MBMS-M3AP-ID, - unknown-or-already-allocated-MCE-MBMS-M3AP-ID, - unknown-or-inconsistent-pair-of-MBMS-M3AP-IDs, - radio-resources-not-available, - invalid-QoS-combination, - interaction-with-other-procedure, - not-supported-QCI-value, - unspecified, - ..., - uninvolved-MCE - + unknown-or-already-allocated-MME-MBMS-M3AP-ID, + unknown-or-already-allocated-MCE-MBMS-M3AP-ID, + unknown-or-inconsistent-pair-of-MBMS-M3AP-IDs, + radio-resources-not-available, + invalid-QoS-combination, + interaction-with-other-procedure, + not-supported-QCI-value, + unspecified, + ..., + uninvolved-MCE } - CauseTransport ::= ENUMERATED { - transport-resource-unavailable, - unspecified, - ... + transport-resource-unavailable, + unspecified, + ... } - CriticalityDiagnostics ::= SEQUENCE { - procedureCode ProcedureCode OPTIONAL, - triggeringMessage TriggeringMessage OPTIONAL, - procedureCriticality Criticality OPTIONAL, - iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, - ... + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-ExtIEs} } OPTIONAL, + ... } - - CriticalityDiagnostics-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... -} - + ... +} CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..maxnooferrors)) OF - SEQUENCE { - iECriticality Criticality, - iE-ID ProtocolIE-ID, - typeOfError TypeOfError, - iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, - ... + SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer { {CriticalityDiagnostics-IE-List-ExtIEs} } OPTIONAL, + ... } - CriticalityDiagnostics-IE-List-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - - -- D -- E - ECGI ::= SEQUENCE { - pLMN-Identity PLMN-Identity, - eUTRANcellIdentifier EUTRANCellIdentifier, - iE-Extensions ProtocolExtensionContainer { {ECGI-ExtIEs} } OPTIONAL, - ... + pLMN-Identity PLMN-Identity, + eUTRANcellIdentifier EUTRANCellIdentifier, + iE-Extensions ProtocolExtensionContainer { {ECGI-ExtIEs} } OPTIONAL, + ... } - ECGI-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - EUTRANCellIdentifier ::= BIT STRING (SIZE (28)) - ExtendedMCE-ID ::= OCTET STRING (SIZE(1)) - -- F -- G - Global-MCE-ID ::= SEQUENCE { - pLMN-Identity PLMN-Identity, - mCE-ID MCE-ID, - extendedMCE-ID ExtendedMCE-ID OPTIONAL, - iE-Extensions ProtocolExtensionContainer { {GlobalMCE-ID-ExtIEs} } OPTIONAL, - ... + pLMN-Identity PLMN-Identity, + mCE-ID MCE-ID, + extendedMCE-ID ExtendedMCE-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {GlobalMCE-ID-ExtIEs} } OPTIONAL, + ... } - GlobalMCE-ID-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - GBR-QosInformation ::= SEQUENCE { - mBMS-E-RAB-MaximumBitrateDL BitRate, - mBMS-E-RAB-GuaranteedBitrateDL BitRate, - iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, - ... -} - + mBMS-E-RAB-MaximumBitrateDL BitRate, + mBMS-E-RAB-GuaranteedBitrateDL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} GBR-QosInformation-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - -GTP-TEID ::= OCTET STRING (SIZE (4)) - +GTP-TEID ::= OCTET STRING (SIZE (4)) -- H -- I - -IPAddress ::= OCTET STRING (SIZE(4..16, ...)) - +IPAddress ::= OCTET STRING (SIZE(4..16, ...)) -- J -- K -- L -- M - MBMS-Cell-List ::= SEQUENCE (SIZE(1.. maxnoofCellsforMBMS)) OF ECGI - MBMS-E-RAB-QoS-Parameters ::= SEQUENCE { - qCI QCI, - gbrQosInformation GBR-QosInformation OPTIONAL, - iE-Extensions ProtocolExtensionContainer { { MBMS-E-RAB-QoS-Parameters-ExtIEs} } OPTIONAL, - ... + qCI QCI, + gbrQosInformation GBR-QosInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-E-RAB-QoS-Parameters-ExtIEs} } OPTIONAL, + ... } - MBMS-E-RAB-QoS-Parameters-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { -- Extension for Release 10 ARP support -- - {ID id-AllocationAndRetentionPriority CRITICALITY ignore EXTENSION AllocationAndRetentionPriority PRESENCE mandatory}, - ... + {ID id-AllocationAndRetentionPriority CRITICALITY ignore EXTENSION AllocationAndRetentionPriority PRESENCE mandatory}, + ... } - MBMS-Service-associatedLogicalM3-ConnectionItem ::= SEQUENCE { - mME-MBMS-M3AP-ID MME-MBMS-M3AP-ID OPTIONAL, - mCE-MBMS-M3AP-ID MCE-MBMS-M3AP-ID OPTIONAL, - iE-Extensions ProtocolExtensionContainer { { MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs} } OPTIONAL, - ... + mME-MBMS-M3AP-ID MME-MBMS-M3AP-ID OPTIONAL, + mCE-MBMS-M3AP-ID MCE-MBMS-M3AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs} } OPTIONAL, + ... } - - MBMS-Service-associatedLogicalM3-ConnectionItemExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - MBMSServiceArea1 ::= OCTET STRING (SIZE (2)) - -MBMS-Service-Area ::= OCTET STRING - - +MBMS-Service-Area ::= OCTET STRING MBMS-Session-Duration ::= OCTET STRING (SIZE (3)) - MBMS-Session-ID ::= OCTET STRING (SIZE (1)) - - -MCE-MBMS-M3AP-ID ::= INTEGER (0..65535) - +MCE-MBMS-M3AP-ID ::= INTEGER (0..65535) MCE-ID ::= OCTET STRING (SIZE(2)) - MCEname ::= PrintableString (SIZE (1..150,...)) - -MinimumTimeToMBMSDataTransfer ::= OCTET STRING (SIZE (1)) - -MME-MBMS-M3AP-ID ::= INTEGER (0..65535) - +MinimumTimeToMBMSDataTransfer ::= OCTET STRING (SIZE (1)) +MME-MBMS-M3AP-ID ::= INTEGER (0..65535) -- N -- O -- P - Pre-emptionCapability ::= ENUMERATED { - shall-not-trigger-pre-emption, - may-trigger-pre-emption + shall-not-trigger-pre-emption, + may-trigger-pre-emption } - Pre-emptionVulnerability ::= ENUMERATED { - not-pre-emptable, - pre-emptable + not-pre-emptable, + pre-emptable } - -PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) - +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) PLMN-Identity ::= OCTET STRING (SIZE(3)) - -- Q - QCI ::= INTEGER (0..255) - -- R - Reestablishment ::= ENUMERATED {true, ...} - -- S -- T - TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} - TMGI ::= SEQUENCE { - pLMNidentity PLMN-Identity, - serviceID OCTET STRING (SIZE (3)), - iE-Extensions ProtocolExtensionContainer { {TMGI-ExtIEs} } OPTIONAL + pLMNidentity PLMN-Identity, + serviceID OCTET STRING (SIZE (3)), + iE-Extensions ProtocolExtensionContainer { {TMGI-ExtIEs} } OPTIONAL } - TMGI-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - - TNL-Information ::= SEQUENCE { - iPMCAddress IPAddress, - iPSourceAddress IPAddress, - gTP-DLTEID GTP-TEID, - iE-Extensions ProtocolExtensionContainer { {TNL-Information-ExtIEs} } OPTIONAL, - ... + iPMCAddress IPAddress, + iPSourceAddress IPAddress, gTP-DLTEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { {TNL-Information-ExtIEs} } OPTIONAL, + ... } - TNL-Information-ExtIEs M3AP-PROTOCOL-EXTENSION ::= { - ... + ... } - TypeOfError ::= ENUMERATED { - not-understood, - missing, - ... + not-understood, + missing, + ... } - - -- U -- V -- W -- X -- Y -- Z - -END +END -- ************************************************************** -- -- Common definitions -- -- ************************************************************** - M3AP-CommonDataTypes { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) -eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-CommonDataTypes (3) } - -DEFINITIONS AUTOMATIC TAGS ::= - +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-CommonDataTypes (3) } +DEFINITIONS AUTOMATIC TAGS ::= BEGIN - -- ************************************************************** -- -- Extension constants -- -- ************************************************************** - -maxPrivateIEs INTEGER ::= 65535 -maxProtocolExtensions INTEGER ::= 65535 -maxProtocolIEs INTEGER ::= 65535 - --- ************************************************************** +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 +-- ************************************************************** -- -- Common Data Types -- -- ************************************************************** - -Criticality ::= ENUMERATED { reject, ignore, notify } - -Presence ::= ENUMERATED { optional, conditional, mandatory } - -PrivateIE-ID ::= CHOICE { - local INTEGER (0.. maxPrivateIEs), - global OBJECT IDENTIFIER +Criticality ::= ENUMERATED { reject, ignore, notify } +Presence ::= ENUMERATED { optional, conditional, mandatory } +PrivateIE-ID ::= CHOICE { + local INTEGER (0.. maxPrivateIEs), + global OBJECT IDENTIFIER } - -ProcedureCode ::= INTEGER (0..255) - - -ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs) - - -TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome} - -END +ProcedureCode ::= INTEGER (0..255) +ProtocolIE-ID ::= INTEGER (0..maxProtocolIEs) +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessful-outcome} +END -- ************************************************************** -- -- Constant definitions -- -- ************************************************************** - M3AP-Constants { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Constants (4) } - -DEFINITIONS AUTOMATIC TAGS ::= - +DEFINITIONS AUTOMATIC TAGS ::= BEGIN - IMPORTS - ProcedureCode, - ProtocolIE-ID + ProcedureCode, + ProtocolIE-ID FROM M3AP-CommonDataTypes; - -- ************************************************************** -- -- Elementary Procedures -- -- ************************************************************** - -id-mBMSsessionStart ProcedureCode ::= 0 -id-mBMSsessionStop ProcedureCode ::= 1 -id-errorIndication ProcedureCode ::= 2 -id-privateMessage ProcedureCode ::= 3 -id-Reset ProcedureCode ::= 4 -id-mBMSsessionUpdate ProcedureCode ::= 5 -id-mCEConfigurationUpdate ProcedureCode ::= 6 -id-m3Setup ProcedureCode ::= 7 - - - +id-mBMSsessionStart ProcedureCode ::= 0 +id-mBMSsessionStop ProcedureCode ::= 1 +id-errorIndication ProcedureCode ::= 2 +id-privateMessage ProcedureCode ::= 3 +id-Reset ProcedureCode ::= 4 +id-mBMSsessionUpdate ProcedureCode ::= 5 +id-mCEConfigurationUpdate ProcedureCode ::= 6 +id-m3Setup ProcedureCode ::= 7 -- ************************************************************** -- -- Lists -- -- ************************************************************** - -maxnoofMBMSServiceAreaIdentitiesPerMCE INTEGER ::= 65536 -maxnooferrors INTEGER ::= 256 -maxNrOfIndividualM3ConnectionsToReset INTEGER ::= 256 -maxnoofCellsforMBMS INTEGER ::= 4096 - +maxnoofMBMSServiceAreaIdentitiesPerMCE INTEGER ::= 65536 +maxnooferrors INTEGER ::= 256 +maxNrOfIndividualM3ConnectionsToReset INTEGER ::= 256 +maxnoofCellsforMBMS INTEGER ::= 4096 -- ************************************************************** -- -- IEs -- -- ************************************************************** - -id-MME-MBMS-M3AP-ID ProtocolIE-ID ::= 0 -id-MCE-MBMS-M3AP-ID ProtocolIE-ID ::= 1 -id-TMGI ProtocolIE-ID ::= 2 -id-MBMS-Session-ID ProtocolIE-ID ::= 3 -id-MBMS-E-RAB-QoS-Parameters ProtocolIE-ID ::= 4 -id-MBMS-Session-Duration ProtocolIE-ID ::= 5 -id-MBMS-Service-Area ProtocolIE-ID ::= 6 -id-TNL-Information ProtocolIE-ID ::= 7 -id-CriticalityDiagnostics ProtocolIE-ID ::= 8 -id-Cause ProtocolIE-ID ::= 9 -id-MBMS-Service-Area-List ProtocolIE-ID ::= 10 -id-MBMS-Service-Area-List-Item ProtocolIE-ID ::= 11 -id-TimeToWait ProtocolIE-ID ::= 12 -id-ResetType ProtocolIE-ID ::= 13 -id-MBMS-Service-associatedLogicalM3-ConnectionItem ProtocolIE-ID ::= 14 -id-MBMS-Service-associatedLogicalM3-ConnectionListResAck ProtocolIE-ID ::= 15 -id-MinimumTimeToMBMSDataTransfer ProtocolIE-ID ::= 16 -id-AllocationAndRetentionPriority ProtocolIE-ID ::= 17 -id-Global-MCE-ID ProtocolIE-ID ::= 18 -id-MCEname ProtocolIE-ID ::= 19 -id-MBMSServiceAreaList ProtocolIE-ID ::= 20 -id-Time-ofMBMS-DataTransfer ProtocolIE-ID ::= 21 -id-Time-ofMBMS-DataStop ProtocolIE-ID ::= 22 -id-Reestablishment ProtocolIE-ID ::= 23 -id-Alternative-TNL-Information ProtocolIE-ID ::= 24 -id-MBMS-Cell-List ProtocolIE-ID ::= 25 -END - - - +id-MME-MBMS-M3AP-ID ProtocolIE-ID ::= 0 +id-MCE-MBMS-M3AP-ID ProtocolIE-ID ::= 1 +id-TMGI ProtocolIE-ID ::= 2 +id-MBMS-Session-ID ProtocolIE-ID ::= 3 +id-MBMS-E-RAB-QoS-Parameters ProtocolIE-ID ::= 4 +id-MBMS-Session-Duration ProtocolIE-ID ::= 5 +id-MBMS-Service-Area ProtocolIE-ID ::= 6 +id-TNL-Information ProtocolIE-ID ::= 7 +id-CriticalityDiagnostics ProtocolIE-ID ::= 8 +id-Cause ProtocolIE-ID ::= 9 +id-MBMS-Service-Area-List ProtocolIE-ID ::= 10 +id-MBMS-Service-Area-List-Item ProtocolIE-ID ::= 11 +id-TimeToWait ProtocolIE-ID ::= 12 +id-ResetType ProtocolIE-ID ::= 13 +id-MBMS-Service-associatedLogicalM3-ConnectionItem ProtocolIE-ID ::= 14 +id-MBMS-Service-associatedLogicalM3-ConnectionListResAck ProtocolIE-ID ::= 15 +id-MinimumTimeToMBMSDataTransfer ProtocolIE-ID ::= 16 +id-AllocationAndRetentionPriority ProtocolIE-ID ::= 17 +id-Global-MCE-ID ProtocolIE-ID ::= 18 +id-MCEname ProtocolIE-ID ::= 19 +id-MBMSServiceAreaList ProtocolIE-ID ::= 20 +id-Time-ofMBMS-DataTransfer ProtocolIE-ID ::= 21 +id-Time-ofMBMS-DataStop ProtocolIE-ID ::= 22 +id-Reestablishment ProtocolIE-ID ::= 23 +id-Alternative-TNL-Information ProtocolIE-ID ::= 24 +id-MBMS-Cell-List ProtocolIE-ID ::= 25 +END -- ************************************************************** -- -- Container definitions -- -- ************************************************************** - M3AP-Containers { -itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) -eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Containers (5) } - -DEFINITIONS AUTOMATIC TAGS ::= - +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +eps-Access (21) modules (3) m3ap (5) version1 (1) m3ap-Containers (5) } +DEFINITIONS AUTOMATIC TAGS ::= BEGIN - -- ************************************************************** -- -- IE parameter types from other modules. -- -- ************************************************************** - IMPORTS - maxPrivateIEs, - maxProtocolExtensions, - maxProtocolIEs, - Criticality, - Presence, - PrivateIE-ID, - ProtocolIE-ID + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs, + Criticality, + Presence, + PrivateIE-ID, + ProtocolIE-ID FROM M3AP-CommonDataTypes; - -- ************************************************************** -- -- Class Definition for Protocol IEs -- -- ************************************************************** - M3AP-PROTOCOL-IES ::= CLASS { - &id ProtocolIE-ID UNIQUE, - &criticality Criticality, - &Value, - &presence Presence + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence } WITH SYNTAX { - ID &id - CRITICALITY &criticality - TYPE &Value - PRESENCE &presence -} - + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} -- ************************************************************** -- -- Class Definition for Protocol IEs -- -- ************************************************************** - M3AP-PROTOCOL-IES-PAIR ::= CLASS { - &id ProtocolIE-ID UNIQUE, - &firstCriticality Criticality, - &FirstValue, - &secondCriticality Criticality, - &SecondValue, - &presence Presence + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence } WITH SYNTAX { - ID &id - FIRST CRITICALITY &firstCriticality - FIRST TYPE &FirstValue - SECOND CRITICALITY &secondCriticality - SECOND TYPE &SecondValue - PRESENCE &presence + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence } - -- ************************************************************** -- -- Class Definition for Protocol Extensions -- -- ************************************************************** - M3AP-PROTOCOL-EXTENSION ::= CLASS { - &id ProtocolIE-ID UNIQUE, - &criticality Criticality, - &Extension, - &presence Presence + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence } WITH SYNTAX { - ID &id - CRITICALITY &criticality - EXTENSION &Extension - PRESENCE &presence + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence } - -- ************************************************************** -- -- Class Definition for Private IEs -- -- ************************************************************** - M3AP-PRIVATE-IES ::= CLASS { - &id PrivateIE-ID, - &criticality Criticality, - &Value, - &presence Presence -} -WITH SYNTAX { - ID &id - CRITICALITY &criticality - TYPE &Value - PRESENCE &presence -} + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} -- ************************************************************** -- -- Container for Protocol IEs -- -- ************************************************************** - -ProtocolIE-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= - SEQUENCE (SIZE (0..maxProtocolIEs)) OF - ProtocolIE-Field {{IEsSetParam}} - -ProtocolIE-Single-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= - ProtocolIE-Field {{IEsSetParam}} - +ProtocolIE-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} +ProtocolIE-Single-Container {M3AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} ProtocolIE-Field {M3AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { - id M3AP-PROTOCOL-IES.&id ({IEsSetParam}), - criticality M3AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), - value M3AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) + id M3AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality M3AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value M3AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) } - -- ************************************************************** -- -- Container for Protocol IE Pairs -- -- ************************************************************** - -ProtocolIE-ContainerPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= - SEQUENCE (SIZE (0..maxProtocolIEs)) OF - ProtocolIE-FieldPair {{IEsSetParam}} - +ProtocolIE-ContainerPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} ProtocolIE-FieldPair {M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { - id M3AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), - firstCriticality M3AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), - firstValue M3AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), - secondCriticality M3AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), - secondValue M3AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) + id M3AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality M3AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue M3AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality M3AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue M3AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) } - -- ************************************************************** -- -- Container Lists for Protocol IE Containers -- -- ************************************************************** - ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, M3AP-PROTOCOL-IES : IEsSetParam} ::= - SEQUENCE (SIZE (lowerBound..upperBound)) OF - ProtocolIE-Container {{IEsSetParam}} - + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-Container {{IEsSetParam}} ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, M3AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= - SEQUENCE (SIZE (lowerBound..upperBound)) OF - ProtocolIE-ContainerPair {{IEsSetParam}} - + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-ContainerPair {{IEsSetParam}} -- ************************************************************** -- -- Container for Protocol Extensions -- -- ************************************************************** - -ProtocolExtensionContainer {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= - SEQUENCE (SIZE (1..maxProtocolExtensions)) OF - ProtocolExtensionField {{ExtensionSetParam}} - +ProtocolExtensionContainer {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} ProtocolExtensionField {M3AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { - id M3AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), - criticality M3AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), - extensionValue M3AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) + id M3AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality M3AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue M3AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) } - -- ************************************************************** -- -- Container for Private IEs -- -- ************************************************************** - -PrivateIE-Container {M3AP-PRIVATE-IES : IEsSetParam} ::= - SEQUENCE (SIZE (1..maxPrivateIEs)) OF - PrivateIE-Field {{IEsSetParam}} - +PrivateIE-Container {M3AP-PRIVATE-IES : IEsSetParam} ::= + SEQUENCE (SIZE (1..maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} PrivateIE-Field {M3AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { - id M3AP-PRIVATE-IES.&id ({IEsSetParam}), - criticality M3AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), - value M3AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) + id M3AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality M3AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value M3AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) } - -END +END - From 69a7658c545a33189d573701babee2e87fb57240 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 16 Dec 2019 17:53:22 +0100 Subject: [PATCH 081/134] USRP device cleanup including record player as config option + some cppcheck warning/errors fixes --- cmake_targets/CMakeLists.txt | 1 + common/config/config_userapi.c | 5 +- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 25 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 53 +- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 9 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c | 2 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 14 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 2 +- openair2/COMMON/platform_types.h | 7 + openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 10 +- openair2/NETWORK_DRIVER/UE_IP/common.c | 6 +- openair2/UTIL/OTG/otg_rx_socket.c | 2 +- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 934 ++++++++---------- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h | 68 +- .../ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c | 73 ++ 17 files changed, 588 insertions(+), 627 deletions(-) create mode 100644 targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a0620d8345..e429b9e58f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -529,6 +529,7 @@ set (SHLIB_LOADER_SOURCES include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") set(HWLIB_USRP_SOURCE ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp + ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c ) add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} ) target_link_libraries(oai_usrpdevif uhd) diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 56c3c0951f..67fdc2c920 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -386,13 +386,12 @@ int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) { status=1; if (cfgoptions->numelt == 0 ) { - config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *)); config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); } else { - sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); - printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); + sprintf((char *)(cfgoptions->strptr), "%s",cfgoptions->defstrval); + printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)(cfgoptions->strptr)); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index dc7489ea51..b3a4948a2a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -32,7 +32,7 @@ #include "PHY/defs_gNB.h" -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch); NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index db0c601b25..2e8f2af5f5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -58,10 +58,9 @@ static uint64_t nb_error_decod =0; //extern double cpuf; -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) -{ - +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr) { int i,r; + NR_gNB_ULSCH_t *ulsch = *ulschptr; if (ulsch) { for (i=0; imax_ldpc_iterations + 1); + } t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; int16_t z [68*384]; @@ -338,11 +340,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, return (ulsch->max_ldpc_iterations + 1); } - if (!harq_process) { - printf("ulsch_decoding.c: NULL harq_process pointer\n"); - return (ulsch->max_ldpc_iterations + 1); - } - if (!frame_parms) { printf("ulsch_decoding.c: NULL frame_parms pointer\n"); return (ulsch->max_ldpc_iterations + 1); @@ -531,7 +528,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); @@ -620,7 +617,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int k=0;k>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -708,7 +705,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_ULSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 53d481919e..6a277cdc42 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -56,11 +56,11 @@ notifiedFIFO_elt_t *msgToPush; //extern double cpuf; -void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch) +void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr) { int i,r; - + NR_UE_DLSCH_t *dlsch=*dlschptr; if (dlsch) { for (i=0; iMdlharq; i++) { if (dlsch->harq_processes[i]) { @@ -175,7 +175,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint } printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag); - free_nr_ue_dlsch(dlsch); + free_nr_ue_dlsch(&dlsch); return(NULL); } @@ -232,6 +232,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_dec_params* p_decParams = &decParams; t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime =&procTime ; + + if (!harq_process) { + printf("dlsch_decoding.c: NULL harq_process pointer\n"); + return(dlsch->max_ldpc_iterations + 1); + } t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; int16_t z [68*384]; @@ -260,11 +265,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations + 1); } - if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations + 1); - } - if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); return(dlsch->max_ldpc_iterations + 1); @@ -498,7 +498,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); @@ -564,7 +564,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("\x1B[34m" "Segment %d CRC OK\n\033[0m",r); + printf("\x1B[34m" "Segment %u CRC OK\n\033[0m",r); //Temporary hack no_iteration_ldpc = dlsch->max_ldpc_iterations; ret = no_iteration_ldpc; @@ -594,7 +594,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int k=0;k>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -696,7 +696,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", @@ -766,6 +766,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime =&procTime ; int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); + if (!harq_process) { + printf("dlsch_decoding.c: NULL harq_process pointer\n"); + return(dlsch->max_ldpc_iterations); + } t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0]; uint8_t Nl=4; int16_t z [68*384]; @@ -796,10 +800,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations); } - if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations); - } + if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); @@ -1006,7 +1007,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #endif #if UE_TIMING_TRACE @@ -1065,7 +1066,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset); #endif #ifdef DEBUG_DLSCH_DECODING @@ -1075,7 +1076,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); for (int i=0;i<(3*8*Kr_bytes);i++) printf("%d : %d\n",i,harq_process->d[r][i]); printf("\n"); @@ -1153,7 +1154,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); + printf("Segment %u CRC OK\n",r); ret = 2; } else { @@ -1162,7 +1163,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } //if (!nb_total_decod%10000){ - printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); + printf("Error number of iteration LPDC %d %lu/%lu \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); //} //else @@ -1303,7 +1304,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", @@ -1391,7 +1392,7 @@ void *nr_dlsch_decoding_process(void *arg) //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r]; nb_symb_sch = harq_process->nb_symbols; - printf("dlsch decoding process frame %d slot %d segment %d r %d nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); + printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); /* @@ -1554,7 +1555,7 @@ void *nr_dlsch_decoding_process(void *arg) #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #endif #if UE_TIMING_TRACE @@ -1615,7 +1616,7 @@ void *nr_dlsch_decoding_process(void *arg) write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); printf("\n"); @@ -1684,7 +1685,7 @@ void *nr_dlsch_decoding_process(void *arg) // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); + printf("Segment %u CRC OK\n",r); ret = 2; } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 1e17f6dab0..a744bb1ef4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -71,7 +71,7 @@ uint16_t nr_pbch_extract(int **rxdataF, rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; rxF_ext = &rxdataF_ext[aarx][symbol*20*12]; #ifdef DEBUG_PBCH - printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift, + printf("extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",frame_parms->nushift, (rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol); int16_t *p = (int16_t *)rxF; @@ -425,7 +425,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int max_h=0; int symbol; //uint8_t pbch_a[64]; - uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32); +//FT ?? cppcheck doesn't like pbch_a allocation because of line 525..and i don't get what this variable is for.. +//uint8_t *pbch_a = malloc(sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); //uint32_t pbch_a_prime; int16_t *pbch_e_rx; uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output; @@ -438,7 +439,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, //uint8_t decoderListSize = 8, pathMetricAppr = 0; //time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; //time_stats_t path_metric,sorting,update_LLR; - memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); +// FT ?? cppcheck fix memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); //printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell); pbch_e_rx = &nr_ue_pbch_vars->llr[0]; @@ -522,7 +523,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #endif pbch_e_rx = nr_ue_pbch_vars->llr; //demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e; - pbch_a = nr_ue_pbch_vars->pbch_a; +// FT?? cppcheck fix - pbch_a = nr_ue_pbch_vars->pbch_a; #ifdef DEBUG_PBCH //pbch_e_rx = &nr_ue_pbch_vars->llr[0]; short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 7559115a29..a4a329b2cf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -47,7 +47,7 @@ \brief This function frees memory allocated for a particular DLSCH at UE @param dlsch Pointer to DLSCH to be removed */ -void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch); +void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch); /** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag) \brief This function allocates structures for a particular DLSCH at UE diff --git a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c index 334faafecd..4012322111 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c @@ -59,7 +59,7 @@ uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit) { int size = M_PN * sizeof(uint32_t); - int size_x = (sizeof(int)*M_PN + size; + int size_x = sizeof(int)*M_PN + size; int *x1 = malloc(size_x); int *x2 = malloc(size_x); diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 1bd7071b99..1b61260d10 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -42,14 +42,16 @@ extern PHY_VARS_NR_UE ***PHY_vars_UE_g; int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) { - /// module id - module_id_t module_id = scheduled_response->module_id; - /// component carrier id - uint8_t cc_id = scheduled_response->CC_id; - uint32_t i; - int slot = scheduled_response->slot; + if(scheduled_response != NULL){ + /// module id + module_id_t module_id = scheduled_response->module_id; + /// component carrier id + uint8_t cc_id = scheduled_response->CC_id; + uint32_t i; + int slot = scheduled_response->slot; + // Note: we have to handle the thread IDs for this. To be revisited completely. uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index aab762b9e2..2980187c42 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -623,7 +623,7 @@ int main(int argc, char **argv) printf("gNB %d\n", i); free_gNB_dlsch(gNB->dlsch[0][i]); printf("UE %d\n", i); - free_nr_ue_dlsch(UE->dlsch[0][0][i]); + free_nr_ue_dlsch(&(UE->dlsch[0][0][i])); } for (i = 0; i < 2; i++) { diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 49c1b340a6..2555be081a 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -302,5 +302,12 @@ typedef struct protocol_ctxt_s { #define CHECK_CTXT_ARGS(CTXT_Pp) #define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) +#ifdef __cplusplus +extern "C" +{ +#endif void exit_function(const char *file, const char *function, const int line, const char *s); +#ifdef __cplusplus +} +#endif #endif diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b56e8b11e9..8ee8cdc1c0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -221,7 +221,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, nr_rlc_ue_t *ue; nr_rlc_entity_t *rb; - LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %d mui %d confirm %d sdu_size %d MBMS_flag %d\n", + LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n", __FUNCTION__, rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP); @@ -824,24 +824,24 @@ rlc_op_status_t rrc_rlc_config_req ( } if ((srb_flagP && !(rb_idP >= 1 && rb_idP <= 2)) || (!srb_flagP && !(rb_idP >= 1 && rb_idP <= 5))) { - LOG_E(RLC, "%s:%d:%s: bad rb_id (%d) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); + LOG_E(RLC, "%s:%d:%s: bad rb_id (%ld) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); exit(1); } nr_rlc_manager_lock(nr_rlc_ue_manager); - LOG_D(RLC, "%s:%d:%s: remove rb %d (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); + LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rnti); if (srb_flagP) { if (ue->srb[rb_idP-1] != NULL) { ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]); ue->srb[rb_idP-1] = NULL; } else - LOG_W(RLC, "removing non allocated SRB %d, do nothing\n", rb_idP); + LOG_W(RLC, "removing non allocated SRB %ld, do nothing\n", rb_idP); } else { if (ue->drb[rb_idP-1] != NULL) { ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]); ue->drb[rb_idP-1] = NULL; } else - LOG_W(RLC, "removing non allocated DRB %d, do nothing\n", rb_idP); + LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP); } /* remove UE if it has no more RB configured */ for (i = 0; i < 2; i++) diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 0d66f42357..86e00ef674 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -193,7 +193,7 @@ ue_ip_common_class_wireless2ip( break; default: - printk("[UE_IP_DRV][%s] begin RB %d Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP); + printk("[UE_IP_DRV][%s] begin RB %ld Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP); printk("[UE_IP_DRV][%s] Inst %d: receive unknown message (version=%d)\n",__FUNCTION__,instP,ipv_p->version); } @@ -318,7 +318,7 @@ ue_ip_common_ip2wireless( if (bytes_wrote != UE_IP_PDCPH_SIZE) { printk("[UE_IP_DRV][%s] problem while writing PDCP's header (bytes wrote = %d)\n",__FUNCTION__,bytes_wrote); - printk("rb_id %d, Wrote %d, Header Size %d \n", pdcph.rb_id, bytes_wrote, UE_IP_PDCPH_SIZE); + printk("rb_id %ld, Wrote %d, Header Size %d \n", pdcph.rb_id, bytes_wrote, UE_IP_PDCPH_SIZE); priv_p->stats.tx_dropped ++; return; } @@ -326,7 +326,7 @@ ue_ip_common_ip2wireless( bytes_wrote += ue_ip_netlink_send((char *)skb_pP->data,skb_pP->len); if (bytes_wrote != skb_pP->len+UE_IP_PDCPH_SIZE) { - printk("[UE_IP_DRV][%s] Inst %d, RB_ID %d: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n", + printk("[UE_IP_DRV][%s] Inst %d, RB_ID %ld: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n", __FUNCTION__, instP, pdcph.rb_id, diff --git a/openair2/UTIL/OTG/otg_rx_socket.c b/openair2/UTIL/OTG/otg_rx_socket.c index 9e9b6bf4a1..a343910efd 100644 --- a/openair2/UTIL/OTG/otg_rx_socket.c +++ b/openair2/UTIL/OTG/otg_rx_socket.c @@ -195,7 +195,7 @@ void server_socket_tcp_ip4() /* create new thread for the new connection */ - threadCreate(&id, (void *)recv_ip4_tcp, (void*)csock), "OTG", -1, OAI_PRIORITY_RT_LOW); + threadCreate(&id, (void *)recv_ip4_tcp, (void*)csock, "OTG", -1, OAI_PRIORITY_RT_LOW); LOG_I(OTG,"SOCKET:: TCP-IP4 :: Client n=%d finish transmission\n", cmpt_cl); cmpt_cl+=1; } diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 8cfa398615..bb05808142 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -30,9 +30,9 @@ #include #include #if UHD_VERSION < 3110000 -#include + #include #else -#include + #include #endif #include #include @@ -48,26 +48,28 @@ #include "common/utils/LOG/log.h" #include "common_lib.h" #include "assertions.h" -#include + #include +#include "usrp_lib.h" + #ifdef __SSE4_1__ -# include + #include #endif #ifdef __AVX2__ -# include + #include #endif #ifdef __arm__ -# include + #include #endif /** @addtogroup _USRP_PHY_RF_INTERFACE_ * @{ */ -/*! \brief USRP Configuration */ + typedef struct { // -------------------------------- @@ -106,7 +108,8 @@ typedef struct { int first_tx; //! timestamp of RX packet openair0_timestamp rx_timestamp; - + uint32_t recplay_mode; + recplay_state_t *recplay_state; } usrp_state_t; //void print_notes(void) @@ -128,10 +131,10 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) { for (int i = 0; i < 30 and not ref_locked; i++) { ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); - + if (not ref_locked) { - std::cout << "." << std::flush; - boost::this_thread::sleep(boost::posix_time::seconds(1)); + std::cout << "." << std::flush; + boost::this_thread::sleep(boost::posix_time::seconds(1)); } } @@ -140,13 +143,11 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) { } else { std::cout << "FAILED" << std::endl; } - } else { std::cout << boost::format("ref_locked sensor not present on this board.\n"); } return ref_locked; - } static int sync_to_gps(openair0_device *device) { @@ -179,14 +180,13 @@ static int sync_to_gps(openair0_device *device) { for (size_t mboard = 0; mboard < num_mboards; mboard++) { std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; - bool ref_locked = check_ref_locked(s,mboard); if (ref_locked) { - std::cout << boost::format("Ref Locked\n"); + std::cout << boost::format("Ref Locked\n"); } else { - std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; - exit(EXIT_FAILURE); + std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; + exit(EXIT_FAILURE); } //Wait for GPS lock @@ -265,175 +265,134 @@ static int sync_to_gps(openair0_device *device) { return EXIT_SUCCESS; } -#if defined(USRP_REC_PLAY) -#include "usrp_lib.h" -static FILE *pFile = NULL; -int mmapfd = 0; -int iqfd = 0; -int use_mmap = 1; // default is to use mmap -struct stat sb; -iqrec_t *ms_sample = NULL; // memory for all subframes -unsigned int nb_samples = 0; -unsigned int cur_samples = 0; -int64_t wrap_count = 0; -int64_t wrap_ts = 0; -unsigned int u_sf_mode = 0; // 1=record, 2=replay -unsigned int u_sf_record = 0; // record mode -unsigned int u_sf_replay = 0; // replay mode -char u_sf_filename[1024] = ""; // subframes file path -unsigned int u_sf_max = DEF_NB_SF; // max number of recorded subframes -unsigned int u_sf_loops = DEF_SF_NB_LOOP; // number of loops in replay mode -unsigned int u_sf_read_delay = DEF_SF_DELAY_READ; // read delay in replay mode -unsigned int u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode - -char config_opt_sf_file[] = CONFIG_OPT_SF_FILE; -char config_def_sf_file[] = DEF_SF_FILE; -char config_hlp_sf_file[] = CONFIG_HLP_SF_FILE; -char config_opt_sf_rec[] = CONFIG_OPT_SF_REC; -char config_hlp_sf_rec[] = CONFIG_HLP_SF_REC; -char config_opt_sf_rep[] = CONFIG_OPT_SF_REP; -char config_hlp_sf_rep[] = CONFIG_HLP_SF_REP; -char config_opt_sf_max[] = CONFIG_OPT_SF_MAX; -char config_hlp_sf_max[] = CONFIG_HLP_SF_MAX; -char config_opt_sf_loops[] = CONFIG_OPT_SF_LOOPS; -char config_hlp_sf_loops[] = CONFIG_HLP_SF_LOOPS; -char config_opt_sf_rdelay[] = CONFIG_OPT_SF_RDELAY; -char config_hlp_sf_rdelay[] = CONFIG_HLP_SF_RDELAY; -char config_opt_sf_wdelay[] = CONFIG_OPT_SF_WDELAY; -char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY; - -#endif - /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ static int trx_usrp_start(openair0_device *device) { -#if defined(USRP_REC_PLAY) + usrp_state_t *s = (usrp_state_t *)device->priv; - if (u_sf_mode != 2) { // not replay mode -#endif - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t *)device->priv; - // setup GPIO for TDD, GPIO(4) = ATR_RX - //set data direction register (DDR) to output - s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); - //set control register to ATR - s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0x7f); - //set ATR register - s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f); - // init recv and send streaming - uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - LOG_I(HW,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); - LOG_I(HW,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate)); + if ( s->recplay_mode == RECPLAY_REPLAYMODE) + return 0; - if (s->use_gps == 1 || device->openair0_cfg[0].time_source == external) { - s->wait_for_first_pps = 1; - cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); - } else { - s->wait_for_first_pps = 0; - cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.005); - } + // setup GPIO for TDD, GPIO(4) = ATR_RX + //set data direction register (DDR) to output + s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); + //set control register to ATR + s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0x7f); + //set ATR register + s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f); + // init recv and send streaming + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + LOG_I(HW,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); + LOG_I(HW,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate)); - cmd.stream_now = false; // start at constant delay - s->rx_stream->issue_stream_cmd(cmd); - /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false;*/ - s->rx_count = 0; - s->tx_count = 0; - s->rx_timestamp = 0; -#if defined(USRP_REC_PLAY) + if (s->use_gps == 1 || device->openair0_cfg[0].time_source == external) { + s->wait_for_first_pps = 1; + cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); + } else { + s->wait_for_first_pps = 0; + cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.005); } -#endif + cmd.stream_now = false; // start at constant delay + s->rx_stream->issue_stream_cmd(cmd); + /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false;*/ + s->rx_count = 0; + s->tx_count = 0; + s->rx_timestamp = 0; return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ static void trx_usrp_end(openair0_device *device) { -#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times... - static int done = 0; + if (device == NULL) + return; - if (done == 1) return; + usrp_state_t *s = (usrp_state_t *)device->priv; - done = 1; + if (s == NULL) + return; - - if (u_sf_mode != 2) { // not subframes replay -#endif - usrp_state_t *s = (usrp_state_t *)device->priv; + if (s->recplay_mode != RECPLAY_REPLAYMODE) { // not subframes replay s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); //send a mini EOB packet s->tx_md.end_of_burst = true; s->tx_stream->send("", 0, s->tx_md); s->tx_md.end_of_burst = false; sleep(1); -#if defined(USRP_REC_PLAY) } -#endif -#if defined(USRP_REC_PLAY) + if (s->recplay_mode == RECPLAY_RECORDMODE) { // subframes store + s->recplay_state->pFile = fopen (s->recplay_state->u_sf_filename,"wb+"); - if (u_sf_mode == 1) { // subframes store - pFile = fopen (u_sf_filename,"wb+"); - - if (pFile == NULL) { - std::cerr << "Cannot open " << u_sf_filename << std::endl; + if (s->recplay_state->pFile == NULL) { + std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << std::endl; } else { unsigned int i = 0; unsigned int modu = 0; - if ((modu = nb_samples % 10) != 0) { - nb_samples -= modu; // store entire number of frames + if ((modu = s->recplay_state->nb_samples % 10) != 0) { + s->recplay_state->nb_samples -= modu; // store entire number of frames } - std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; + std::cerr << "Writing " << s->recplay_state->nb_samples << " subframes to " << s->recplay_state->u_sf_filename << " ..." << std::endl; - for (i = 0; i < nb_samples; i++) { - fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); + for (i = 0; i < s->recplay_state->nb_samples; i++) { + fwrite(s->recplay_state->ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), s->recplay_state->pFile); } - fclose (pFile); - std::cerr << "File " << u_sf_filename << " closed." << std::endl; + fclose (s->recplay_state->pFile); + std::cerr << "File " << s->recplay_state->u_sf_filename << " closed." << std::endl; } - } - if (u_sf_mode == 1) { // record - if (ms_sample != NULL) { - free((void *)ms_sample); - ms_sample = NULL; + if (s->recplay_state->ms_sample != NULL) { + free((void *)s->recplay_state->ms_sample); + s->recplay_state->ms_sample = NULL; } - } - - if (u_sf_mode == 2) { // replay - if (use_mmap) { - if (ms_sample != MAP_FAILED) { - munmap(ms_sample, sb.st_size); - ms_sample = NULL; + } else if (s->recplay_mode == RECPLAY_REPLAYMODE) { // replay + if (s->recplay_state->use_mmap) { + if (s->recplay_state->ms_sample != MAP_FAILED) { + munmap(s->recplay_state->ms_sample, s->recplay_state->mapsize); + s->recplay_state->ms_sample = NULL; } - if (mmapfd != 0) { - close(mmapfd); - mmapfd = 0; + if (s->recplay_state->mmapfd != 0) { + close(s->recplay_state->mmapfd); + s->recplay_state->mmapfd = 0; } } else { - if (ms_sample != NULL) { - free(ms_sample); - ms_sample = NULL; + if (s->recplay_state->ms_sample != NULL) { + free(s->recplay_state->ms_sample); + s->recplay_state->ms_sample = NULL; } - if (iqfd != 0) { - close(iqfd); - iqfd = 0; + if (s->recplay_state->iqfd != 0) { + close(s->recplay_state->iqfd); + s->recplay_state->iqfd = 0; } } } - -#endif } - +/*! \brief Write iqs function when in replay mode, just introduce a delay, as configured at init time, + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at which the first sample MUST be sent + @param buff Buffer which holds the samples + @param nsamps number of samples to be sent + @param antenna_id index of the antenna if the device has multiple antennas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied +*/ +static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + struct timespec req; + usrp_state_t *s = (usrp_state_t *)device->priv; + req.tv_sec = 0; + req.tv_nsec = s->recplay_state->u_sf_write_delay * 1000; + nanosleep(&req, NULL); + return nsamps; +} /*! \brief Called to send samples to the USRP RF target @param device pointer to the device structure specific to the RF hardware target @param timestamp The timestamp at which the first sample MUST be sent @@ -444,14 +403,8 @@ static void trx_usrp_end(openair0_device *device) { */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { int ret=0; -#if defined(USRP_REC_PLAY) - - if (u_sf_mode != 2) { // not replay mode -#endif - usrp_state_t *s = (usrp_state_t *)device->priv; - - int nsamps2; // aligned to upper 32 or 16 byte boundary - + usrp_state_t *s = (usrp_state_t *)device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -464,23 +417,24 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, nsamps2 = (nsamps+3)>>2; int16x8_t buff_tx[8][nsamps2]; #else - #error Unsupported CPU architecture, USRP device cannot be built +#error Unsupported CPU architecture, USRP device cannot be built #endif - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; itx_md.start_of_burst = true; - // s->tx_md.end_of_burst = true; + // s->tx_md.start_of_burst = true; + // s->tx_md.end_of_burst = true; first_packet_state = true; last_packet_state = true; } else if (flags==1) { // middle of burst - // s->tx_md.start_of_burst = false; - // s->tx_md.end_of_burst = false; + // s->tx_md.start_of_burst = false; + // s->tx_md.end_of_burst = false; first_packet_state = false; last_packet_state = false; - } - else if (flags==10) { // fail safe mode - // s->tx_md.has_time_spec = false; - // s->tx_md.start_of_burst = false; - // s->tx_md.end_of_burst = true; - first_packet_state = false; - last_packet_state = true; + } else if (flags==10) { // fail safe mode + // s->tx_md.has_time_spec = false; + // s->tx_md.start_of_burst = false; + // s->tx_md.end_of_burst = true; + first_packet_state = false; + last_packet_state = true; } s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; + s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; s->tx_md.end_of_burst = last_packet_state; s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - s->tx_count++; if (cc>1) { - std::vector buff_ptrs; + std::vector buff_ptrs; - for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md); + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); + if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); - if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); - -#if defined(USRP_REC_PLAY) - } else { - struct timespec req; - req.tv_sec = 0; - req.tv_nsec = u_sf_write_delay * 1000; - nanosleep(&req, NULL); - ret = nsamps; - } - -#endif return ret; } +/*! \brief Receive samples from iq file. + * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param antenna_id Index of antenna for which to receive samples + * \returns the number of sample read +*/ +static int trx_usrp_read_recplay(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + int samples_received=0; + static unsigned int cur_samples; + static int64_t wrap_count; + static int64_t wrap_ts; + usrp_state_t *s = (usrp_state_t *)device->priv; + + + if (cur_samples == s->recplay_state->nb_samples) { + cur_samples = 0; + wrap_count++; + if (wrap_count == s->recplay_state->u_sf_loops) { + std::cerr << "USRP device terminating subframes replay mode after " << s->recplay_state->u_sf_loops << " loops." << std::endl; + exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n"); + } + + wrap_ts = wrap_count * (s->recplay_state->nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); + + if (!s->recplay_state->use_mmap) { + if (lseek(s->recplay_state->iqfd, 0, SEEK_SET) == 0) { + std::cerr << "Seeking at the beginning of IQ file" << std::endl; + } else { + std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; + } + } + } + + if (s->recplay_state->use_mmap) { + if (cur_samples < s->recplay_state->nb_samples) { + *ptimestamp = (s->recplay_state->ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + + memcpy(buff[0], &s->recplay_state->ms_sample[cur_samples].samples[0], nsamps*4); + cur_samples++; + } + } else { + // read sample from file + if (read(s->recplay_state->iqfd, s->recplay_state->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { + std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; + close(s->recplay_state->iqfd); + free(s->recplay_state->ms_sample); + s->recplay_state->ms_sample = NULL; + s->recplay_state->iqfd = 0; + exit(-1); + } + + if (cur_samples < s->recplay_state->nb_samples) { + static int64_t ts0 = 0; + + if ((cur_samples == 0) && (wrap_count == 0)) { + ts0 = s->recplay_state->ms_sample->ts; + } + + *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + + memcpy(buff[0], &s->recplay_state->ms_sample->samples[0], nsamps*4); + cur_samples++; + // Prepare for next read + off_t where = lseek(s->recplay_state->iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); + + if (where < 0) { + LOG_E(HW,"Cannot lseek in iqfile: %s\n",strerror(errno)); + } + } + } + + struct timespec req; + + req.tv_sec = 0; + + req.tv_nsec = s->recplay_state->u_sf_read_delay * 1000; + + nanosleep(&req, NULL); + + return nsamps; + + return samples_received; +} + + /*! \brief Receive samples from hardware. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for * the first channel. *ptimestamp is the time at which the first sample @@ -559,186 +600,102 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp usrp_state_t *s = (usrp_state_t *)device->priv; int samples_received=0; int nsamps2; // aligned to upper 32 or 16 byte boundary -#if defined(USRP_REC_PLAY) - - if (u_sf_mode != 2) { // not replay mode -#endif #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[8][nsamps2]; + nsamps2 = (nsamps+7)>>3; + __m256i buff_tmp[2][nsamps2]; #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[8][nsamps2]; + nsamps2 = (nsamps+3)>>2; + __m128i buff_tmp[2][nsamps2]; #endif #elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[8][nsamps2]; + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tmp[2][nsamps2]; #endif - if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; + if (device->type == USRP_B200_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; - for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received=0; + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received=0; - while (samples_received != nsamps) { - samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, - nsamps-samples_received, s->rx_md); + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); - if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) - break; + if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) + break; - if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { - printf("sleep...\n"); //usleep(100); - } + if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { + printf("sleep...\n"); //usleep(100); } - - if (samples_received == nsamps) s->wait_for_first_pps=0; } - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; iwait_for_first_pps=0; + } + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; itype == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - - for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md,1.0); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md,1.0); } } + } else if (device->type == USRP_X300_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; - if (samples_received < nsamps) - LOG_E(HW,"[recv] received %d samples out of %d\n",samples_received,nsamps); + for (int i=0; irx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - LOG_E(HW, "%s\n", s->rx_md.to_pp_string(true).c_str()); - - s->rx_count += nsamps; - s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); - *ptimestamp = s->rx_timestamp; -#if defined (USRP_REC_PLAY) - } - -#endif -#if defined(USRP_REC_PLAY) - - if (u_sf_mode == 1) { // record mode - // Copy subframes to memory (later dump on a file) - if (nb_samples < u_sf_max) { - (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; - (ms_sample+nb_samples)->ts = *ptimestamp; - memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4); - nb_samples++; - } - } else if (u_sf_mode == 2) { // replay mode - if (cur_samples == nb_samples) { - cur_samples = 0; - wrap_count++; - - if (wrap_count == u_sf_loops) { - std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; - return 0; // should make calling process exit - } - - wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); - - if (!use_mmap) { - if (lseek(iqfd, 0, SEEK_SET) == 0) { - std::cerr << "Seeking at the beginning of IQ file" << std::endl; - } else { - std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; - } - } - } - - if (use_mmap) { - if (cur_samples < nb_samples) { - *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; - - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } - - memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); - cur_samples++; - } + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md,1.0); } else { - // read sample from file - if (read(iqfd, ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { - std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; - close(iqfd); - free(ms_sample); - ms_sample = NULL; - iqfd = 0; - exit(-1); - } - - if (cur_samples < nb_samples) { - static int64_t ts0 = 0; - - if ((cur_samples == 0) && (wrap_count == 0)) { - ts0 = ms_sample->ts; - } - - *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; - - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } - - memcpy(buff[0], &ms_sample->samples[0], nsamps*4); - cur_samples++; - // Prepare for next read - off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); - } + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md,1.0); } - - struct timespec req; - - req.tv_sec = 0; - - req.tv_nsec = u_sf_read_delay * 1000; - - nanosleep(&req, NULL); - - return nsamps; } -#endif + if (samples_received < nsamps) + LOG_E(HW,"[recv] received %d samples out of %d\n",samples_received,nsamps); + + if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) + LOG_E(HW, "%s\n", s->rx_md.to_pp_string(true).c_str()); + + s->rx_count += nsamps; + s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); + *ptimestamp = s->rx_timestamp; + + if (s->recplay_mode == RECPLAY_RECORDMODE) { // record mode + // Copy subframes to memory (later dump on a file) + if (s->recplay_state->nb_samples < s->recplay_state->u_sf_max) { + (s->recplay_state->ms_sample+s->recplay_state->nb_samples)->header = BELL_LABS_IQ_HEADER; + (s->recplay_state->ms_sample+s->recplay_state->nb_samples)->ts = *ptimestamp; + memcpy((s->recplay_state->ms_sample+s->recplay_state->nb_samples)->samples, buff[0], nsamps*4); + s->recplay_state->nb_samples++; + } else exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n"); + } + return samples_received; } @@ -868,7 +825,6 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ if (bw_gain_adjust==1) { switch ((int)openair0_cfg[0].sample_rate) { - case 46080000: break; @@ -940,117 +896,37 @@ static void uhd_set_thread_priority(void) { uhd::set_thread_priority_safe(1.0); } -#if defined(USRP_REC_PLAY) -extern "C" { - /*! \brief Initializer for USRP record/playback config - * \param parameter array description - * \returns 0 on success - */ - int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { - // --subframes-file - memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file)); - usrp_recplay_params[0].helpstr = config_hlp_sf_file; - usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE; - usrp_recplay_params[0].strptr=(char **)&u_sf_filename; - usrp_recplay_params[0].defstrval = NULL; - usrp_recplay_params[0].type=TYPE_STRING; - usrp_recplay_params[0].numelt=sizeof(u_sf_filename); - // --subframes-record - memcpy(usrp_recplay_params[1].optname, config_opt_sf_rec, strlen(config_opt_sf_rec)); - usrp_recplay_params[1].helpstr = config_hlp_sf_rec; - usrp_recplay_params[1].paramflags=PARAMFLAG_BOOL; - usrp_recplay_params[1].uptr=&u_sf_record; - usrp_recplay_params[1].defuintval=0; - usrp_recplay_params[1].type=TYPE_UINT; - usrp_recplay_params[1].numelt=0; - // --subframes-replay - memcpy(usrp_recplay_params[2].optname, config_opt_sf_rep, strlen(config_opt_sf_rep)); - usrp_recplay_params[2].helpstr = config_hlp_sf_rep; - usrp_recplay_params[2].paramflags=PARAMFLAG_BOOL; - usrp_recplay_params[2].uptr=&u_sf_replay; - usrp_recplay_params[2].defuintval=0; - usrp_recplay_params[2].type=TYPE_UINT; - usrp_recplay_params[2].numelt=0; - // --subframes-max - memcpy(usrp_recplay_params[3].optname, config_opt_sf_max, strlen(config_opt_sf_max)); - usrp_recplay_params[3].helpstr = config_hlp_sf_max; - usrp_recplay_params[3].paramflags=0; - usrp_recplay_params[3].uptr=&u_sf_max; - usrp_recplay_params[3].defuintval=DEF_NB_SF; - usrp_recplay_params[3].type=TYPE_UINT; - usrp_recplay_params[3].numelt=0; - // --subframes-loops - memcpy(usrp_recplay_params[4].optname, config_opt_sf_loops, strlen(config_opt_sf_loops)); - usrp_recplay_params[4].helpstr = config_hlp_sf_loops; - usrp_recplay_params[4].paramflags=0; - usrp_recplay_params[4].uptr=&u_sf_loops; - usrp_recplay_params[4].defuintval=DEF_SF_NB_LOOP; - usrp_recplay_params[4].type=TYPE_UINT; - usrp_recplay_params[4].numelt=0; - // --subframes-read-delay - memcpy(usrp_recplay_params[5].optname, config_opt_sf_rdelay, strlen(config_opt_sf_rdelay)); - usrp_recplay_params[5].helpstr = config_hlp_sf_rdelay; - usrp_recplay_params[5].paramflags=0; - usrp_recplay_params[5].uptr=&u_sf_read_delay; - usrp_recplay_params[5].defuintval=DEF_SF_DELAY_READ; - usrp_recplay_params[5].type=TYPE_UINT; - usrp_recplay_params[5].numelt=0; - // --subframes-write-delay - memcpy(usrp_recplay_params[6].optname, config_opt_sf_wdelay, strlen(config_opt_sf_wdelay)); - usrp_recplay_params[6].helpstr = config_hlp_sf_wdelay; - usrp_recplay_params[6].paramflags=0; - usrp_recplay_params[6].uptr=&u_sf_write_delay; - usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE; - usrp_recplay_params[6].type=TYPE_UINT; - usrp_recplay_params[6].numelt=0; - return 0; // always ok - } +void noop_func(void) { + return; } -#endif - extern "C" { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { -#if defined(USRP_REC_PLAY) - paramdef_t usrp_recplay_params[7]; - struct sysinfo systeminfo; - // to check - static int done = 0; + LOG_D(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs); + LOG_D(HW, "openair0_cfg[0].clock_source == '%d'\n", openair0_cfg[0].clock_source); + usrp_state_t *s ; - if (done == 1) { + if ( device->priv == NULL) { + s=(usrp_state_t *)calloc(sizeof(usrp_state_t),1); + device->priv=s; + AssertFatal( s!=NULL,"USRP device: memory allocation failure\n"); + } else { + LOG_E(HW, "multiple device init detected\n"); return 0; - } // prevent from multiple init - - done = 1; - // end to check - // Use mmap for IQ files for systems with less than 6GB total RAM - sysinfo(&systeminfo); - - if (systeminfo.totalram < 6144000000) { - use_mmap = 0; } - memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); - memset(&u_sf_filename[0], 0, 1024); + device->openair0_cfg = openair0_cfg; + read_usrpconfig(&(s->recplay_mode), &(s->recplay_state)); + device->trx_start_func = trx_usrp_start; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; - if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { - std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; - return -1; - } - - config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); - - if (strlen(u_sf_filename) == 0) { - (void) strcpy(u_sf_filename, DEF_SF_FILE); - } - - if (u_sf_replay == 1) u_sf_mode = 2; - - if (u_sf_record == 1) u_sf_mode = 1; - - if (u_sf_mode == 2) { + if ( s->recplay_mode == RECPLAY_REPLAYMODE) { // Replay subframes from from file int bw_gain_adjust=0; - device->openair0_cfg = openair0_cfg; device->type = USRP_B200_DEV; openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; bw_gain_adjust=1; @@ -1060,45 +936,30 @@ extern "C" { openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust); - device->priv = NULL; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - device->uhd_set_thread_priority = uhd_set_thread_priority; - std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" - << use_mmap << std::endl; + device->trx_write_func = trx_usrp_write_recplay; + device->trx_read_func = trx_usrp_read_recplay; + device->uhd_set_thread_priority = noop_func; + std::cerr << "USRP device initialized in subframes replay mode for " << s->recplay_state->u_sf_loops << " loops. Use mmap=" + << s->recplay_state->use_mmap << std::endl; } else { -#endif - usrp_state_t *s = (usrp_state_t *)calloc(sizeof(usrp_state_t),1); - // Initialize USRP device - device->openair0_cfg = openair0_cfg; int vers=0,subvers=0,subsubvers=0; int bw_gain_adjust=0; -#if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { + if (s->recplay_mode == RECPLAY_RECORDMODE) { std::cerr << "USRP device initialized in subframes record mode" << std::endl; } -#endif sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); LOG_I(HW,"UHD version %s (%d.%d.%d)\n", uhd::get_version_string().c_str(),vers,subvers,subsubvers); - std::string args; + if (openair0_cfg[0].sdr_addrs == NULL) { args = "type=b200"; } else { args = openair0_cfg[0].sdr_addrs; - LOG_I(HW,"Checking for USRP with args %s\n",openair0_cfg[0].sdr_addrs); + LOG_I(HW,"Checking for USRP with args %s\n",openair0_cfg[0].sdr_addrs); } uhd::device_addrs_t device_adds = uhd::device::find(args); @@ -1109,8 +970,8 @@ extern "C" { return -1; } else if (device_adds.size() > 1) { LOG_E(HW,"More than one USRP Device Found. Please specify device more precisely in config file.\n"); - free(s); - return -1; + free(s); + return -1; } LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str()); @@ -1123,6 +984,7 @@ extern "C" { args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ; } + if (device_adds[0].get("type") == "n3xx") { printf("Found USRP n300\n"); device->type=USRP_X300_DEV; //treat it as X300 for now @@ -1136,60 +998,55 @@ extern "C" { device->type=USRP_X300_DEV; usrp_master_clock = 184.32e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + // USRP recommended: https://files.ettus.com/manual/page_usrp_x3x0_config.html if ( 0 != system("sysctl -w net.core.rmem_max=33554432 net.core.wmem_max=33554432") ) - LOG_W(HW,"Can't set kernel parameters for X3xx\n"); + LOG_W(HW,"Can't set kernel parameters for X3xx\n"); } s->usrp = uhd::usrp::multi_usrp::make(args); - device->priv = s; if (args.find("clock_source")==std::string::npos) { - LOG_I(HW, "Using clock_source == '%d'\n", openair0_cfg[0].clock_source); + LOG_I(HW, "Using clock_source == '%d'\n", openair0_cfg[0].clock_source); - if (openair0_cfg[0].clock_source == internal) { - //in UHD 3.14 we could use - //s->usrp->set_sync_source("clock_source=internal","time_source=internal"); - s->usrp->set_time_source("internal"); - s->usrp->set_clock_source("internal"); - } - else if (openair0_cfg[0].clock_source == external ) { - //s->usrp->set_sync_source("clock_source=external","time_source=external"); - s->usrp->set_time_source("external"); - s->usrp->set_clock_source("external"); - } - else if (openair0_cfg[0].clock_source==gpsdo) { - s->usrp->set_clock_source("gpsdo"); - s->usrp->set_time_source("gpsdo"); - } + if (openair0_cfg[0].clock_source == internal) { + //in UHD 3.14 we could use + //s->usrp->set_sync_source("clock_source=internal","time_source=internal"); + s->usrp->set_time_source("internal"); + s->usrp->set_clock_source("internal"); + } else if (openair0_cfg[0].clock_source == external ) { + //s->usrp->set_sync_source("clock_source=external","time_source=external"); + s->usrp->set_time_source("external"); + s->usrp->set_clock_source("external"); + } else if (openair0_cfg[0].clock_source==gpsdo) { + s->usrp->set_clock_source("gpsdo"); + s->usrp->set_time_source("gpsdo"); + } } else { - LOG_W(HW, "clock_source already specified in device arguments! Ignoring command line parameter\n"); + LOG_W(HW, "clock_source already specified in device arguments! Ignoring command line parameter\n"); } if (s->usrp->get_clock_source(0) == "gpsdo") { - s->use_gps = 1; + s->use_gps = 1; + if (sync_to_gps(device)==EXIT_SUCCESS) { LOG_I(HW,"USRP synced with GPS!\n"); - } - else { + } else { LOG_I(HW,"USRP fails to sync with GPS. Exiting.\n"); exit(EXIT_FAILURE); } - } else if (s->usrp->get_clock_source(0) == "external") { - if (check_ref_locked(s,0)) { - LOG_I(HW,"USRP locked to external reference!\n"); - } else { - LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); - exit(EXIT_FAILURE); - } + } else if (s->usrp->get_clock_source(0) == "external") { + if (check_ref_locked(s,0)) { + LOG_I(HW,"USRP locked to external reference!\n"); + } else { + LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); + exit(EXIT_FAILURE); + } } - - + if (device->type==USRP_X300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; -#if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info -#endif LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); switch ((int)openair0_cfg[0].sample_rate) { @@ -1208,7 +1065,7 @@ extern "C" { openair0_cfg[0].tx_bw = 80e6; openair0_cfg[0].rx_bw = 80e6; break; - + case 61440000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; @@ -1264,19 +1121,15 @@ extern "C" { if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { openair0_cfg[0].rx_gain_calib_table = calib_table_b210; bw_gain_adjust=0; -#if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info -#endif } else { openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; bw_gain_adjust=1; -#if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info -#endif } switch ((int)openair0_cfg[0].sample_rate) { - case 46080000: + case 46080000: s->usrp->set_master_clock_rate(46.08e6); //openair0_cfg[0].samples_per_packet = 1024; openair0_cfg[0].tx_sample_advance = 115; @@ -1284,7 +1137,7 @@ extern "C" { openair0_cfg[0].rx_bw = 40e6; break; - case 30720000: + case 30720000: s->usrp->set_master_clock_rate(30.72e6); //openair0_cfg[0].samples_per_packet = 1024; openair0_cfg[0].tx_sample_advance = 115; @@ -1373,7 +1226,6 @@ extern "C" { // display USRP settings LOG_I(HW,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); sleep(1); - // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); int samples=openair0_cfg[0].sample_rate; @@ -1422,21 +1274,12 @@ extern "C" { LOG_I(HW," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); LOG_I(HW," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); LOG_I(HW," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); - LOG_I(HW," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps()); + LOG_I(HW," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps()); } LOG_I(HW,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - device->priv = s; - device->trx_start_func = trx_usrp_start; device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; device->uhd_set_thread_priority = uhd_set_thread_priority; s->sample_rate = openair0_cfg[0].sample_rate; @@ -1450,87 +1293,82 @@ extern "C" { if(is_equal(s->sample_rate, (double)7.68e6)) s->tx_forward_nsamps = 50; - - -#if defined(USRP_REC_PLAY) } -#endif -#if defined(USRP_REC_PLAY) + if (s->recplay_mode == RECPLAY_RECORDMODE) { // record mode + s->recplay_state->ms_sample = (iqrec_t *) malloc(s->recplay_state->u_sf_max * sizeof(iqrec_t)); - if (u_sf_mode == 1) { // record mode - ms_sample = (iqrec_t *) malloc(u_sf_max * sizeof(iqrec_t)); - - if (ms_sample == NULL) { + if (s->recplay_state->ms_sample == NULL) { std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; exit(-1); } - memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); - } - - if (u_sf_mode == 2) { - if (use_mmap) { + memset(s->recplay_state->ms_sample, 0, s->recplay_state->u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + } else if (s->recplay_mode == RECPLAY_REPLAYMODE) { + if (s->recplay_state->use_mmap) { // use mmap - mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + s->recplay_state->mmapfd = open(s->recplay_state->u_sf_filename, O_RDONLY | O_LARGEFILE); - if (mmapfd != 0) { - fstat(mmapfd, &sb); - std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; - ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); + if (s->recplay_state->mmapfd != 0) { + struct stat sb; + fstat(s->recplay_state->mmapfd, &sb); + s->recplay_state->mapsize=sb.st_size; + std::cerr << "Loading subframes using mmap() from " << s->recplay_state->u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + s->recplay_state->ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->recplay_state->mmapfd, 0); - if (ms_sample != MAP_FAILED) { - nb_samples = (sb.st_size / sizeof(iqrec_t)); - int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; - std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; + if (s->recplay_state->ms_sample != MAP_FAILED) { + s->recplay_state->nb_samples = (sb.st_size / sizeof(iqrec_t)); + int aligned = (((unsigned long)s->recplay_state->ms_sample & 31) == 0)? 1:0; + std::cerr<< "Loaded "<< s->recplay_state->nb_samples << " subframes." << std::endl; if (aligned == 0) { std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; - close(mmapfd); + close(s->recplay_state->mmapfd); exit(-1); } } else { std::cerr << "Cannot mmap file, exiting." << std::endl; - close(mmapfd); + close(s->recplay_state->mmapfd); exit(-1); } } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << " , exiting." << std::endl; exit(-1); } } else { - iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + s->recplay_state->iqfd = open(s->recplay_state->u_sf_filename, O_RDONLY | O_LARGEFILE); - if (iqfd != 0) { - fstat(iqfd, &sb); - nb_samples = (sb.st_size / sizeof(iqrec_t)); - std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename + if (s->recplay_state->iqfd != 0) { + struct stat sb; + fstat(s->recplay_state->iqfd, &sb); + s->recplay_state->mapsize=sb.st_size; + s->recplay_state->nb_samples = (sb.st_size / sizeof(iqrec_t)); + std::cerr << "Loading " << s->recplay_state->nb_samples << " subframes from " << s->recplay_state->u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; // allocate buffer for 1 sample at a time - ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); + s->recplay_state->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); - if (ms_sample == NULL) { + if (s->recplay_state->ms_sample == NULL) { std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; - close(iqfd); + close(s->recplay_state->iqfd); exit(-1); } - memset(ms_sample, 0, sizeof(iqrec_t)); + memset(s->recplay_state->ms_sample, 0, sizeof(iqrec_t)); // point at beginning of file - if (lseek(iqfd, 0, SEEK_SET) == 0) { + if (lseek(s->recplay_state->iqfd, 0, SEEK_SET) == 0) { std::cerr << "Initial seek at beginning of the file" << std::endl; } else { std::cerr << "Problem initial seek at beginning of the file" << std::endl; } } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << " , exiting." << std::endl; exit(-1); } } } -#endif return 0; } diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h index 228d3a5857..d29cf41db2 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h @@ -26,8 +26,6 @@ * \author: bruno.mongazon-cazavet@nokia-bell-labs.com */ -#if defined (USRP_REC_PLAY) - #include #include #include @@ -35,6 +33,29 @@ #include "common/config/config_paramdesc.h" #include "common/config/config_userapi.h" +#ifdef __cplusplus +extern "C" +{ +#endif +#define CONFIG_OPT_RECPLAY "enable_recplay" + +#define CONFIG_HLP_RECPLAY "Allow record player" +#define USRP_SECTION "device.usrp" +/* inclusion for device configuration */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters for USRP record/playback */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define USRP_DEVICE_PARAMS_DESC { \ + {CONFIG_OPT_RECPLAY, CONFIG_HLP_RECPLAY, PARAMFLAG_BOOL, uptr:&enable_recplay, defuintval:0, TYPE_UINT, 0} \ + } + + +/* inclusions for record player */ +#define RECPLAY_DISABLED 0 +#define RECPLAY_RECORDMODE 1 +#define RECPLAY_REPLAYMODE 2 + #define BELL_LABS_IQ_HEADER 0xabababababababab #define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now #define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4) @@ -46,13 +67,13 @@ typedef struct { unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe } iqrec_t; #define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz) -#define DEF_SF_FILE "/home/nokia/iqfile" // default subframes file name +#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name #define DEF_SF_DELAY_READ 700 // default read delay µs (860=real) #define DEF_SF_DELAY_WRITE 15 // default write delay µs (15=real) #define DEF_SF_NB_LOOP 5 // default nb loops -/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ +/* help strings definition for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_HLP_SF_FILE "Path of the file used for subframes record or replay" #define CONFIG_HLP_SF_REC "Record subframes from USRP driver into a file for later replay" #define CONFIG_HLP_SF_REP "Replay subframes into USRP driver from a file" @@ -61,7 +82,7 @@ typedef struct { #define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode" #define CONFIG_HLP_SF_WDELAY "Delay in microseconds to write a subframe in replay mode" -/* keyword strings for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ +/* keyword strings for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_OPT_SF_FILE "subframes-file" #define CONFIG_OPT_SF_REC "subframes-record" #define CONFIG_OPT_SF_REP "subframes-replay" @@ -70,20 +91,41 @@ typedef struct { #define CONFIG_OPT_SF_RDELAY "subframes-read-delay" #define CONFIG_OPT_SF_WDELAY "subframes-write-delay" +#define USRP_RECPLAY_SECTION "device.recplay" /* For information only - the macro is not usable in C++ */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters for USRP record/playback */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define USRP_RECPLAY_PARAMS_DESC { \ -{"subframes-file", CONFIG_HLP_SF_FILE, 0, strptr:(char **)&u_sf_filename, defstrval:DEF_SF_FILE, TYPE_STRING, sizeof(u_sf_filename)}, \ -{"subframes-record", CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&u_sf_record, defuintval:0, TYPE_UINT, 0}, \ -{"subframes-replay", CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&u_sf_replay, defuintval:0, TYPE_UINT, 0}, \ -{"subframes-max", CONFIG_HLP_SF_MAX, 0, uptr:&u_sf_max, defintval:DEF_NB_SF, TYPE_UINT, 0}, \ -{"subframes-loops", CONFIG_HLP_SF_LOOPS, 0, uptr:&u_sf_loops, defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ -{"subframes-read-delay", CONFIG_HLP_SF_RDELAY, 0, uptr:&u_sf_read_delay, defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ -{"subframes-write-delay", CONFIG_HLP_SF_WDELAY, 0, uptr:&u_sf_write_delay, defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:(char **)((*recplay_state)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 1024}, \ + {CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_state)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_state)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_state)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_state)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ + }/*! \brief USRP Configuration and state */ + +typedef struct { + FILE *pFile; + int mmapfd; + int iqfd; + int use_mmap; // default is to use mmap + size_t mapsize; + iqrec_t *ms_sample; // memory for all subframes + unsigned int nb_samples; + char u_sf_filename[1024]; // subframes file path + unsigned int u_sf_max ; // max number of recorded subframes + unsigned int u_sf_loops ; // number of loops in replay mode + unsigned int u_sf_read_delay; // read delay in replay mode + unsigned int u_sf_write_delay ; // write delay in replay mode +} recplay_state_t; + + +extern int read_usrpconfig(uint32_t *recplay_mode, recplay_state_t **recplay_state); +#ifdef __cplusplus } -#endif // BELL_LABS_MUST +#endif #endif // __USRP_LIB_H diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c new file mode 100644 index 0000000000..ebf1d61eed --- /dev/null +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c @@ -0,0 +1,73 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/** usrp_lib_config.c + * + * \author: HongliangXU : hong-liang-xu@agilent.com + */ + +#include +#include +#include +#include +#include +#include "common/utils/LOG/log.h" +#include "assertions.h" +#include "common_lib.h" +#include "usrp_lib.h" + + +int read_usrpconfig(uint32_t *recplay_mode, recplay_state_t **recplay_state) { +unsigned int u_sf_record = 0; // record mode +unsigned int u_sf_replay = 0; // replay mode +uint32_t enable_recplay; + + paramdef_t usrp_params[] = USRP_DEVICE_PARAMS_DESC; + config_get(usrp_params,sizeof(usrp_params)/sizeof(paramdef_t),USRP_SECTION); + if (enable_recplay) { + *recplay_state = calloc(sizeof(recplay_state_t),1); + paramdef_t usrp_recplay_params[]=USRP_RECPLAY_PARAMS_DESC ; + struct sysinfo systeminfo; + + // Use mmap for IQ files for systems with less than 6GB total RAM + sysinfo(&systeminfo); + + if (systeminfo.totalram < 6144000000) { + (*recplay_state)->use_mmap = 0; + } else { + (*recplay_state)->use_mmap = 1; + } + + memset((*recplay_state)->u_sf_filename, 0, 1024); + config_get(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),USRP_RECPLAY_SECTION); + + if (strlen((*recplay_state)->u_sf_filename) == 0) { + (void) strcpy(( + *recplay_state)->u_sf_filename, DEF_SF_FILE); + } + } /* record player enabled */ + if (u_sf_replay == 1) *recplay_mode = RECPLAY_REPLAYMODE; + + if (u_sf_record == 1) *recplay_mode = RECPLAY_RECORDMODE; + + + return 0; + } \ No newline at end of file From ad28a3fe43617191066b4f5b88c106d9fa788dce Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Tue, 17 Dec 2019 10:10:18 +0100 Subject: [PATCH 082/134] using the old mechanism if having L1 and gNB on the same machine --- openair1/SCHED_NR/nr_ru_procedures.c | 224 ++++++++++++++++++--------- 1 file changed, 153 insertions(+), 71 deletions(-) diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 0ce3172bfd..7b1962ef5b 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -120,8 +120,8 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { int slot = tti_tx; int i = 0; - int j = 0; - int aa = 0; + int j = 0;//symbol + int aa = 0;//logical antenna number int ret = 0; int nb_antenna_ports = fp->N_ssb; int ofdm_mask_full = (1<<(ru->nb_tx*2))-1; @@ -133,67 +133,98 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { } start_meas(&ru->ofdm_total_stats); - - for(j=0; jsymbols_per_slot; ++j){ - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); - start_meas(&ru->txdataF_copy_stats); - if (ru->num_gNB == 1){ - gNB = ru->gNB_list[0]; - cfg = &gNB->gNB_config; - - for(i=0; icommon.txdataF[i][j*fp->ofdm_symbol_size], - (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], - fp->ofdm_symbol_size*sizeof(int32_t)); - } - - }//num_gNB == 1 - stop_meas(&ru->txdataF_copy_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); - - if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) { - // If this is not an S-tti + if(ru->num_gNB != 0){//L1 RU on same machine + for(j=0; j<2; ++j){//half slot for(i=0; inb_tx; ++i){ - if(j%2 == 0){ - while(feptx[i].instance_cnt_feptx != -1){ - usleep(5); - } + if(j == 0){ AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); feptx[i].aa = i; feptx[i].index = i; feptx[i].ru = ru; - feptx[i].symbol = j; + feptx[i].symbol = 0; feptx[i].slot = slot; feptx[i].nb_antenna_ports = nb_antenna_ports; feptx[i].instance_cnt_feptx = 0; AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); - } + }//first half else{ - while(feptx[i+ru->nb_tx].instance_cnt_feptx != -1){ - usleep(5); - } AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); feptx[i+ru->nb_tx].aa = i; feptx[i+ru->nb_tx].index = i+ru->nb_tx; feptx[i+ru->nb_tx].ru = ru; - feptx[i+ru->nb_tx].symbol = j; + feptx[i+ru->nb_tx].symbol = fp->symbols_per_tti>>1; feptx[i+ru->nb_tx].slot = slot; feptx[i+ru->nb_tx].nb_antenna_ports = nb_antenna_ports; feptx[i+ru->nb_tx].instance_cnt_feptx = 0; AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + }//second half + }//physical antenna + }//half slot + }//if L1 RU on same machine + else{//(RU only machine) + for(j=0; jsymbols_per_slot; ++j){ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); + start_meas(&ru->txdataF_copy_stats); + if (ru->num_gNB == 1){ + gNB = ru->gNB_list[0]; + cfg = &gNB->gNB_config; + + for(i=0; icommon.txdataF[i][j*fp->ofdm_symbol_size], + (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], + fp->ofdm_symbol_size*sizeof(int32_t)); + } + + }//num_gNB == 1 + stop_meas(&ru->txdataF_copy_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + + if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) { + // If this is not an S-tti + for(i=0; inb_tx; ++i){ + if(j%2 == 0){ + while(feptx[i].instance_cnt_feptx != -1){ + usleep(5); + } + AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i].aa = i; + feptx[i].index = i; + feptx[i].ru = ru; + feptx[i].symbol = j; + feptx[i].slot = slot; + feptx[i].nb_antenna_ports = nb_antenna_ports; + feptx[i].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + else{ + while(feptx[i+ru->nb_tx].instance_cnt_feptx != -1){ + usleep(5); + } + AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i+ru->nb_tx].aa = i; + feptx[i+ru->nb_tx].index = i+ru->nb_tx; + feptx[i+ru->nb_tx].ru = ru; + feptx[i+ru->nb_tx].symbol = j; + feptx[i+ru->nb_tx].slot = slot; + feptx[i+ru->nb_tx].nb_antenna_ports = nb_antenna_ports; + feptx[i+ru->nb_tx].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } } - } - }//if == SF_DL - else { - proc->feptx_mask = ofdm_mask_full; - } - }//jsymbols_per_slot + }//if == SF_DL + else { + proc->feptx_mask = ofdm_mask_full; + } + }//jsymbols_per_slot + }//else (RU only machine) // wait all process to finish AssertFatal((ret=pthread_mutex_lock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); @@ -219,9 +250,12 @@ static void *nr_feptx_thread(void *param) { RU_feptx_t *feptx = (RU_feptx_t *)param; RU_t *ru; int aa, slot, start, l, nb_antenna_ports, ret; + int i; int32_t ***bw; NR_DL_FRAME_PARMS *fp; int ofdm_mask_full; + int txdataF_offset; + int32_t *txdataF; while (!oai_exit) { @@ -239,22 +273,69 @@ static void *nr_feptx_thread(void *param) { nb_antenna_ports = feptx->nb_antenna_ports; ofdm_mask_full = (1<<(ru->nb_tx*2))-1; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); - start_meas(&ru->precoding_stats); - if (ru->nb_tx == 1) { - AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); - for (int p=0; pLmax; p++) { - if ((fp->L_ssb >> p) & 0x01){ - memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], - (void*)&ru->common.txdataF[p][l*fp->ofdm_symbol_size], - fp->ofdm_symbol_size*sizeof(int32_t)); + if(ru->num_gNB != 0){ + half_slot = feptx->half_slot; + txdataF_offset = ((slot%2)*fp->samples_per_slot_wCP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + start_meas(&ru->precoding_stats); + if (ru->nb_tx == 1) { + AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); + for (int p=0; pLmax; p++) { + if ((fp->L_ssb >> p) & 0x01){ + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], + (fp->symbols_per_tti>>1)*fp->ofdm_symbol_size*sizeof(int32_t)); + } } } - } - else { - bw = ru->beam_weights[0]; - nr_beam_precoding(ru->common.txdataF, + else { + bw = ru->beam_weights[0]; + txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset]; + for(i=0; isymbols_per_tti>>1; ++i){ + nr_beam_precoding(&txdataF, + ru->common.txdataF_BF, + fp, + bw, + slot, + l+i, + aa, + nb_antenna_ports); + } + } + stop_meas(&ru->precoding_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); + + + start_meas(&ru->ofdm_mod_stats); + nr_feptx0(ru,slot,start,fp->symbols_per_tti>>1,aa); + stop_meas(&ru->ofdm_mod_stats); + + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx->instance_cnt_feptx = -1; + ru->proc.feptx_mask |= 1<<(feptx->index); + if(ru->proc.feptx_mask == ofdm_mask_full) + AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); + AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); + }// if L1 RU on same machine + + else{ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + start_meas(&ru->precoding_stats); + if (ru->nb_tx == 1) { + AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); + for (int p=0; pLmax; p++) { + if ((fp->L_ssb >> p) & 0x01){ + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->common.txdataF[p][l*fp->ofdm_symbol_size], + fp->ofdm_symbol_size*sizeof(int32_t)); + } + } + } + else { + bw = ru->beam_weights[0]; + nr_beam_precoding(ru->common.txdataF, ru->common.txdataF_BF, fp, bw, @@ -262,27 +343,28 @@ static void *nr_feptx_thread(void *param) { l, aa, nb_antenna_ports); - } - stop_meas(&ru->precoding_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); + } + stop_meas(&ru->precoding_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); - start_meas(&ru->ofdm_mod_stats); - nr_feptx0(ru,slot,start,1,aa); - stop_meas(&ru->ofdm_mod_stats); + start_meas(&ru->ofdm_mod_stats); + nr_feptx0(ru,slot,start,1,aa); + stop_meas(&ru->ofdm_mod_stats); - if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; - if(l >= fp->symbols_per_slot -2){ - AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); - ru->proc.feptx_mask |= 1<<(feptx->index); - if(ru->proc.feptx_mask == ofdm_mask_full) - AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); - AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); + if(l >= fp->symbols_per_slot -2){ + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); + ru->proc.feptx_mask |= 1<<(feptx->index); + if(ru->proc.feptx_mask == ofdm_mask_full) + AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); + AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); + }// else (RU only machine) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 0 ); - } + }// while (oai_exit) return(NULL); } From e47b212ab63139edb9cad295756889b52a48eea9 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 17 Dec 2019 10:33:59 +0100 Subject: [PATCH 083/134] CI: adding RF simulator skeleton on 5G NR gNB and UE Signed-off-by: Raphael Defosseux --- ci-scripts/oai-ci-vm-tool | 6 +- ci-scripts/reportTestLocally.sh | 130 +++++++++++- ci-scripts/runTestOnVM.sh | 346 +++++++++++++++++++++++++++++--- 3 files changed, 446 insertions(+), 36 deletions(-) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index fb9dc9ad76..485c22902e 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -197,11 +197,15 @@ function variant__v4__cppcheck { } function variant__v5__gnb_usrp { + VM_MEMORY=8192 + VM_CPU=8 NB_PATTERN_FILES=9 BUILD_OPTIONS="--gNB -w USRP" } function variant__v6__nr_ue_usrp { + VM_MEMORY=4096 + VM_CPU=4 NB_PATTERN_FILES=9 BUILD_OPTIONS="--nrUE -w USRP" } @@ -234,8 +238,8 @@ function variant__v20__l1_sim { } function variant__v21__rf_sim { + ARCHIVES_LOC=rf_sim RUN_OPTIONS="complex" - EXPERIMENTAL="true" } function variant__v22__l2_sim { diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index dd0e6b819c..e087cc04e6 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -97,14 +97,20 @@ function analyzeIperfFiles { FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` if [ $FILE_COMPLETE -eq 0 ] then - echo " " >> ./test_simulator_results.html SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` - EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` + EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}else{printf "%.2f KBits/sec", br/1000}}'` PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` + if [[ $PERF_INT -lt 80 ]] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi else EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] @@ -394,6 +400,126 @@ function report_test { echo " " >> ./test_simulator_results.html fi + ARCHIVES_LOC=archives/rf_sim/test + if [ -d $ARCHIVES_LOC ] + then + echo "

5G NR RF Simulator Check

" >> ./test_simulator_results.html + + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] + then + echo "
" >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + else + echo "
" >> ./test_simulator_results.html + echo " TEST was a FAILURE! " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + fi + else + echo "
" >> ./test_simulator_results.html + echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + fi + + echo " " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + echo "
Relative Time (ms)Test IdTest DescTest Options
Final Tab StatusFinal Tab StatusPASS
' + format(currentTime / 1000, '.1f') + '' + self.testCase_id + '' + self.desc + '' + str(options) + '
' + format(currentTime / 1000, '.1f') + '' + self.testCase_id + '' + self.desc + '' + str(options) + ' KOKOOK
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + + EPC_CONFIGS=("noS1") + TRANS_MODES=("tdd") + BW_CASES=(106) + for CN_CONFIG in ${EPC_CONFIGS[@]} + do + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + echo " " >> ./test_simulator_results.html + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log + UE_LOG=`echo $ENB_LOG | sed -e "s#gnb#ue#"` + if [ -f $ENB_LOG ] && [ -f $UE_LOG ] + then + NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfuly configured" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "Initial sync: starting PBCH detection" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfuly configured" $UE_LOG` + if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + #PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null` + #analyzePingFiles + + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null` + analyzeIperfFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null` + #analyzeIperfFiles + done + done + done + + echo "
Log File NameCommandStatusStatistics
Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
+                    if [ $NB_ENB_GOT_SYNC -gt 0 ]
+                    then
+                        echo "- gNB --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- gNB NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_ENB_TUNNEL_UP -gt 0 ]
+                    then
+                        echo "- gNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                    else
+                        echo "- gNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_UE_GOT_SYNC -gt 0 ]
+                    then
+                        echo "- NR UE --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
+                    then
+                        echo "- NR UE attached to gNB" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE NEVER attached to eNB" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_UE_TUNNEL_UP -gt 0 ]
+                    then
+                        echo "- NR UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                    fi
+                    echo "        
" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + fi + ARCHIVES_LOC=archives/l2_sim/test if [ -d $ARCHIVES_LOC ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index ded67443bc..32a1652783 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -274,21 +274,30 @@ function generic_iperf { local LOC_BASE_LOG_FILE=$8 local LOC_PORT_ID=$[$9+5001] local LOC_FG_OR_BG=${10} + # By default the requested bandwidth is in Mbits/sec + if [[ $LOC_REQ_BANDWIDTH =~ .*K.* ]] + then + local IPERF_FORMAT="-fk" + local FORMATTED_REQ_BW=$LOC_REQ_BANDWIDTH + else + local IPERF_FORMAT="-fm" + local FORMATTED_REQ_BW=${LOC_REQ_BANDWIDTH}"M" + fi # Starting Iperf Server - echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID}" - echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} + echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 ${IPERF_FORMAT} -p ${LOC_PORT_ID}" + echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 ${IPERF_FORMAT} -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ISERVER_IP} < ${LOC_ISERVER_CMD} rm ${LOC_ISERVER_CMD} # Starting Iperf Client - echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" - echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" + echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} if [ $LOC_FG_OR_BG -eq 0 ] then - echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} echo "tail -3 ${LOC_BASE_LOG_FILE}_client.txt | grep -v datagram" >> ${LOC_ICLIENT_CMD} else - echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} + echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} fi ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ICLIENT_IP} < ${LOC_ICLIENT_CMD} rm -f ${LOC_ICLIENT_CMD} @@ -305,19 +314,46 @@ function generic_iperf { function check_iperf { local LOC_BASE_LOG=$1 - local LOC_REQ_BW=$2 + local LOC_REQ_BW=`echo $2 | sed -e "s#K##"` local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l` local LOC_REQ_BW_MINUS_THREE=`echo "$LOC_REQ_BW - 3" | bc -l` local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` + local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim` + local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` if [ $FILE_COMPLETE -eq 0 ] then - IPERF_STATUS=-1 - echo "File Report not found" + if [[ $LOC_IS_RF_SIM -eq 1 ]] && [[ $LOC_IS_NR -eq 1 ]] + then + echo "no UL integration right now --> normal to have no server report" + if [ -f ${LOC_BASE_LOG}_server.txt ] + then + local EFFECTIVE_BANDWIDTH=`tail -n1 ${LOC_BASE_LOG}_server.txt | sed -e "s#^.*MBytes *##" -e "s#^.*KBytes *##" -e "s#sec.*#sec#"` + if [[ $2 =~ .*K.* ]] + then + local BW_SUFFIX="K" + else + local BW_SUFFIX="M" + fi + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_SUFFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_SUFFIX}bits.* ]] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + echo "got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + IPERF_STATUS=-1 + fi + else + IPERF_STATUS=-1 + echo "Server File Report not found" + fi + else + IPERF_STATUS=-1 + echo "File Report not found" + fi else local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] @@ -351,40 +387,26 @@ function check_iperf { } function terminate_enb_ue_basic_sim { - # mode = 0 : eNB + UE - # mode = 1 : eNB - # mode = 2 : UE + # mode = 0 : eNB + UE or gNB and NR-UE + # mode = 1 : eNB or gNB + # mode = 2 : UE or NR-UE local LOC_MODE=$3 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" > $1 if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=enb_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=enb_daemon --stop; fi" >> $1 - fi - if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] - then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=ue_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=ue_daemon --stop; fi" >> $1 - fi - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 - echo "echo \"ps -aux | grep softmodem\"" >> $1 - echo "ps -aux | grep softmodem | grep -v grep" >> $1 - echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] - then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGINT lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGINT lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGINT .*-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGINT .*-softmodem; fi" >> $1 echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 echo "echo \"ps -aux | grep softmodem\"" >> $1 echo "ps -aux | grep softmodem | grep -v grep" >> $1 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGKILL .*-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGKILL .*-softmodem; fi" >> $1 fi if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-uesoftmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-uesoftmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGKILL .*-uesoftmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGKILL .*-uesoftmodem; fi" >> $1 echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 fi echo "echo \"ps -aux | grep softmodem\"" >> $1 @@ -1075,6 +1097,162 @@ function start_rf_sim_ue { } +function start_rf_sim_gnb { + local LOC_GNB_VM_IP_ADDR=$2 + local LOC_LOG_FILE=$3 + local LOC_NB_RBS=$4 + local LOC_CONF_FILE=$5 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$6 + echo "cd /home/ubuntu/tmp" > $1 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"source oaienv\"" >> $1 + echo "source oaienv" >> $1 + echo "cd ci-scripts/conf_files/" >> $1 + echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 + #echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + #echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 + #echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim\" > ./my-nr-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 + echo "cat ./my-nr-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=gnb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/ran_build/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-nr-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + GNB_SYNC=0 + echo "RF-SIM gNB is NOT sync'ed: process still alive?" + else + GNB_SYNC=1 + echo "RF-SIM gNB is sync'ed: waiting for UE(s) to connect" + fi + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 + # Checking oaitun_enb1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + sleep 5 + fi + done + rm $1 + if [ $i -lt 50 ] + then + GNB_SYNC=0 + echo "RF-SIM gNB oaitun_enb1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM gNB oaitun_enb1 is UP and CONFIGURED" + fi + fi + sleep 10 +} + +function start_rf_sim_nr_ue { + local LOC_NR_UE_VM_IP_ADDR=$2 + local LOC_GNB_VM_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_PRB=$5 + local LOC_FREQUENCY=$6 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$7 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --numerology 1 -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 + echo "cat ./my-nr-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=nr_ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/ran_build/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-nr-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"rfsimulator: Success\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + NR_UE_SYNC=1 + rm $1 + if [ $i -lt 50 ] + then + NR_UE_SYNC=0 + echo "RF-SIM NR-UE is NOT sync'ed w/ gNB" + return + else + echo "RF-SIM NR-UE is sync'ed w/ gNB" + fi + # Checking oaitun_ue1 interface has now an IP address + i="0" + echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + NR_UE_SYNC=0 + echo "RF-SIM NR-UE oaitun_ue1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM NR-UE oaitun_ue1 is UP and CONFIGURED" + fi + sleep 10 +} + + function run_test_on_vm { echo "############################################################" echo "OAI CI VM script" @@ -1089,6 +1267,14 @@ function run_test_on_vm { UE_VM_CMDS=${UE_VM_NAME}_cmds.txt echo "UE_VM_NAME = $UE_VM_NAME" echo "UE_VM_CMD_FILE = $UE_VM_CMDS" + GNB_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#gnb-usrp#" -e "s#rf-sim#gnb-usrp#"` + GNB_VM_CMDS=${GNB_VM_NAME}_cmds.txt + echo "GNB_VM_NAME = $GNB_VM_NAME" + echo "GNB_VM_CMD_FILE = $GNB_VM_CMDS" + NR_UE_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#nr-ue-usrp#" -e "s#rf-sim#nr-ue-usrp#"` + NR_UE_VM_CMDS=${UE_VM_NAME}_cmds.txt + echo "NR_UE_VM_NAME = $NR_UE_VM_NAME" + echo "NR_UE_VM_CMD_FILE = $NR_UE_VM_CMDS" else echo "VM_NAME = $VM_NAME" echo "VM_CMD_FILE = $VM_CMDS" @@ -1113,6 +1299,22 @@ function run_test_on_vm { UE_VM_IP_ADDR=`uvt-kvm ip $UE_VM_NAME` echo "$UE_VM_NAME has for IP addr = $UE_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for GNB VM to be started" + echo "############################################################" + uvt-kvm wait $GNB_VM_NAME --insecure + + GNB_VM_IP_ADDR=`uvt-kvm ip $GNB_VM_NAME` + echo "$GNB_VM_NAME has for IP addr = $GNB_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for NR-UE VM to be started" + echo "############################################################" + uvt-kvm wait $NR_UE_VM_NAME --insecure + + NR_UE_VM_IP_ADDR=`uvt-kvm ip $NR_UE_VM_NAME` + echo "$NR_UE_VM_NAME has for IP addr = $NR_UE_VM_IP_ADDR" else echo "############################################################" echo "Waiting for VM to be started" @@ -1466,7 +1668,7 @@ function run_test_on_vm { fi fi - if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-ru-sim.* ]] then PING_STATUS=0 IPERF_STATUS=0 @@ -1666,6 +1868,84 @@ function run_test_on_vm { fi fi + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + then + PING_STATUS=0 + IPERF_STATUS=0 + if [ -d $ARCHIVES_LOC ] + then + rm -Rf $ARCHIVES_LOC + fi + mkdir --parents $ARCHIVES_LOC + + CN_CONFIG="noS1" + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + S1_NOS1_CFG=0 + PRB=106 + FREQUENCY=3510 + + ######### start of loop + + echo "############################################################" + echo "${CN_CONFIG} : Starting the gNB" + echo "############################################################" + CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log + start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG + + echo "############################################################" + echo "${CN_CONFIG} : Starting the NR-UE" + echo "############################################################" + CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log + start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG + if [ $NR_UE_SYNC -eq 0 ] + then + echo "Problem w/ gNB and NR-UE not syncing" + terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 + terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + STATUS=-1 + return + fi + + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + THROUGHPUT="30K" + CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl + get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR + get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 + generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 + terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC + + ######### end of loop + full_l2_sim_destroy + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $STATUS -eq 0 ] + then + echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + fi + fi + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-l2-sim.* ]] then PING_STATUS=0 From 3f066dec562131e8f8f07bdc5ac1321702cb028a Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Tue, 17 Dec 2019 17:06:17 +0100 Subject: [PATCH 084/134] parameter fix --- openair1/SCHED_NR/nr_ru_procedures.c | 27 ++++++++++++++------------- targets/RT/USER/gNB_usrp.gtkw | 22 ++++++++++++---------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 7b1962ef5b..137454d6b5 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -134,6 +134,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { start_meas(&ru->ofdm_total_stats); if(ru->num_gNB != 0){//L1 RU on same machine + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); for(j=0; j<2; ++j){//half slot for(i=0; inb_tx; ++i){ if(j == 0){ @@ -153,7 +154,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { feptx[i+ru->nb_tx].aa = i; feptx[i+ru->nb_tx].index = i+ru->nb_tx; feptx[i+ru->nb_tx].ru = ru; - feptx[i+ru->nb_tx].symbol = fp->symbols_per_tti>>1; + feptx[i+ru->nb_tx].symbol = fp->symbols_per_slot>>1; feptx[i+ru->nb_tx].slot = slot; feptx[i+ru->nb_tx].nb_antenna_ports = nb_antenna_ports; feptx[i+ru->nb_tx].instance_cnt_feptx = 0; @@ -239,7 +240,6 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, proc->feptx_mask ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); - //write_output stop_meas(&ru->ofdm_total_stats); @@ -274,9 +274,9 @@ static void *nr_feptx_thread(void *param) { ofdm_mask_full = (1<<(ru->nb_tx*2))-1; if(ru->num_gNB != 0){ - half_slot = feptx->half_slot; txdataF_offset = ((slot%2)*fp->samples_per_slot_wCP); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + ////////////precoding//////////// + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); start_meas(&ru->precoding_stats); if (ru->nb_tx == 1) { AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); @@ -284,14 +284,14 @@ static void *nr_feptx_thread(void *param) { if ((fp->L_ssb >> p) & 0x01){ memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], - (fp->symbols_per_tti>>1)*fp->ofdm_symbol_size*sizeof(int32_t)); + (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); } } } else { bw = ru->beam_weights[0]; txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset]; - for(i=0; isymbols_per_tti>>1; ++i){ + for(i=0; isymbols_per_slot>>1; ++i){ nr_beam_precoding(&txdataF, ru->common.txdataF_BF, fp, @@ -303,15 +303,16 @@ static void *nr_feptx_thread(void *param) { } } stop_meas(&ru->precoding_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); + ////////////FEPTX//////////// start_meas(&ru->ofdm_mod_stats); - nr_feptx0(ru,slot,start,fp->symbols_per_tti>>1,aa); + nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa); stop_meas(&ru->ofdm_mod_stats); + if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); - feptx->instance_cnt_feptx = -1; ru->proc.feptx_mask |= 1<<(feptx->index); if(ru->proc.feptx_mask == ofdm_mask_full) AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); @@ -321,7 +322,7 @@ static void *nr_feptx_thread(void *param) { }// if L1 RU on same machine else{ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); start_meas(&ru->precoding_stats); if (ru->nb_tx == 1) { AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); @@ -345,7 +346,7 @@ static void *nr_feptx_thread(void *param) { nb_antenna_ports); } stop_meas(&ru->precoding_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); start_meas(&ru->ofdm_mod_stats); @@ -406,7 +407,7 @@ void nr_init_feptx_thread(RU_t *ru) { RU_feptx_t *feptx = proc->feptx; int i = 0; - for(i=0; i<16; i++){ + for(i=0; i<(ru->nb_tx*2); i++){ feptx[i].instance_cnt_feptx = -1; pthread_mutex_init( &feptx[i].mutex_feptx, NULL); diff --git a/targets/RT/USER/gNB_usrp.gtkw b/targets/RT/USER/gNB_usrp.gtkw index 416dd3b62b..e6726e7d9f 100644 --- a/targets/RT/USER/gNB_usrp.gtkw +++ b/targets/RT/USER/gNB_usrp.gtkw @@ -1,15 +1,15 @@ [*] -[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Fri Sep 6 15:01:30 2019 +[*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI +[*] Tue Dec 17 15:31:51 2019 [*] -[dumpfile] "/tmp/gNB_prec.vcd" -[dumpfile_mtime] "Fri Sep 6 14:59:50 2019" -[dumpfile_size] 13106022 -[savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" -[timestart] 2183320000 +[dumpfile] "/tmp/gNB.vcd" +[dumpfile_mtime] "Tue Dec 17 15:25:49 2019" +[dumpfile_size] 6343431 +[savefile] "/home/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" +[timestart] 1517712000 [size] 1920 1018 -[pos] -1 -1 -*-18.423141 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[pos] -9 -33 +*-19.276148 1518358451 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [sst_width] 386 [signals_width] 344 [sst_expanded] 1 @@ -60,9 +60,11 @@ functions.phy_procedures_ru_feprx0 functions.phy_procedures_ru_feprx1 functions.phy_procedures_ru_feptx_ofdm0 functions.phy_procedures_ru_feptx_ofdm1 +functions.phy_procedures_ru_feptx_ofdm2 functions.phy_procedures_ru_feptx_prec0 functions.phy_procedures_ru_feptx_prec1 -@23 +functions.phy_procedures_ru_feptx_prec2 +@22 variables.ru_tx_ofdm_mask[63:0] [pattern_trace] 1 [pattern_trace] 0 From c25c720fa5599582aab4bcff897122866da82cff Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 17 Dec 2019 17:29:17 +0100 Subject: [PATCH 085/134] hotfix for harq_pid --- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index d001141f37..244e29a243 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -278,7 +278,7 @@ int nr_dlsch_encoding(unsigned char *a, unsigned int G; unsigned int crc=1; - uint8_t harq_pid = dlsch->harq_ids[frame&2][slot]; + uint8_t harq_pid = dlsch->harq_ids[frame%2][slot]; AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid); nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; uint16_t nb_rb = rel15.n_prb; From 00fb1e95acbe35d689ff602ac6749ba3ac2c3484 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 17 Dec 2019 17:54:25 +0100 Subject: [PATCH 086/134] CI: forcing the workspace removal on caracal Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 18 +++++++++++++++++- ci-scripts/xml_files/gnb_usrp_build.xml | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index aaa7ede62a..35574512f1 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -128,6 +128,7 @@ class SSHConnection(): self.Build_eNB_args = '' self.backgroundBuild = False self.backgroundBuildTestId = ['', '', ''] + self.Build_eNB_forced_workspace_cleanup = False self.Initialize_eNB_args = '' self.air_interface = 'lte' self.eNB_instance = '' @@ -370,9 +371,16 @@ class SSHConnection(): self.air_interface = 'nr' else: self.air_interface = 'lte' + if self.Build_eNB_forced_workspace_cleanup: + self.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) + result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) + if result is not None: + full_ran_repo_name = self.ranRepository + else: + full_ran_repo_name = self.ranRepository + '.git' self.command('mkdir -p ' + lSourcePath, '\$', 5) self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # Raphael: here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) @@ -4158,6 +4166,14 @@ def CheckClassValidity(action,id): def GetParametersFromXML(action): if action == 'Build_eNB': SSH.Build_eNB_args = test.findtext('Build_eNB_args') + forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') + if (forced_workspace_cleanup is None): + SSH.Build_eNB_forced_workspace_cleanup = False + else: + if re.match('true', forced_workspace_cleanup, re.IGNORECASE): + SSH.Build_eNB_forced_workspace_cleanup = True + else: + SSH.Build_eNB_forced_workspace_cleanup = False SSH.eNB_instance = test.findtext('eNB_instance') if (SSH.eNB_instance is None): SSH.eNB_instance = '0' diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml index 1b57c077ba..bba92930c5 100644 --- a/ci-scripts/xml_files/gnb_usrp_build.xml +++ b/ci-scripts/xml_files/gnb_usrp_build.xml @@ -34,6 +34,7 @@ Build_eNB Build gNB (USRP) --gNB -w USRP + True
From 3e7ac8256e89ab078ed42e955f19248531677b9a Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Javier Morgade" Date: Tue, 17 Dec 2019 22:15:11 +0100 Subject: [PATCH 087/134] Just triggering CI to check HO scenario --- README.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/README.txt b/README.txt index 59f48445e2..bd96404ec6 100644 --- a/README.txt +++ b/README.txt @@ -93,3 +93,4 @@ v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the li v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU v0.1 -> Last stable commit on develop branch before enhancement-10-harmony + From e75a96c934e7e1506d279af0c0808e813945e6e8 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Fri, 30 Aug 2019 19:27:16 +0200 Subject: [PATCH 088/134] start_symbol has to be 0 as PUSCH mapping type A is used --- executables/nr-ue.c | 4 ++-- openair1/PHY/INIT/nr_init.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 24288d76d3..c6f237e300 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -382,8 +382,8 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { n_rnti = 0x1234; nb_rb = 50; start_rb = 0; - nb_symb_sch = 12; - start_symbol = 2; + nb_symb_sch = 14; + start_symbol = 0; precod_nbr_layers = 1; mcs = 9; harq_pid = 0; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index c8df496423..30895bff19 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -507,8 +507,8 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { rel15_ul->rnti = 0x1234; rel15_ul->ulsch_pdu_rel15.start_rb = 0; rel15_ul->ulsch_pdu_rel15.number_rbs = 50; - rel15_ul->ulsch_pdu_rel15.start_symbol = 2; - rel15_ul->ulsch_pdu_rel15.number_symbols = 12; + rel15_ul->ulsch_pdu_rel15.start_symbol = 0; + rel15_ul->ulsch_pdu_rel15.number_symbols = 14; rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; rel15_ul->ulsch_pdu_rel15.Qm = 2; From bf2477276614c5f1933443c59f5f98531f4222d6 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Fri, 6 Sep 2019 19:11:33 +0200 Subject: [PATCH 089/134] PUSCH DMRS generation - added get_l_prime function - added Table 6.4.1.1.3-3 - added added is_dmrs_symbol function --- openair1/PHY/NR_REFSIG/dmrs_nr.h | 13 +++ openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c | 6 -- openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h | 7 +- openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c | 118 +++++++++++++++++++++ openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 17 ++- openair1/PHY/impl_defs_nr.h | 1 + 6 files changed, 153 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 5c4f218512..45c1f275b3 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -57,6 +57,19 @@ void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_H uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos); + +uint8_t is_dmrs_symbol(uint8_t l, + uint16_t k, + uint16_t start_sc, + uint8_t k_prime, + uint16_t n, + uint8_t delta, + uint8_t duration_in_symbols, + dmrs_UplinkConfig_t *dmrs_UplinkConfig, + uint8_t mapping_type, + uint16_t ofdm_symbol_size); + #undef EXTERN #endif /* DMRS_NR_H */ diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index 303282929f..63922c8c65 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -32,7 +32,6 @@ #include "nr_sch_dmrs.h" - /*Table 7.4.1.1.2-1 and 7.4.1.1.2-2 38211 Columns: ap - CDM group - Delta - Wf(0) - Wf(1) - Wt(0) - Wt(1)*/ /*Table 6.4.1.1.3-1 is identical to Table 7.4.1.1.2-1 and Table 6.4.1.1.3-2 is identical to Table 7.4.1.1.2-2. UL DMRS can reuse these tables*/ int8_t pdsch_dmrs_1[8][7] = {{0,0,0,1,1,1,1}, @@ -57,11 +56,6 @@ int8_t pdsch_dmrs_2[12][7] = {{0,0,0,1,1,1,1}, {10,2,4,1,1,1,-1}, {11,2,4,1,-1,1,-1}}; -void get_l_prime(uint8_t *l_prime, uint8_t n_symbs) { - for (int i=0; i0,"invalid l_prime < 0\n"); + + return l_prime; +} + +/******************************************************************* +* +* NAME : is_dmrs_symbol +* +* PARAMETERS : l ofdm symbol index within slot +* k subcarrier index +* start_sc first subcarrier index +* k_prime index alternating 0 and 1 +* n index starting 0,1,... +* delta see Table 6.4.1.1.3 +* duration_in_symbols number of scheduled PUSCH ofdm symbols +* dmrs_UplinkConfig DMRS uplink configuration +* mapping_type PUSCH mapping type (A or B) +* ofdm_symbol_size IFFT size +* +* RETURN : 0 if symbol(k,l) is data, or 1 if symbol(k,l) is dmrs +* +* DESCRIPTION : 3GPP TS 38.211 6.4.1.1 Demodulation reference signal for PUSCH +* +*********************************************************************/ + +uint8_t is_dmrs_symbol(uint8_t l, + uint16_t k, + uint16_t start_sc, + uint8_t k_prime, + uint16_t n, + uint8_t delta, + uint8_t duration_in_symbols, + dmrs_UplinkConfig_t *dmrs_UplinkConfig, + uint8_t mapping_type, + uint16_t ofdm_symbol_size) { + + uint8_t is_dmrs_freq, is_dmrs_time, dmrs_type, l0; + int32_t l_prime_mask; + pusch_dmrs_AdditionalPosition_t additional_pos; + + is_dmrs_freq = 0; + is_dmrs_time = 0; + dmrs_type = dmrs_UplinkConfig->pusch_dmrs_type; + additional_pos = dmrs_UplinkConfig->pusch_dmrs_AdditionalPosition; + + + l0 = get_l0_ul(mapping_type, 2); + l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos); + + if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%ofdm_symbol_size)) + is_dmrs_freq = 1; + + + if (l_prime_mask == 1){ + + if (l == l0) + is_dmrs_time = 1; + + } else if ( (l==l0) || (((l_prime_mask>>l)&1) == 1 && l!=0) ) + is_dmrs_time = 1; + + if (dmrs_UplinkConfig->pusch_maxLength == pusch_len2){ + + if (((l_prime_mask>>(l-1))&1) == 1 && l!=0 && l!=1) + is_dmrs_time = 1; + + if (l-1 == l0) + is_dmrs_time = 1; + + } + + if (is_dmrs_time && is_dmrs_freq) + return 1; + else + return 0; + +} + /******************************************************************* * * NAME : pseudo_random_gold_sequence diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index d2dbd6fef2..cdea8f58be 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -287,17 +287,32 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t k_prime=0; + uint8_t is_dmrs; uint16_t m=0, n=0, dmrs_idx=0, k=0; for (l=start_symbol; lnumber_of_symbols; l++) { k = start_sc; + n = 0; for (i=0; inb_rb*NR_NB_SC_PER_RB; i++) { sample_offsetF = l*frame_parms->ofdm_symbol_size + k; - if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) { + is_dmrs = 0; + + is_dmrs = is_dmrs_symbol(l, + k, + start_sc, + k_prime, + n, + delta, + harq_process_ul_ue->number_of_symbols, + &UE->dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); + + if (is_dmrs == 1) { ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 05e14f5e8d..43333857d6 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -537,6 +537,7 @@ typedef enum { typedef enum { pusch_dmrs_pos0 = 0, pusch_dmrs_pos1 = 1, + pusch_dmrs_pos2 = 2, pusch_dmrs_pos3 = 3, } pusch_dmrs_AdditionalPosition_t; typedef enum { From ccc515c537ccd7ef4014ac8a92fb6cbc94125c9d Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Thu, 12 Sep 2019 14:49:02 +0200 Subject: [PATCH 090/134] PUSCH Rx channel estimation supporting DMRS type 1 and mapping type B --- cmake_targets/CMakeLists.txt | 3 +- .../nfapi/public_inc/nfapi_nr_interface.h | 1 - openair1/PHY/INIT/nr_init.c | 19 +- openair1/PHY/INIT/nr_init_ue.c | 4 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- .../{NR_UE_TRANSPORT => NR_REFSIG}/dmrs_nr.c | 0 openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c | 3 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 7 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 250 ++++++++++-------- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 32 ++- openair1/PHY/defs_gNB.h | 11 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 21 +- 14 files changed, 220 insertions(+), 137 deletions(-) rename openair1/PHY/{NR_UE_TRANSPORT => NR_REFSIG}/dmrs_nr.c (100%) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a0620d8345..1978995dae 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1334,6 +1334,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c @@ -1362,7 +1363,6 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pss_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c - ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dmrs_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -1380,6 +1380,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index e85caf7690..a6cb7262a4 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -690,7 +690,6 @@ typedef struct { uint8_t frame_offset; uint16_t number_symbols; uint16_t start_symbol; - uint8_t nb_re_dmrs; uint8_t length_dmrs; nr_pusch_freq_hopping_t pusch_freq_hopping; uint8_t mcs; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 30895bff19..920b0f5df4 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -153,13 +153,25 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } + //------------- config PUSCH DMRS parameters(to be updated from RRC)--------------// + gNB->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1; + gNB->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos3; + gNB->dmrs_UplinkConfig.pusch_maxLength = pusch_len1; + //--------------------------------------------------------------------------------// + nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); + // default values until overwritten by RRCConnectionReconfiguration + + for (i=0;ipusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t)); + gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB; + } + /// Transport init necessary for NR synchro init_nr_transport(gNB); - gNB->first_run_I0_measurements = - 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. + gNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. common_vars->rxdata = (int32_t **)malloc16(15*sizeof(int32_t*)); common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); @@ -509,8 +521,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { rel15_ul->ulsch_pdu_rel15.number_rbs = 50; rel15_ul->ulsch_pdu_rel15.start_symbol = 0; rel15_ul->ulsch_pdu_rel15.number_symbols = 14; - rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; - rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; + rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength; rel15_ul->ulsch_pdu_rel15.Qm = 2; rel15_ul->ulsch_pdu_rel15.R = 679; rel15_ul->ulsch_pdu_rel15.mcs = 9; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 0c7ce1cdd6..b4a4bee4ef 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -700,12 +700,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, for (i=0; ipusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t)); - ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeA; + ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB; } //------------- config DMRS parameters--------------// ue->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1; - ue->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; + ue->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos3; ue->dmrs_UplinkConfig.pusch_maxLength = pusch_len1; //-------------------------------------------------// ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 16fc94a59f..9c061f5872 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -111,7 +111,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - length_dmrs = 1; //to update from pusch config + length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength; nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs); diff --git a/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c similarity index 100% rename from openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c rename to openair1/PHY/NR_REFSIG/dmrs_nr.c diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 859e59d055..9736e97e34 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -338,8 +338,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size; rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index; rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols; - rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; //where should this come from? - rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; //where should this come from? + rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength; rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order; rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index; rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 8d220a76bb..d74db96e4e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -62,6 +62,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, @param start_rb The starting RB in the RB allocation (used for Resource Allocation Type 1 in NR) @param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR) @param frame_parms, Pointer to frame descriptor structure + @param is_dmrs_symbol, flag to indicate wether this OFDM symbol contains DMRS symbols or not. */ void nr_ulsch_extract_rbs_single(int **rxdataF, @@ -73,7 +74,9 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned char symbol, unsigned short start_rb, unsigned short nb_rb_pusch, - NR_DL_FRAME_PARMS *frame_parms); + NR_DL_FRAME_PARMS *frame_parms, + uint8_t is_dmrs_symbol, + uint8_t dmrs_symbol); void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, @@ -118,7 +121,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, int **rho, NR_DL_FRAME_PARMS *frame_parms, unsigned char symbol, - uint8_t pilots, + uint8_t is_dmrs_symbol, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index db0c601b25..eb2b3c7c7c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -323,7 +323,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint16_t R = nfapi_ulsch_pdu_rel15->R; uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs; uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers; - uint8_t nb_re_dmrs = nfapi_ulsch_pdu_rel15->nb_re_dmrs; + uint16_t nb_re_dmrs = harq_process->nb_re_dmrs; uint8_t length_dmrs = nfapi_ulsch_pdu_rel15->length_dmrs; // ------------------------------------------------------------------ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index b961b592d5..f74c32e0c7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -3,6 +3,7 @@ #include "nr_transport_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "PHY/defs_nr_common.h" @@ -229,10 +230,12 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned char symbol, unsigned short start_rb, unsigned short nb_rb_pusch, - NR_DL_FRAME_PARMS *frame_parms) + NR_DL_FRAME_PARMS *frame_parms, + uint8_t is_dmrs_symbol, + uint8_t dmrs_symbol) { unsigned short start_re, re, nb_re_pusch; - unsigned char aarx, is_dmrs_symbol = 0; + unsigned char aarx; uint32_t rxF_ext_index = 0; uint32_t ul_ch0_ext_index = 0; uint32_t ul_ch0_index = 0; @@ -242,12 +245,10 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, #ifdef DEBUG_RB_EXT - printf("--------------------symbol = %d-----------------------\n", symbol); + printf("--------------------symbol = %d, is_dmrs_symbol = %u-----------------------\n", symbol, is_dmrs_symbol); printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch); #endif - - is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; @@ -258,7 +259,8 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 - ul_ch0 = &ul_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; // DMRS REs are only in symbol 2 (to be updated from config) + ul_ch0 = &ul_ch_estimates[aarx][dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available + ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch]; for (re = 0; re < nb_re_pusch; re++) { @@ -269,17 +271,18 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; + ul_ch0_ext_index++; + rxF_ext_index = rxF_ext_index + 2; + } + + ul_ch0_index++; + #ifdef DEBUG_RB_EXT printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]); printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]); - printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index]); - printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index + 1]); + printf("ul_ch0_ext[%d] = %d\n", 2*rxF_ext_index, ((int16_t *)ul_ch0_ext)[2*rxF_ext_index]); + printf("ul_ch0_ext[%d] = %d\n", 2*rxF_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*rxF_ext_index + 1]); #endif - - rxF_ext_index = rxF_ext_index + 2; - ul_ch0_ext_index++; - } - ul_ch0_index++; } } } @@ -288,7 +291,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_gNB_ULSCH_t **ulsch_gNB, uint8_t symbol, - uint8_t pilots, + uint8_t is_dmrs_symbol, unsigned short nb_rb) { @@ -302,7 +305,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a)); - LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, pilots, nb_rb, frame_parms->Ncp, symbol); + LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, is_dmrs_symbol, nb_rb, frame_parms->Ncp, symbol); // printf("Scaling PUSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 @@ -312,7 +315,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB]; - if (pilots==1){ + if (is_dmrs_symbol==1){ nb_rb = nb_rb>>1; } @@ -325,7 +328,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, ul_ch128[1] = _mm_mulhi_epi16(ul_ch128[1], ch_amp128); ul_ch128[1] = _mm_slli_epi16(ul_ch128[1], 3); - if (pilots) { + if (is_dmrs_symbol) { ul_ch128+=2; } else { ul_ch128[2] = _mm_mulhi_epi16(ul_ch128[2], ch_amp128); @@ -446,7 +449,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, int **rho, NR_DL_FRAME_PARMS *frame_parms, unsigned char symbol, - uint8_t pilots, + uint8_t is_dmrs_symbol, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift) @@ -549,7 +552,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); - if (pilots==0) { + if (is_dmrs_symbol==0) { mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); @@ -568,7 +571,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); - if (pilots==0) { + if (is_dmrs_symbol==0) { ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); } @@ -616,7 +619,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, // print_shorts("ch:",ul_ch128+1); // print_shorts("pack:",rxdataF_comp128+1); - if (pilots==0) { + if (is_dmrs_symbol==0) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -738,7 +741,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, unsigned short rb; - unsigned char aatx,aarx,symbol_mod,pilots=0; + unsigned char aatx,aarx,symbol_mod,is_dmrs_symbol=0; int16x4_t *ul_ch128,*ul_ch128_2,*rxdataF128; int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; @@ -756,7 +759,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, nb_rb=1+(5*nb_rb/6); } else { - pilots=1; + is_dmrs_symbol=1; } } @@ -793,7 +796,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = vmull_s16(ul_ch128[3], ul_ch128[3]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { + if (is_dmrs_symbol==0) { mmtmpD0 = vmull_s16(ul_ch128[4], ul_ch128[4]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(ul_ch128[5], ul_ch128[5]); @@ -806,7 +809,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); ul_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); - if (pilots==0) { + if (is_dmrs_symbol==0) { ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); ul_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); } @@ -843,7 +846,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { + if (is_dmrs_symbol==0) { mmtmpD0 = vmull_s16(ul_ch128[4], rxdataF128[4]); mmtmpD1 = vmull_s16(ul_ch128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), @@ -971,114 +974,135 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, unsigned char harq_pid) { - uint8_t first_symbol_flag, aarx, aatx, pilots; // pilots, a flag to indicate DMRS REs in current symbol + uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; uint32_t nb_re_pusch, bwp_start_subcarrier; + uint8_t mapping_type; int avgs; int avg[4]; - pilots = 0; + dmrs_symbol_flag = 0; first_symbol_flag = 0; - - if(symbol == rel15_ul->start_symbol){ - gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; - first_symbol_flag = 1; - } + mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; - if (symbol == rel15_ul->start_symbol){ // [hna] here it is assumed that first carries 6 DMRS REs (dmrs-type 1) - nb_re_pusch = rel15_ul->number_rbs * 6; - pilots = 1; - } else { - nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; - pilots = 0; - } + if (mapping_type == typeB) { - bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; + if(symbol == rel15_ul->start_symbol){ + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; + gNB->pusch_vars[UE_id]->dmrs_symbol = 0; + first_symbol_flag = 1; + } - //---------------------------------------------------------- - //--------------------- Channel estimation --------------------- - //---------------------------------------------------------- + bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; - if (pilots == 1) - nr_pusch_channel_estimation(gNB, - 0, - nr_tti_rx, - 0, // p - symbol, - bwp_start_subcarrier, - rel15_ul->number_rbs); + dmrs_symbol_flag = is_dmrs_symbol(symbol, + 0, + 0, + 0, + 0, + 0, + rel15_ul->number_symbols, + &gNB->dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); - //---------------------------------------------------------- - //--------------------- RBs extraction --------------------- - //---------------------------------------------------------- - - nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, - gNB->pusch_vars[UE_id]->ul_ch_estimates, - gNB->pusch_vars[UE_id]->rxdataF_ext, - gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - gNB->pusch_vars[UE_id]->rxdataF_ext_offset, - // rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment - symbol, - rel15_ul->start_rb, - rel15_ul->number_rbs, - frame_parms); + if (dmrs_symbol_flag == 1){ + nb_re_pusch = rel15_ul->number_rbs * 6; + gNB->pusch_vars[UE_id]->dmrs_symbol = symbol; + } else { + nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; + } - nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - frame_parms, - gNB->ulsch[UE_id], - symbol, - pilots, - rel15_ul->number_rbs); - if (first_symbol_flag==1) { + //---------------------------------------------------------- + //--------------------- Channel estimation --------------------- + //---------------------------------------------------------- - nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - frame_parms, - avg, - symbol, - nb_re_pusch, - rel15_ul->number_rbs); - avgs = 0; + if (dmrs_symbol_flag == 1) + nr_pusch_channel_estimation(gNB, + 0, + nr_tti_rx, + 0, // p + symbol, + bwp_start_subcarrier, + rel15_ul->number_rbs); - for (aatx=0;aatxnb_antennas_tx;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + //---------------------------------------------------------- + //--------------------- RBs extraction --------------------- + //---------------------------------------------------------- - gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1; - - } - - nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext, + nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, + gNB->pusch_vars[UE_id]->ul_ch_estimates, + gNB->pusch_vars[UE_id]->rxdataF_ext, gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - gNB->pusch_vars[UE_id]->ul_ch_mag0, - gNB->pusch_vars[UE_id]->ul_ch_magb0, - gNB->pusch_vars[UE_id]->rxdataF_comp, - (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL, - frame_parms, + gNB->pusch_vars[UE_id]->rxdataF_ext_offset, + // rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment symbol, - pilots, - rel15_ul->Qm, + rel15_ul->start_rb, rel15_ul->number_rbs, - gNB->pusch_vars[UE_id]->log2_maxh); + frame_parms, + dmrs_symbol_flag, + gNB->pusch_vars[UE_id]->dmrs_symbol); -#ifdef NR_SC_FDMA - nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch); -#endif + nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + gNB->ulsch[UE_id], + symbol, + dmrs_symbol_flag, + rel15_ul->number_rbs); - //---------------------------------------------------------- - //-------------------- LLRs computation -------------------- - //---------------------------------------------------------- - - nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], - gNB->pusch_vars[UE_id]->ul_ch_mag0, - gNB->pusch_vars[UE_id]->ul_ch_magb0, - &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm], - rel15_ul->number_rbs, - nb_re_pusch, - symbol, - rel15_ul->Qm); - - gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch; + if (first_symbol_flag==1) { + + nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_re_pusch, + rel15_ul->number_rbs); + avgs = 0; + + for (aatx=0;aatxnb_antennas_tx;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + + gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1; + + } + + nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext, + gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, + gNB->pusch_vars[UE_id]->rxdataF_comp, + (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL, + frame_parms, + symbol, + dmrs_symbol_flag, + rel15_ul->Qm, + rel15_ul->number_rbs, + gNB->pusch_vars[UE_id]->log2_maxh); + + #ifdef NR_SC_FDMA + nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch); + #endif + + //---------------------------------------------------------- + //-------------------- LLRs computation -------------------- + //---------------------------------------------------------- + + nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, + &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm], + rel15_ul->number_rbs, + nb_re_pusch, + symbol, + rel15_ul->Qm); + + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch; + } else { + LOG_E(PHY, "PUSCH mapping type A is not supported \n"); + } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index cbe0a816ff..4f23e4d703 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -232,7 +232,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Ilbrm = 0; Tbslbrm = 950984; //max tbs nb_re_dmrs = ulsch->nb_re_dmrs; - length_dmrs = 1; + length_dmrs = ulsch->length_dmrs; Coderate = 0.0; /////////// diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index cdea8f58be..5a83ab7efc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -98,8 +98,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int32_t **txdataF; uint16_t start_sc, start_rb; int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - uint16_t n_dmrs,code_rate; - uint8_t dmrs_type, length_dmrs; + uint16_t n_dmrs, code_rate, number_dmrs_symbols; + uint8_t dmrs_type; uint8_t mapping_type; int ap, start_symbol, Nid_cell, i; int sample_offsetF, N_RE_prime, N_PRB_oh; @@ -111,20 +111,36 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; num_of_codewords = 1; // tmp assumption - length_dmrs = 1; n_rnti = 0x1234; Nid_cell = 0; N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig + number_dmrs_symbols = 0; + + mapping_type = UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) { ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index]; harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; - ulsch_ue->length_dmrs = length_dmrs; + for (i = 0; i < NR_SYMBOLS_PER_SLOT; i++) + number_dmrs_symbols += is_dmrs_symbol(i, + 0, + 0, + 0, + 0, + 0, + harq_process_ul_ue->number_of_symbols, + &UE->dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); + + printf("number_dmrs_symbols = %u\n", number_dmrs_symbols); + + ulsch_ue->length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength; ulsch_ue->rnti = n_rnti; ulsch_ue->Nid_cell = Nid_cell; - ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4); + ulsch_ue->nb_re_dmrs = ((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs - N_PRB_oh; @@ -213,11 +229,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs); int16_t mod_dmrs[n_dmrs<<1]; dmrs_type = UE->dmrs_UplinkConfig.pusch_dmrs_type; - mapping_type = UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; l0 = get_l0_ul(mapping_type, 2); - nr_modulation(pusch_dmrs[l0][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated - /////////// //////////////////////////////////////////////////////////////////////// @@ -294,6 +307,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, k = start_sc; n = 0; + dmrs_idx = 0; for (i=0; inb_rb*NR_NB_SC_PER_RB; i++) { @@ -314,6 +328,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { + nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3746af85aa..6e5382add6 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -246,6 +246,8 @@ typedef struct { /// This is needed for PHICH generation which /// is done after a new scheduling uint8_t previous_n_DMRS; + /// number of DMRS resource elements in one RB + uint16_t nb_re_dmrs; ////////////////////////////////////////////////////////////// @@ -414,6 +416,8 @@ typedef struct { /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; + // DMRS symbol index, to be updated every DMRS symbol within a slot. + uint8_t dmrs_symbol; } NR_gNB_PUSCH; @@ -707,6 +711,8 @@ typedef struct PHY_VARS_gNB_s { // PUSCH Varaibles PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_UE_MAX]; + PUSCH_Config_t pusch_config; + // PUCCH variables PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_UE_MAX]; @@ -722,6 +728,11 @@ typedef struct PHY_VARS_gNB_s { // SRS Variables SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX]; + + dmrs_UplinkConfig_t dmrs_UplinkConfig; + + dmrs_DownlinkConfig_t dmrs_DownlinkConfig; + uint8_t ncs_cell[20][7]; // Scheduling Request Config diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a665a14112..3652801bc3 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -224,12 +224,31 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &rel15_ul->ulsch_pdu_rel15; uint8_t ret; + uint8_t l, number_dmrs_symbols = 0; + uint8_t mapping_type; uint32_t G; int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled) + mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; + gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->nb_re_dmrs = 0; + + for (l = 0; l < NR_SYMBOLS_PER_SLOT; l++) + number_dmrs_symbols += is_dmrs_symbol(l, + 0, + 0, + 0, + 0, + 0, + nfapi_ulsch_pdu_rel15->number_symbols, + &gNB->dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); + + gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; + G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, nfapi_ulsch_pdu_rel15->number_symbols, - nfapi_ulsch_pdu_rel15->nb_re_dmrs, + gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->nb_re_dmrs, nfapi_ulsch_pdu_rel15->length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers); From 935c2ce7cea4170e9c873e2459fe37562d8dfe68 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Mon, 16 Sep 2019 18:51:16 +0200 Subject: [PATCH 091/134] Adding table 6.4.1.1.3-4 for double DMRS symbol --- openair1/PHY/INIT/nr_init.c | 2 +- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair1/PHY/NR_REFSIG/dmrs_nr.c | 29 +++++++++++++++++++--- openair1/PHY/NR_REFSIG/dmrs_nr.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 ++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 920b0f5df4..f0ad3cbaae 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -155,7 +155,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, //------------- config PUSCH DMRS parameters(to be updated from RRC)--------------// gNB->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1; - gNB->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos3; + gNB->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; gNB->dmrs_UplinkConfig.pusch_maxLength = pusch_len1; //--------------------------------------------------------------------------------// diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index b4a4bee4ef..d2046596c6 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -705,7 +705,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, //------------- config DMRS parameters--------------// ue->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1; - ue->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos3; + ue->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; ue->dmrs_UplinkConfig.pusch_maxLength = pusch_len1; //-------------------------------------------------// ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index cd6667bb60..67118f35a9 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -55,7 +55,27 @@ int32_t table_6_4_1_1_3_3_pusch_dmrs_positions_l [12][8] = { {1, 2049, 2177, 2337, 1, 1025, 1057, 585}, //14 // (DMRS l' position) }; -int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos) { + +// TS 38.211 Table 6.4.1.1.3-4: PUSCH DMRS positions l' within a slot for double-symbol DMRS and intra-slot frequency hopping disabled. +// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B. +// When l' = l0, it is represented by 1 + +int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { // Duration in symbols +{-1, -1, -1, -1, -1, -1, -1, -1}, //<4 // (DMRS l' position) +{1, 1, -1, -1, -1, -1, -1, -1}, //4 // (DMRS l' position) +{1, 1, -1, -1, 1, 1, -1, -1}, //5 // (DMRS l' position) +{1, 1, -1, -1, 1, 1, -1, -1}, //6 // (DMRS l' position) +{1, 1, -1, -1, 1, 1, -1, -1}, //7 // (DMRS l' position) +{1, 1, -1, -1, 1, 33, -1, -1}, //8 // (DMRS l' position) +{1, 1, -1, -1, 1, 33, -1, -1}, //9 // (DMRS l' position) +{1, 257, -1, -1, 1, 129, -1, -1}, //10 // (DMRS l' position) +{1, 257, -1, -1, 1, 129, -1, -1}, //11 // (DMRS l' position) +{1, 257, -1, -1, 1, 513, -1, -1}, //12 // (DMRS l' position) +{1, 1025, -1, -1, 1, 513, -1, -1}, //13 // (DMRS l' position) +{1, 1025, -1, -1, 1, 513, -1, -1}, //14 // (DMRS l' position) +}; + +int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength) { uint8_t row, colomn; int32_t l_prime; @@ -70,7 +90,10 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr else row = duration_in_symbols - 3; - l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn]; + if (pusch_maxLength == pusch_len1) + l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn]; + else + l_prime = table_6_4_1_1_3_4_pusch_dmrs_positions_l[row][colomn]; AssertFatal(l_prime>0,"invalid l_prime < 0\n"); @@ -120,7 +143,7 @@ uint8_t is_dmrs_symbol(uint8_t l, l0 = get_l0_ul(mapping_type, 2); - l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos); + l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos, dmrs_UplinkConfig->pusch_maxLength); if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%ofdm_symbol_size)) is_dmrs_freq = 1; diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 45c1f275b3..de77a8a6ce 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -57,7 +57,7 @@ void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_H uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); -int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos); +int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength); uint8_t is_dmrs_symbol(uint8_t l, uint16_t k, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 5a83ab7efc..e1e44e137f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -328,6 +328,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { + printf("DMRS l = %u\n", l); + nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; From 23ade3ada6383fc48e652ee62e3b797c962650f2 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Mon, 23 Sep 2019 18:25:18 +0200 Subject: [PATCH 092/134] PUSCH Rx channel estimation supporting DMRS type 2 - nr_ulsim supports multiple DMRS configurations --- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 235 ++++--- openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 3 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 21 +- openair1/PHY/NR_REFSIG/nr_refsig.h | 3 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 9 +- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 91 ++- openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c | 12 + openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h | 11 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 26 +- openair1/PHY/TOOLS/cmult_sv.c | 26 + openair1/PHY/TOOLS/tools_defs.h | 4 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 1 + openair1/SIMULATION/NR_PHY/ulschsim.c | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 36 +- ubl | 575 ++++++++++++++++++ 15 files changed, 922 insertions(+), 132 deletions(-) create mode 100644 ubl diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 9c061f5872..e1055e3e24 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -23,6 +23,7 @@ #include #include "nr_ul_estimation.h" +#include "PHY/sse_intrin.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" @@ -35,18 +36,19 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned short p, unsigned char symbol, unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pusch) + unsigned short nb_rb_pusch, + dmrs_UplinkConfig_t *dmrs_UplinkConfig) { int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; - unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*ul_ch; + unsigned int pilot_cnt,re_cnt; + int16_t ch[2],ch_r[2],ch_l[2],*pil,*rxF,*ul_ch; int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset, length_dmrs, UE_id = 0; unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config - int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(32))); int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time; + __m128i *ul_ch_128; #ifdef DEBUG_CH FILE *debug_ch_est; @@ -115,17 +117,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs); - nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch); + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch, dmrs_UplinkConfig->pusch_dmrs_type); //------------------------------------------------// for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; - ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + pil = (int16_t *)&pilot[0]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; - memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); + memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); #ifdef DEBUG_PUSCH printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL); @@ -135,6 +137,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif //if ((gNB->frame_parms.N_RB_UL&1)==0) { + + if (dmrs_UplinkConfig->pusch_dmrs_type == pusch_dmrs_type1){ + // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); @@ -144,6 +149,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]); #endif + multadd_real_vector_complex_scalar(fl, ch, ul_ch, @@ -192,28 +198,33 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_CH - fprintf(debug_ch_est, "pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); - //printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fm, + + #ifdef DEBUG_PUSCH + printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + #endif + multadd_real_vector_complex_scalar(fml, ch, ul_ch, 8); - pil+=2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - + //printf("ul_ch addr %p\n",ul_ch); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); -#ifdef DEBUG_PUSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif + + #ifdef DEBUG_PUSCH + printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + #endif multadd_real_vector_complex_scalar(fmm, ch, ul_ch, 8); + + //for (int i= 0; i<16; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + pil+=2; re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; @@ -328,65 +339,153 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, printf("%d\n",idxP); } #endif + + } else { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d| + + // Treat first DMRS specially (left edge) + + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ul_ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ul_ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + pil+=2; + ul_ch+=2; + re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size; + ch_offset++; + + for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt+=6){ + + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ul_ch[0] = ch_l[0]; + ul_ch[1] = ch_l[1]; + + pil+=2; + ul_ch+=2; + ch_offset++; + + multadd_real_four_symbols_vector_complex_scalar(filt8_ml2, + ch_l, + ul_ch); + + re_offset = (re_offset+5)%gNB->frame_parms.ofdm_symbol_size; + + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + + multadd_real_four_symbols_vector_complex_scalar(filt8_mr2, + ch_r, + ul_ch); + + //for (int re_idx = 0; re_idx < 8; re_idx+=2) + //printf("ul_ch = %d + j*%d\n", ul_ch[re_idx], ul_ch[re_idx+1]); + + ul_ch+=8; + ch_offset+=4; + + ul_ch[0] = ch_r[0]; + ul_ch[1] = ch_r[1]; + + pil+=2; + ul_ch+=2; + ch_offset++; + re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size; + + } + + // Treat last pilot specially (right edge) + + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ul_ch[0] = ch_l[0]; + ul_ch[1] = ch_l[1]; + + ul_ch+=2; + ch_offset++; + + multadd_real_four_symbols_vector_complex_scalar(filt8_rr1, + ch_l, + ul_ch); + + multadd_real_four_symbols_vector_complex_scalar(filt8_rr2, + ch_r, + ul_ch); + + ul_ch_128 = (__m128i *)&ul_ch_estimates[aarx][ch_offset]; + + ul_ch_128[0] = _mm_slli_epi16 (ul_ch_128[0], 2); + } + + + // Convert to time domain - memset(temp_in_ifft_0, 0, gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t)); - memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t)); - switch (gNB->frame_parms.ofdm_symbol_size) { - case 128: - idft128((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + switch (gNB->frame_parms.ofdm_symbol_size) { + case 128: + idft128((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 256: - idft256((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 256: + idft256((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 512: - idft512((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 512: + idft512((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 1024: - idft1024((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 1024: + idft1024((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 1536: - idft1536((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 1536: + idft1536((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 2048: - idft2048((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 2048: + idft2048((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 4096: - idft4096((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 4096: + idft4096((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; - case 8192: - idft8192((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; + case 8192: + idft8192((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + default: + idft512((int16_t*) &ul_ch_estimates[aarx][symbol_offset], + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + } - default: - idft512((int16_t*) temp_in_ifft_0, - (int16_t*) ul_ch_estimates_time[aarx], - 1); - break; - } } #ifdef DEBUG_CH diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 125c166f7d..cc84f2292c 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -45,7 +45,8 @@ unsigned short p, unsigned char symbol, unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pusch); + unsigned short nb_rb_pusch, + dmrs_UplinkConfig_t *dmrs_UplinkConfig); int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 182f8b6215..f933a8c7ab 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -56,9 +56,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, int32_t *output, unsigned short p, unsigned char lp, - unsigned short nb_pusch_rb) + unsigned short nb_pusch_rb, + uint8_t dmrs_type) { - int8_t w,config_type; + int8_t w; short *mod_table; unsigned char idx=0; @@ -66,18 +67,16 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, array_of_w *wf; array_of_w *wt; - config_type = 0; //to be updated by higher layer + wf = (dmrs_type==pusch_dmrs_type1) ? wf1 : wf2; + wt = (dmrs_type==pusch_dmrs_type1) ? wt1 : wt2; - wf = (config_type==0) ? wf1 : wf2; - wt = (config_type==0) ? wt1 : wt2; + if (dmrs_type > 2) + LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", dmrs_type); - if (config_type > 1) - LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", config_type); - - if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) { + if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) { if (gNB->frame_parms.Ncp == NORMAL) { - for (int i=0; i>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index e1bfa1420d..754edfef64 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -47,5 +47,6 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, int32_t *output, unsigned short p, unsigned char lp, - unsigned short nb_pusch_rb); + unsigned short nb_pusch_rb, + uint8_t dmrs_type); #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index d74db96e4e..4c8d8650e3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -75,15 +75,18 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned short start_rb, unsigned short nb_rb_pusch, NR_DL_FRAME_PARMS *frame_parms, - uint8_t is_dmrs_symbol, - uint8_t dmrs_symbol); + uint8_t dmrs_symbol, + uint16_t number_symbols, + uint8_t mapping_type, + dmrs_UplinkConfig_t *dmrs_UplinkConfig); void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_gNB_ULSCH_t **ulsch_gNB, uint8_t symbol, uint8_t start_symbol, - uint16_t nb_rb); + uint16_t nb_rb, + pusch_dmrs_type_t pusch_dmrs_type); /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index f74c32e0c7..eb35fd7dc6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -231,21 +231,25 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned short start_rb, unsigned short nb_rb_pusch, NR_DL_FRAME_PARMS *frame_parms, - uint8_t is_dmrs_symbol, - uint8_t dmrs_symbol) + uint8_t dmrs_symbol, + uint16_t number_symbols, + uint8_t mapping_type, + dmrs_UplinkConfig_t *dmrs_UplinkConfig) { unsigned short start_re, re, nb_re_pusch; unsigned char aarx; uint32_t rxF_ext_index = 0; uint32_t ul_ch0_ext_index = 0; uint32_t ul_ch0_index = 0; + uint8_t is_dmrs_symbol_flag, k_prime; + uint16_t n=0; int16_t *rxF,*rxF_ext; int *ul_ch0,*ul_ch0_ext; #ifdef DEBUG_RB_EXT - printf("--------------------symbol = %d, is_dmrs_symbol = %u-----------------------\n", symbol, is_dmrs_symbol); + printf("--------------------symbol = %d-----------------------\n", symbol); printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch); #endif @@ -253,6 +257,7 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch; + is_dmrs_symbol_flag = 0; for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { @@ -263,26 +268,44 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch]; + n = 0; + k_prime = 0; + for (re = 0; re < nb_re_pusch; re++) { - if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A - // frame_parms->nushift should be initialized with 0 + is_dmrs_symbol_flag = is_dmrs_symbol(symbol, + (start_re + re)%frame_parms->ofdm_symbol_size, + start_re, + k_prime, + n, + 0, + number_symbols, + dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); + #ifdef DEBUG_RB_EXT + printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol); + #endif + + if ( is_dmrs_symbol_flag == 0 ) { + rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; - ul_ch0_ext_index++; - rxF_ext_index = rxF_ext_index + 2; - } - - ul_ch0_index++; - #ifdef DEBUG_RB_EXT printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]); printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]); - printf("ul_ch0_ext[%d] = %d\n", 2*rxF_ext_index, ((int16_t *)ul_ch0_ext)[2*rxF_ext_index]); - printf("ul_ch0_ext[%d] = %d\n", 2*rxF_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*rxF_ext_index + 1]); #endif + + ul_ch0_ext_index++; + rxF_ext_index +=2; + } else { + k_prime++; + k_prime&=1; + n+=(k_prime)?0:1; + } + ul_ch0_index++; } } } @@ -292,7 +315,8 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, NR_gNB_ULSCH_t **ulsch_gNB, uint8_t symbol, uint8_t is_dmrs_symbol, - unsigned short nb_rb) + unsigned short nb_rb, + pusch_dmrs_type_t pusch_dmrs_type) { #if defined(__x86_64__)||defined(__i386__) @@ -316,7 +340,10 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB]; if (is_dmrs_symbol==1){ - nb_rb = nb_rb>>1; + if (pusch_dmrs_type == pusch_dmrs_type1) + nb_rb = nb_rb>>1; + else + nb_rb = (2*nb_rb)/3; } @@ -367,7 +394,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; - for (rb = 0; rb < nb_rb; rb++) { + for (rb = 0; rb < len/12; rb++) { avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); @@ -997,18 +1024,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; dmrs_symbol_flag = is_dmrs_symbol(symbol, - 0, - 0, - 0, - 0, - 0, - rel15_ul->number_symbols, - &gNB->dmrs_UplinkConfig, - mapping_type, - frame_parms->ofdm_symbol_size); + 0, + 0, + 0, + 0, + 0, + rel15_ul->number_symbols, + &gNB->dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); if (dmrs_symbol_flag == 1){ - nb_re_pusch = rel15_ul->number_rbs * 6; + nb_re_pusch = rel15_ul->number_rbs * ((gNB->dmrs_UplinkConfig.pusch_dmrs_type==pusch_dmrs_type1)?6:8); gNB->pusch_vars[UE_id]->dmrs_symbol = symbol; } else { nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; @@ -1026,7 +1053,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, 0, // p symbol, bwp_start_subcarrier, - rel15_ul->number_rbs); + rel15_ul->number_rbs, + &gNB->dmrs_UplinkConfig); //---------------------------------------------------------- //--------------------- RBs extraction --------------------- @@ -1042,15 +1070,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, rel15_ul->start_rb, rel15_ul->number_rbs, frame_parms, - dmrs_symbol_flag, - gNB->pusch_vars[UE_id]->dmrs_symbol); + gNB->pusch_vars[UE_id]->dmrs_symbol, + rel15_ul->number_symbols, + mapping_type, + &gNB->dmrs_UplinkConfig); nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, frame_parms, gNB->ulsch[UE_id], symbol, dmrs_symbol_flag, - rel15_ul->number_rbs); + rel15_ul->number_rbs, + gNB->dmrs_UplinkConfig.pusch_dmrs_type); if (first_symbol_flag==1) { diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c index eeee55ea3f..dec3d7cc2d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c @@ -173,3 +173,15 @@ short filt8_dcl1_h[8]= { short filt8_dcr1_h[8]= { 0,0,4096,8192,12288,16384,0,0}; + +short filt8_ml2[8] = { +13107,9830,6554,3277,0,0,0,0}; + +short filt8_mr2[8] = { +3277,6554,9830,13107,0,0,0,0}; + +short filt8_rr1[8] = { +8192,12288,16384,20480,0,0,0,0}; + +short filt8_rr2[8] = { +-4096,-8192,-12288,-16384,0,0,0,0}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index f64aebeb52..e350985b0a 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -124,4 +124,13 @@ extern short filt8_dcr1[8]; extern short filt8_dcl1_h[8]; extern short filt8_dcr1_h[8]; -#endif + +extern short filt8_ml2[8]; + +extern short filt8_mr2[8]; + +extern short filt8_rr1[8]; + +extern short filt8_rr2[8]; + +#endif \ No newline at end of file diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index e1e44e137f..b07d9c31f2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -91,13 +91,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int gNB_id) { uint32_t available_bits; - uint8_t mod_order, cwd_index, num_of_codewords; + uint8_t mod_order, cwd_index, num_of_codewords, l; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; uint32_t ***pusch_dmrs; int16_t **tx_layers; int32_t **txdataF; uint16_t start_sc, start_rb; - int8_t Wf[2], Wt[2], l0, l_prime[2], delta; + int8_t Wf[2], Wt[2], l_prime[2], delta; uint16_t n_dmrs, code_rate, number_dmrs_symbols; uint8_t dmrs_type; uint8_t mapping_type; @@ -135,8 +135,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, mapping_type, frame_parms->ofdm_symbol_size); - printf("number_dmrs_symbols = %u\n", number_dmrs_symbols); - ulsch_ue->length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength; ulsch_ue->rnti = n_rnti; ulsch_ue->Nid_cell = Nid_cell; @@ -229,8 +227,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs); int16_t mod_dmrs[n_dmrs<<1]; dmrs_type = UE->dmrs_UplinkConfig.pusch_dmrs_type; - - l0 = get_l0_ul(mapping_type, 2); /////////// //////////////////////////////////////////////////////////////////////// @@ -252,7 +248,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// l_prime[0] = 0; // single symbol ap 0 - uint8_t dmrs_symbol = l0+l_prime[0], l; // Assuming dmrs-AdditionalPosition = 0 #ifdef NR_SC_FDMA uint32_t nb_re_pusch, nb_re_dmrs_per_rb; @@ -260,8 +255,19 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, for (l = start_symbol; l < start_symbol + harq_process_ul_ue->number_of_symbols; l++) { - if(l == dmrs_symbol) - nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; // [hna] ulsch_ue->nb_re_dmrs = 6 in this configuration + is_dmrs = is_dmrs_symbol(l, + 0, + 0, + 0, + 0, + 0, + harq_process_ul_ue->number_of_symbols, + &UE->dmrs_UplinkConfig, + mapping_type, + frame_parms->ofdm_symbol_size); + + if (is_dmrs == 1) + nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; else nb_re_dmrs_per_rb = 0; @@ -328,8 +334,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { - printf("DMRS l = %u\n", l); - nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index 013fedc6e9..dc57964ca5 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -119,6 +119,32 @@ void multadd_real_vector_complex_scalar(int16_t *x, } +void multadd_real_four_symbols_vector_complex_scalar(int16_t *x, + int16_t *alpha, + int16_t *y) +{ + + // do 8 multiplications at a time + simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x; + simd_q15_t y_128; + y_128 = _mm_loadu_si128((simd_q15_t*)y); + + alpha_r_128 = set1_int16(alpha[0]); + alpha_i_128 = set1_int16(alpha[1]); + + + yr = mulhi_s1_int16(alpha_r_128,x_128[0]); + yi = mulhi_s1_int16(alpha_i_128,x_128[0]); + y_128 = _mm_adds_epi16(y_128,_mm_unpacklo_epi16(yr,yi)); + y_128 = _mm_adds_epi16(y_128,_mm_unpackhi_epi16(yr,yi)); + + _mm_storeu_si128((simd_q15_t*)y, y_128); + + _mm_empty(); + _m_empty(); + +} + /* int rotate_cpx_vector(int16_t *x, int16_t *alpha, diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 5e5d5054b1..57f5a782de 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -71,6 +71,10 @@ void multadd_real_vector_complex_scalar(int16_t *x, int16_t *y, uint32_t N); +void multadd_real_four_symbols_vector_complex_scalar(int16_t *x, + int16_t *alpha, + int16_t *y); + /*!\fn void multadd_complex_vector_real_scalar(int16_t *x,int16_t alpha,int16_t *y,uint8_t zero_flag,uint32_t N) This function performs componentwise multiplication and accumulation of a real scalar and a complex vector. @param x Vector input (Q1.15) in the format |Re0 Im0|Re1 Im 1| ... diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 3652801bc3..c9bd24de76 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -22,6 +22,7 @@ #include "PHY/phy_extern.h" #include "PHY/defs_gNB.h" #include "sched_nr.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 07105e6e1f..5e1a8d2158 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -400,7 +400,6 @@ int main(int argc, char **argv) rel15_ul->mcs = Imcs; rel15_ul->rv = rvidx; rel15_ul->n_layers = Nl; - rel15_ul->nb_re_dmrs = nb_re_dmrs; rel15_ul->length_dmrs = length_dmrs; rel15_ul->R = code_rate; /////////////////////////////////////////////////// diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 724faf1d7f..767c90e7e2 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -150,8 +150,8 @@ int main(int argc, char **argv) NR_DL_FRAME_PARMS *frame_parms; int loglvl = OAILOG_WARNING; uint64_t SSB_positions=0x01; - uint16_t nb_symb_sch = 12; - int start_symbol = NR_SYMBOLS_PER_SLOT - nb_symb_sch; + uint16_t nb_symb_sch = 14; + int start_symbol = 0; uint16_t nb_rb = 50; uint8_t Imcs = 9; uint8_t precod_nbr_layers = 1; @@ -453,13 +453,14 @@ int main(int argc, char **argv) available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); + NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; //nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0]; - + unsigned char *estimated_output_bit; unsigned char *test_input_bit; uint32_t errors_decoding = 0; @@ -471,7 +472,33 @@ int main(int argc, char **argv) nr_scheduled_response_t scheduled_response; fapi_nr_ul_config_request_t ul_config; - + + unsigned int TBS; + uint16_t number_dmrs_symbols = 0; + unsigned int available_bits; + uint8_t nb_re_dmrs; + uint8_t length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength; + unsigned char mod_order; + uint16_t code_rate; + + for (i = 0; i < NR_SYMBOLS_PER_SLOT; i++) + number_dmrs_symbols += is_dmrs_symbol(i, + 0, + 0, + 0, + 0, + 0, + nb_symb_sch, + &UE->dmrs_UplinkConfig, + UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType, + frame_parms->ofdm_symbol_size); + + mod_order = nr_get_Qm_ul(Imcs, 0); + nb_re_dmrs = ((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1) ? 6 : 4) * number_dmrs_symbols; + code_rate = nr_get_code_rate_ul(Imcs, 0); + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); + TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); + printf("\n"); for (SNR = snr0; SNR < snr1; SNR += snr_step) { @@ -493,7 +520,6 @@ int main(int argc, char **argv) rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb; rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol; rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch; - rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = nb_re_dmrs; rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs; rel15_ul->ulsch_pdu_rel15.Qm = mod_order; rel15_ul->ulsch_pdu_rel15.mcs = Imcs; diff --git a/ubl b/ubl new file mode 100644 index 0000000000..c03ed2e987 --- /dev/null +++ b/ubl @@ -0,0 +1,575 @@ +diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai +index 227e8d8..6cd7151 100755 +--- a/cmake_targets/build_oai ++++ b/cmake_targets/build_oai +@@ -661,7 +661,8 @@ function main() { + if [ "$SIMUS_PHY" = "1" ] ; then + echo_info "Compiling physical unitary tests simulators" + # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim +- simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim" ++ #simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim" ++ simlist="nr_ulsim nr_dlsim" + for f in $simlist ; do + compilations \ + phy_simulators $f \ +diff --git a/executables/nr-ru.c b/executables/nr-ru.c +index b96fc9e..4ab9fce 100644 +--- a/executables/nr-ru.c ++++ b/executables/nr-ru.c +@@ -2330,7 +2330,7 @@ void RCconfig_RU(void) + RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); + RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); + RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); +- RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); ++ RC.ru[j]->att_rx = 4;//*(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + }// j=0..num_rus + } else { + RC.nb_RU = 0; +diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c +index fff1245..66d6e09 100644 +--- a/openair1/PHY/INIT/nr_init.c ++++ b/openair1/PHY/INIT/nr_init.c +@@ -403,12 +403,47 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, + gNB->mac_enabled = 1; + fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); +- fp->threequarter_fs= 0; ++ fp->threequarter_fs= 1; + nr_init_frame_parms(gNB_config, fp); + gNB->configured = 1; + LOG_I(PHY,"gNB configured\n"); + } +  ++void nr_phy_config_request_sim_ulsim(PHY_VARS_gNB *gNB, ++ int N_RB_DL, ++ int N_RB_UL, ++ int mu, ++ int Nid_cell, ++ uint64_t position_in_burst, ++ uint8_t threequarter_fs) ++{ ++ NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; ++ nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config; ++ //overwrite for new NR parameters ++ gNB_config->nfapi_config.rf_bands.rf_band[0] = 78; ++ gNB_config->nfapi_config.nrarfcn.value = 620000; ++ gNB_config->subframe_config.numerology_index_mu.value = mu; ++ gNB_config->subframe_config.duplex_mode.value = TDD; ++ gNB_config->rf_config.dl_carrier_bandwidth.value = N_RB_DL; ++ gNB_config->rf_config.ul_carrier_bandwidth.value = N_RB_UL; ++ gNB_config->sch_config.half_frame_index.value = 0; ++ gNB_config->sch_config.ssb_subcarrier_offset.value = 0; ++ gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20); ++ gNB_config->sch_config.ssb_subcarrier_offset.value = 0; ++ gNB_config->sch_config.physical_cell_id.value = Nid_cell; ++ gNB_config->sch_config.ssb_scg_position_in_burst.value = position_in_burst; ++ gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; ++ ++ gNB->mac_enabled = 1; ++ fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); ++ fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); ++ fp->threequarter_fs= threequarter_fs; ++ nr_init_frame_parms(gNB_config, fp); ++ nr_dump_frame_parms(fp); ++ gNB->configured = 1; ++ LOG_I(PHY,"gNB configured\n"); ++} ++ +  + void nr_phy_config_request(NR_PHY_Config_t *phy_config) + { +diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h +index 7e0500b..4209413 100644 +--- a/openair1/PHY/INIT/phy_init.h ++++ b/openair1/PHY/INIT/phy_init.h +@@ -387,6 +387,7 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); + int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag); + void nr_phy_config_request(NR_PHY_Config_t *gNB); + void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst); ++void nr_phy_config_request_sim_ulsim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst, uint8_t threequarter_fs); + void phy_free_nr_gNB(PHY_VARS_gNB *gNB); + int l1_north_init_gNB(void); + void init_nr_transport(PHY_VARS_gNB *gNB); +diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +index 0656091..9e5fcb1 100644 +--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c ++++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +@@ -140,7 +140,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + ul_ch, + 8); + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + //for (int i= 0; i<8; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); +@@ -156,7 +156,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + ul_ch, + 8); + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + //printf("ul_ch addr %p\n",ul_ch); +  +@@ -175,7 +175,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); +  + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; +  +@@ -193,7 +193,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + 8); +  + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; +  + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); +@@ -206,7 +206,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + ul_ch, + 8); + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; +  +@@ -227,7 +227,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); +  + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; +  + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); +@@ -242,7 +242,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + 8); +  + pil+=2; +- re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); ++ re_offset = (re_offset+2)%gNB->frame_parms.ofdm_symbol_size;//(re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; +  +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +index 2bc623a..e78842d 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +@@ -54,5 +54,8 @@ void nr_ulsch_unscrambling(int16_t* llr, + } + if (((s>>(i&0x1f))&1)==1) + llr[i] = -llr[i]; ++ ++ //if (i<10) ++ //printf("llr[%d] = %d\n", i, llr[i]); + } + } +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +index 19ca123..68a54b3 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +@@ -346,7 +346,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, +  + G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers); +  +- LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); ++ LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); +  + if (harq_process->round == 0) { +  +diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +index e1b3c5c..0369e73 100644 +--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c ++++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +@@ -365,9 +365,9 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; +  + for (rb = 0; rb < nb_rb; rb++) { +- avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); +- avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); +- avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); ++ avg128U = _mm_add_epi32(avg128U, _mm_srai_epi16(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); ++ avg128U = _mm_add_epi32(avg128U, _mm_srai_epi16(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); ++ avg128U = _mm_add_epi32(avg128U, _mm_srai_epi16(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); + ul_ch128+=3; + } +  +@@ -977,6 +977,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, + uint32_t nb_re_pusch, bwp_start_subcarrier; + int avgs; + int avg[4]; ++ char filename[40]; +  + pilots = 0; + first_symbol_flag = 0; +@@ -1062,6 +1063,16 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, + rel15_ul->number_rbs, + gNB->pusch_vars[UE_id]->log2_maxh); +  ++ if (symbol == 3){ ++ printf("log2_maxh = %d\n", gNB->pusch_vars[UE_id]->log2_maxh); ++ sprintf(filename,"rxdataF_gnb_ext.m"); ++ LOG_M(filename,"rxdataF_gnb_v",&gNB->pusch_vars[UE_id]->rxdataF_ext[0][symbol*NR_NB_SC_PER_RB*rel15_ul->number_rbs],NR_NB_SC_PER_RB*rel15_ul->number_rbs, 1, 1); ++ sprintf(filename,"rxdataF_comp_gnb.m"); ++ LOG_M(filename,"rxdataF_comp_gnb_v",&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol*NR_NB_SC_PER_RB*rel15_ul->number_rbs],NR_NB_SC_PER_RB*rel15_ul->number_rbs, 1, 1); ++ sprintf(filename,"ul_ch_est_ext_gnb.m"); ++ LOG_M(filename,"ul_ch_est_ext_gnb_v",&gNB->pusch_vars[UE_id]->ul_ch_estimates_ext[0][symbol*NR_NB_SC_PER_RB*rel15_ul->number_rbs], NR_NB_SC_PER_RB*rel15_ul->number_rbs, 1, 1); ++ } ++ + #ifdef NR_SC_FDMA + nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch); + #endif +diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +index 79b5c8d..c96a9a6 100644 +--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c ++++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +@@ -155,6 +155,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, + uint16_t n_tx=1, n_rx=1; + int32_t median[16]; + uint32_t len; ++ char filename[40]; +  + switch (type) { + case SI_PDSCH: +@@ -592,6 +593,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, +  + } +  ++ if (symbol == 3){ ++ printf("log2_maxh = %d\n", pdsch_vars[eNB_id]->log2_maxh); ++ sprintf(filename,"rxdataF_ue_ext.m"); ++ LOG_M(filename,"rxdataF_ue_ext_v",&pdsch_vars[eNB_id]->rxdataF_ext[0][symbol*NR_NB_SC_PER_RB*nb_rb],NR_NB_SC_PER_RB*nb_rb, 1, 1); ++ sprintf(filename,"rxdataF_comp_ue.m"); ++ LOG_M(filename,"rxdataF_comp_ue_v",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*NR_NB_SC_PER_RB*nb_rb],NR_NB_SC_PER_RB*nb_rb, 1, 1); ++ sprintf(filename,"dl_ch_est_ext_ue.m"); ++ LOG_M(filename,"dl_ch_est_ext_ue",&pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][symbol*NR_NB_SC_PER_RB*nb_rb], NR_NB_SC_PER_RB*nb_rb, 1, 1); ++ } ++ ++ + #if UE_TIMING_TRACE + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + #if DISABLE_LOG_X +@@ -636,6 +648,15 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, + dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0; + //i_mod should have been passed as a parameter + } ++ ++ ++ if (symbol == 3){ ++ printf("log2_maxh = %d\n", pdsch_vars[eNB_id]->log2_maxh); ++ sprintf(filename,"rxdataF_comp_ue.m"); ++ LOG_M(filename,"rxdataF_comp_ue_v",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*NR_NB_SC_PER_RB*nb_rb],NR_NB_SC_PER_RB*nb_rb, 1, 1); ++ sprintf(filename,"dl_ch_est_ext_ue.m"); ++ LOG_M(filename,"dl_ch_est_ext_ue",&pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][symbol*NR_NB_SC_PER_RB*nb_rb], NR_NB_SC_PER_RB*nb_rb, 1, 1); ++ } +  + #if UE_TIMING_TRACE + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); +diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c +index 3ac808f..9ab539a 100644 +--- a/openair1/SCHED_NR/nr_ru_procedures.c ++++ b/openair1/SCHED_NR/nr_ru_procedures.c +@@ -395,6 +395,7 @@ void nr_fep_full(RU_t *ru, int slot) { + RU_proc_t *proc = &ru->proc; + int l, aa; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; ++ char filename[40]; +  + // if ((fp->frame_type == TDD) &&  + // (subframe_select(fp,proc->tti_rx) != SF_UL)) return; +@@ -405,6 +406,9 @@ void nr_fep_full(RU_t *ru, int slot) { + // remove_7_5_kHz(ru,proc->tti_rx<<1); + // remove_7_5_kHz(ru,1+(proc->tti_rx<<1)); +  ++ //sprintf(filename,"rxdata_gnb.m"); ++ //LOG_M(filename,"rxdata_gnb_v",&ru->common.rxdata[0][proc->tti_rx*fp->samples_per_slot], 2*fp->samples_per_slot, 1, 0); ++ + for (l = 0; l < fp->symbols_per_slot; l++) { + for (aa = 0; aa < fp->nb_antennas_rx; aa++) { + nr_slot_fep_ul(fp, +diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +index ccf5343..bbd0c65 100644 +--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c ++++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +@@ -4143,6 +4143,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, + uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) + uint8_t dci_cnt = 0; + fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; ++ ++ char filename[40]; +  + LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); +  +@@ -4200,6 +4202,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, + } +  + dci_cnt = nr_ue_pdcch_procedures(eNB_id, ue, proc); ++ dci_cnt = 1; +  + if (dci_cnt > 0) { +  +@@ -4215,17 +4218,32 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, + 16384); + } + } else { +- LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx); ++ LOG_I(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx); + } + #endif //NR_PDCCH_SCHED +  +  + if (dci_cnt > 0){ +- LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); ++ ++ ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1; ++ dlsch0_harq->nb_rb = 50; ++ dlsch0_harq->start_rb = 0; ++ dlsch0_harq->nb_symbols = 12;//dlsch_config_pdu->number_symbols; ++ dlsch0_harq->start_symbol = 2;//dlsch_config_pdu->start_symbol; ++ dlsch0_harq->mcs = 9; ++ dlsch0_harq->DCINdi = 1; ++ dlsch0_harq->rvidx = 0; ++ dlsch0_harq->Nl=1; ++ dlsch0_harq->status = ACTIVE; ++ ++ LOG_I(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + //to update from pdsch config + nr_gold_pdsch(ue,nb_symb_pdcch,0, 1); +  + nb_symb_sch = dlsch0_harq->nb_symbols; ++ ++ sprintf(filename,"rxdata_ue_test.m"); ++ LOG_M(filename,"rxdata_ue_test_v",&ue->common_vars.rxdata[0][nr_tti_rx*ue->frame_parms.samples_per_slot],ue->frame_parms.samples_per_slot, 1, 1); +  + for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){ + nr_slot_fep(ue, +@@ -4237,7 +4255,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, +  + } + //set active for testing, to be removed +- ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1; ++  + } + else + ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0; +diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c +index a471062..cd64e53 100644 +--- a/openair1/SIMULATION/NR_PHY/dlsim.c ++++ b/openair1/SIMULATION/NR_PHY/dlsim.c +@@ -173,7 +173,7 @@ int main(int argc, char **argv) + //unsigned char frame_type = 0; + unsigned char pbch_phase = 0; +  +- int frame=0,slot=1; ++ int frame=0,slot=2; + int frame_length_complex_samples; + int frame_length_complex_samples_no_prefix; + int slot_length_complex_samples_no_prefix; +@@ -188,7 +188,7 @@ int main(int argc, char **argv) + int run_initial_sync=0; + int do_pdcch_flag=1; +  +- int loglvl=OAILOG_WARNING; ++ int loglvl=OAILOG_INFO; +  + float target_error_rate = 0.01; +  +@@ -398,6 +398,7 @@ int main(int argc, char **argv) + logInit(); + set_glog(loglvl); + T_stdout = 1; ++ FILE *in_file; +  + if (snr1set==0) + snr1 = snr0+10; +@@ -695,8 +696,13 @@ int main(int argc, char **argv) +  + nr_ue_phy_config_request(&UE_mac->phy_config); +  ++ int16_t *rxdata_ue; ++ rxdata_ue = &((short*) UE->common_vars.rxdata[0])[2*slot*frame_parms->samples_per_slot]; ++ + for (SNR = snr0; SNR < snr1; SNR += .2) { +  ++ in_file = fopen("rxdata_gnb.m", "r"); ++ + n_errors = 0; + //n_errors2 = 0; + //n_alamouti = 0; +@@ -710,14 +716,22 @@ int main(int argc, char **argv) + sigma2_dB = 10 * log10((double)txlev) - SNR; + sigma2 = pow(10, sigma2_dB/10); + // printf("sigma2 %f (%f dB)\n",sigma2,sigma2_dB); +- ++/* + for (i=0; inb_antennas_rx; aa++) { + ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + } + } +- ++*/ ++ for (i = 0; i < 2*frame_parms->samples_per_slot; i++){ ++ fscanf(in_file, "%d", &rxdata_ue[i]); ++ } ++/* ++ char filename[40]; ++ sprintf(filename,"rxdata_ue_test.m"); ++ LOG_M(filename,"rxdata_ue_test_v",&UE->common_vars.rxdata[0][slot*frame_parms->samples_per_slot],frame_parms->samples_per_slot, 1, 1); ++*/ + if (n_trials == 1) { +  + LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); +diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c +index 00ba0bb..3e31fa0 100644 +--- a/openair1/SIMULATION/NR_PHY/ulsim.c ++++ b/openair1/SIMULATION/NR_PHY/ulsim.c +@@ -99,7 +99,7 @@ int main(int argc, char **argv) + double sigma, sigma_dB; + double snr_step = 0.1; + uint8_t snr1set = 0; +- int slot = 0; ++ int slot = 1; + FILE *output_fd = NULL; + //uint8_t write_output_file = 0; + int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0; +@@ -116,10 +116,10 @@ int main(int argc, char **argv) + int number_of_frames = 1; + int frame_length_complex_samples; + NR_DL_FRAME_PARMS *frame_parms; +- int loglvl = OAILOG_WARNING; ++ int loglvl = OAILOG_INFO; + uint64_t SSB_positions=0x01; +- uint16_t nb_symb_sch = 12; +- int start_symbol = NR_SYMBOLS_PER_SLOT - nb_symb_sch; ++ uint16_t nb_symb_sch = 9; ++ int start_symbol = 2; + uint16_t nb_rb = 50; + uint8_t Imcs = 9; + uint8_t precod_nbr_layers = 1; +@@ -130,6 +130,7 @@ int main(int argc, char **argv) + int32_t txlev; + int start_rb = 0; + int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) ++ uint8_t threequarter_fs = 0; +  + cpuf = get_cpu_freq_GHz(); +  +@@ -144,7 +145,7 @@ int main(int argc, char **argv) + //logInit(); + randominit(0); +  +- while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:")) != -1) { ++ while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:pr:s:y:z:F:M:N:P:R:S:E")) != -1) { + switch (c) { +  + /*case 'd': +@@ -303,6 +304,10 @@ int main(int argc, char **argv) + printf("Setting SNR1 to %f\n", snr1); + break; +  ++ case 'E': ++ threequarter_fs = 1; ++ break; ++ + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]); +@@ -330,6 +335,7 @@ int main(int argc, char **argv) + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-R N_RB_DL\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); ++ printf("-E enable threequarter sampling\n"); + exit(-1); + break; + } +@@ -338,6 +344,7 @@ int main(int argc, char **argv) + logInit(); + set_glog(loglvl); + T_stdout = 1; ++ FILE *in_file; +  + if (snr1set == 0) + snr1 = snr0 + 10; +@@ -367,7 +374,7 @@ int main(int argc, char **argv) +  + crcTableInit(); +  +- nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions); ++ nr_phy_config_request_sim_ulsim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions, threequarter_fs); +  + phy_init_nr_gNB(gNB, 0, 0); + //init_eNB_afterRU(); +@@ -511,20 +518,42 @@ int main(int argc, char **argv) + sigma_dB = 10*log10(txlev_float)-SNR; + sigma = pow(10,sigma_dB/10); +  ++ int16_t *rxdata_gnb; ++ rxdata_gnb = &((short*) gNB->common_vars.rxdata[0])[2*slot*frame_parms->samples_per_slot]; ++ + for (trial = 0; trial < n_trials; trial++) { +  + errors_scrambling = 0; + errors_decoding = 0; +  ++ in_file = fopen("rxdata_ue.m", "r"); ++ ++ if (in_file == NULL) ++ { ++ printf("Can't open file for reading.\n"); ++ return -1; ++ } ++ + //---------------------------------------------------------- + //------------------------ add noise ----------------------- + //---------------------------------------------------------- ++ /* + for (i=0; inb_antennas_rx; ap++) { +- ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point +- ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); ++ ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = 0.5*((((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP)); // convert to fixed point ++ ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = 0.5*((((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP)); + } + } ++ */ ++ ++ for (i = 0; i < 2*frame_parms->samples_per_slot; i++){ ++ fscanf(in_file, "%d", &rxdata_gnb[i]); ++ } ++ ++ char filename[40]; ++ sprintf(filename,"rxdata_ue_ulsim.m"); ++ LOG_M(filename,"rxdata_ue_v",&gNB->common_vars.rxdata[0][slot*frame_parms->samples_per_slot], frame_parms->samples_per_slot, 1, 1); ++  + //////////////////////////////////////////////////////////// +  + //---------------------------------------------------------- +@@ -628,5 +657,8 @@ int main(int argc, char **argv) + if (input_fd) + fclose(input_fd); +  ++ if (in_file) ++ fclose(in_file); ++ + return (n_errors); + } +diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +index a11bf9d..86dc080 100644 +--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf ++++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +@@ -255,7 +255,6 @@ RUs = ( + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "type=x300"; +- + } + );  +  From c62443b2352df558e3b9e3fc70fa04133d366920 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Tue, 19 Nov 2019 16:03:16 +0100 Subject: [PATCH 093/134] fixing bugs intoduced after fapi implementation --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 9 +++++---- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index eb2b3c7c7c..c3197abe66 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -356,7 +356,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers); - LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); + LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d, nb_re_dmrs %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb, nb_re_dmrs, Qm, n_layers); if (harq_process->round == 0) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 4f23e4d703..cd0060d983 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -247,7 +247,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); - LOG_D(PHY,"ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs); + LOG_D(PHY,"ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d, harq_process->Nl = %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs, harq_process->Nl); G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index c9bd24de76..21dc0d93dc 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -231,7 +231,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled) mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; - gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->nb_re_dmrs = 0; + gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs = 0; for (l = 0; l < NR_SYMBOLS_PER_SLOT; l++) number_dmrs_symbols += is_dmrs_symbol(l, @@ -245,15 +245,16 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id mapping_type, frame_parms->ofdm_symbol_size); - gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; + gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, nfapi_ulsch_pdu_rel15->number_symbols, - gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->nb_re_dmrs, + gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs, nfapi_ulsch_pdu_rel15->length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers); + //---------------------------------------------------------- //------------------- ULSCH unscrambling ------------------- //---------------------------------------------------------- @@ -389,7 +390,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; - nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); + nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); uint8_t UE_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index ea3ee86db1..5b525bd3f7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -526,8 +526,8 @@ void nr_schedule_uss_ulsch_phytest(nfapi_nr_ul_tti_request_t *UL_tti_req, //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] pusch_pdu->uplink_frequency_shift_7p5khz = 0; //Resource Allocation in time domain - pusch_pdu->start_symbol_index = 2; - pusch_pdu->nr_of_symbols = 12; + pusch_pdu->start_symbol_index = 0; + pusch_pdu->nr_of_symbols = 14; //Optional Data only included if indicated in pduBitmap pusch_pdu->pusch_data.rv_index = 0; pusch_pdu->pusch_data.harq_process_id = 0; From c9eea33fdba0cca685bc07ddb3bc9debebdb4de4 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Mon, 11 Nov 2019 15:03:48 +0100 Subject: [PATCH 094/134] Fix samples per frame config for 3/4 sampling rate --- executables/nr-uesoftmodem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 7e2ffebb35..8d31beb580 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -555,7 +555,7 @@ void init_openair0(void) { } else if (numerology==1) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=46.08e6; - openair0_cfg[card].samples_per_frame = 480800; + openair0_cfg[card].samples_per_frame = 460800; } else { openair0_cfg[card].sample_rate=61.44e6; From 6ee084056250d7a7205a1e8b578e84fa2a88a28d Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 12 Nov 2019 17:39:47 +0100 Subject: [PATCH 095/134] make time to transmit UL slot less hard-coded Replace "slot == 18" by "slot == (20 + NR_UPLINK_SLOT - DURATION_RX_TO_TX) % 20". At least this is correct for 30 kHz SCS... --- executables/nr-ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index c6f237e300..6472514881 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -736,7 +736,7 @@ void *UE_thread(void *arg) { readBlockSize, UE->frame_parms.nb_antennas_rx),""); -if (slot_nr==18) +if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX)%20) AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, timestamp+ From f7d546f2d9a35e7ebeff2ba8bc367bfa6863fcf9 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 12 Nov 2019 18:14:07 +0100 Subject: [PATCH 096/134] port DL fix 4297beffa03b8da0126811c01f593794be4a4384 to UL --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index cd0060d983..e1f9f4c456 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -200,7 +200,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, uint32_t A, Z, F; uint32_t *pz; uint8_t mod_order; - uint16_t Kr,r,r_offset; + uint16_t Kr,r; + uint32_t r_offset; uint8_t BG; uint32_t E,Kb; uint8_t Ilbrm; From 2dd941a22d16ecb158c813aeb29b253987bb2f10 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Tue, 17 Dec 2019 11:56:03 +0100 Subject: [PATCH 097/134] Adding one UL empty slot before actual UL slot - total num of symbols is 12 instead of 14 in PUSCH - actual UL slot is 3 instead of 2 --- executables/nr-ue.c | 16 ++++++++++++++-- openair1/PHY/impl_defs_nr.h | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 4 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 6472514881..2e36b648d2 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -382,7 +382,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { n_rnti = 0x1234; nb_rb = 50; start_rb = 0; - nb_symb_sch = 14; + nb_symb_sch = 12; start_symbol = 0; precod_nbr_layers = 1; mcs = 9; @@ -736,6 +736,18 @@ void *UE_thread(void *arg) { readBlockSize, UE->frame_parms.nb_antennas_rx),""); +if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX - 1)%20) + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 2),""); + if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX)%20) AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, @@ -746,7 +758,7 @@ if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX)%20) txp, writeBlockSize, UE->frame_parms.nb_antennas_tx, - 4),""); + 3),""); if( slot_nr==(nb_slot_frame-1)) { // read in first symbol of next frame and adjust for timing drift diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 43333857d6..d62da853ee 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -119,7 +119,7 @@ SystemInformationBlockType1_nr_t; #define NR_TDD_SET_ALL_SYMBOLS (0x3FFF) #define NR_DOWNLINK_SLOT (0x01) -#define NR_UPLINK_SLOT (0x02) +#define NR_UPLINK_SLOT (0x03) #define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index e43f2633b1..d988294db1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -375,11 +375,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // Phytest scheduling - if (slot_rxP==2){ + if (slot_rxP==NR_UPLINK_SLOT){ nr_schedule_uss_ulsch_phytest(&RC.nrmac[module_idP]->UL_tti_req[0], frame_rxP, slot_rxP); } - if (slot_txP==1){ + if (slot_txP==NR_DOWNLINK_SLOT){ nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 5b525bd3f7..7fe81ebd1c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -527,7 +527,7 @@ void nr_schedule_uss_ulsch_phytest(nfapi_nr_ul_tti_request_t *UL_tti_req, pusch_pdu->uplink_frequency_shift_7p5khz = 0; //Resource Allocation in time domain pusch_pdu->start_symbol_index = 0; - pusch_pdu->nr_of_symbols = 14; + pusch_pdu->nr_of_symbols = 12; //Optional Data only included if indicated in pduBitmap pusch_pdu->pusch_data.rv_index = 0; pusch_pdu->pusch_data.harq_process_id = 0; From 8e00f8df08ea24e604e949a53d3d7f583a6a162e Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Tue, 17 Dec 2019 12:18:04 +0100 Subject: [PATCH 098/134] Fixing a bug in number of UL DMRS symbol computation --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 6 +++--- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index b07d9c31f2..dfdce058d8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -123,7 +123,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index]; harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; - for (i = 0; i < NR_SYMBOLS_PER_SLOT; i++) + start_symbol = harq_process_ul_ue->start_symbol; + + for (i = start_symbol; i < start_symbol + harq_process_ul_ue->number_of_symbols; i++) number_dmrs_symbols += is_dmrs_symbol(i, 0, 0, @@ -219,8 +221,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } - start_symbol = 14 - harq_process_ul_ue->number_of_symbols; - /////////////////////////DMRS Modulation///////////////////////// /////////// pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 21dc0d93dc..9c36ae740f 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -229,18 +229,22 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id uint8_t mapping_type; uint32_t G; int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled) + uint16_t start_symbol, number_symbols; mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs = 0; - for (l = 0; l < NR_SYMBOLS_PER_SLOT; l++) + start_symbol = nfapi_ulsch_pdu_rel15->start_symbol; + number_symbols = nfapi_ulsch_pdu_rel15->number_symbols; + + for (l = start_symbol; l < start_symbol + number_symbols; l++) number_dmrs_symbols += is_dmrs_symbol(l, 0, 0, 0, 0, 0, - nfapi_ulsch_pdu_rel15->number_symbols, + number_symbols, &gNB->dmrs_UplinkConfig, mapping_type, frame_parms->ofdm_symbol_size); @@ -248,7 +252,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, - nfapi_ulsch_pdu_rel15->number_symbols, + number_symbols, gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs, nfapi_ulsch_pdu_rel15->length_dmrs, nfapi_ulsch_pdu_rel15->Qm, @@ -274,7 +278,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id gNB->pusch_vars[UE_id]->llr, frame_parms, frame_rx, - nfapi_ulsch_pdu_rel15->number_symbols, + number_symbols, slot_rx, harq_pid, 0); From 4fe691f443e06a6becd112cd6b7ce7bc1f9183ab Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Tue, 17 Dec 2019 17:36:22 +0100 Subject: [PATCH 099/134] Fixing nr_ulsim configuration for DMRS --- openair1/SIMULATION/NR_PHY/ulsim.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 767c90e7e2..3cea63975f 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -150,7 +150,7 @@ int main(int argc, char **argv) NR_DL_FRAME_PARMS *frame_parms; int loglvl = OAILOG_WARNING; uint64_t SSB_positions=0x01; - uint16_t nb_symb_sch = 14; + uint16_t nb_symb_sch = 12; int start_symbol = 0; uint16_t nb_rb = 50; uint8_t Imcs = 9; @@ -441,18 +441,6 @@ int main(int argc, char **argv) } unsigned char harq_pid = 0; - unsigned int TBS; - unsigned int available_bits; - uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4); - uint8_t length_dmrs = 1; - unsigned char mod_order; - uint16_t code_rate; - - mod_order = nr_get_Qm_ul(Imcs, 0); - code_rate = nr_get_code_rate_ul(Imcs, 0); - available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); - NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; //nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; @@ -481,7 +469,7 @@ int main(int argc, char **argv) unsigned char mod_order; uint16_t code_rate; - for (i = 0; i < NR_SYMBOLS_PER_SLOT; i++) + for (i = start_symbol; i < nb_symb_sch; i++) number_dmrs_symbols += is_dmrs_symbol(i, 0, 0, @@ -541,8 +529,8 @@ int main(int argc, char **argv) pusch_pdu->rnti = n_rnti; pusch_pdu->mcs_index = Imcs; pusch_pdu->mcs_table = 0; - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->target_code_rate = code_rate; + pusch_pdu->qam_mod_order = mod_order; pusch_pdu->transform_precoding = 0; pusch_pdu->data_scrambling_id = 0; pusch_pdu->nrOfLayers = 1; @@ -561,13 +549,7 @@ int main(int argc, char **argv) pusch_pdu->pusch_data.rv_index = 0; pusch_pdu->pusch_data.harq_process_id = 0; pusch_pdu->pusch_data.new_data_indicator = 0; - pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, - pusch_pdu->target_code_rate, - pusch_pdu->rb_size, - pusch_pdu->nr_of_symbols, - nb_re_dmrs*length_dmrs, - 0, - pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.tb_size = TBS; pusch_pdu->pusch_data.num_cb = 0; From 1e4cbce244ae323831f19bdfa95a3fedd3b48303 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 18 Dec 2019 16:13:42 +0100 Subject: [PATCH 100/134] multiple ssb fix --- openair1/SCHED_NR/nr_ru_procedures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 137454d6b5..bf1d0b4a75 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -123,7 +123,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { int j = 0;//symbol int aa = 0;//logical antenna number int ret = 0; - int nb_antenna_ports = fp->N_ssb; + int nb_antenna_ports = fp->L_ssb; int ofdm_mask_full = (1<<(ru->nb_tx*2))-1; int txdataF_offset = ((tti_tx%2)*fp->samples_per_slot_wCP); @@ -283,7 +283,7 @@ static void *nr_feptx_thread(void *param) { for (int p=0; pLmax; p++) { if ((fp->L_ssb >> p) & 0x01){ memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], - (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], + (void*)&ru->gNB_list[0]->common_vars.txdataF[p][txdataF_offset + l*fp->ofdm_symbol_size], (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); } } From 5490d3e75dbd2e9cfed477e701760c4b9398bdcc Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 19 Dec 2019 09:43:45 +0100 Subject: [PATCH 101/134] some cppcheck fixes and also compilation warnings removal --- executables/nr-ru.c | 6 +-- openair1/PHY/CODING/TESTBENCH/ldpctest.c | 1 + openair1/PHY/CODING/TESTBENCH/polartest.c | 6 ++- .../ldpc_generate_coefficient.c | 3 +- .../CODING/nrPolar_tools/nr_polar_decoder.c | 2 + .../nrPolar_tools/nr_polar_decoding_tools.c | 2 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 16 +++++--- openair1/PHY/NR_TRANSPORT/nr_dlsch.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 13 +++--- openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c | 1 + .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 7 ++-- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 40 +++++++++++-------- openair1/PHY/TOOLS/nr_phy_scope.c | 12 +++--- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 4 +- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 10 ++--- openair2/NETWORK_DRIVER/UE_IP/common.c | 4 +- 18 files changed, 77 insertions(+), 58 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index b402110c4b..11584871ae 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -806,7 +806,6 @@ static void *ru_thread_asynch_rxtx( void *param ) { printf( "devices ok (ru_thread_asynch_rx)\n"); while (!oai_exit) { - if (oai_exit) break; if (subframe==9) { subframe=0; @@ -854,7 +853,7 @@ static void *ru_thread_prach( void *param ) { LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__); while (!oai_exit) { - if (oai_exit) break; + if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; @@ -1159,7 +1158,7 @@ int setup_RU_buffers(RU_t *ru) { frame_parms = ru->nr_frame_parms; printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); } else { - printf("RU[%d] not initialized\n", ru->idx); + printf("ru pointer is NULL\n"); return(-1); } @@ -1259,7 +1258,6 @@ static void *ru_thread_tx( void *param ) { } while (!oai_exit) { - if (oai_exit) break; LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); // wait until eNBs are finished subframe RX n and TX n+4 diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index ed8dd3b49a..95ee3fed17 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -317,6 +317,7 @@ int test_ldpc(short No_iteration, for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++) if (channel_input[j][i]!=channel_input_optim[j][i]) { printf("differ in seg %u pos %u (%u,%u)\n", j, i, channel_input[j][i], channel_input_optim[j][i]); + free(channel_output); return (-1); } //else{ diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 36b6bbf826..7fcaa0646c 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -215,6 +215,8 @@ if (logFlag){ free(encoder_outputByte); free(channel_output); free(modulated_input); + if (logFlag) + fclose(logFile); return 0; #endif @@ -317,13 +319,13 @@ if (logFlag){ if (nBitError>0) blockErrorState=1; #ifdef DEBUG_POLARTEST for (int i = 0; i < testArrayLength; i++) - printf("[polartest/decoderState=%d] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",decoderState, i, testInput[i], i, estimatedOutput[i]); + printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",decoderState, i, testInput[i], i, estimatedOutput[i]); #endif //Iteration times are in microseconds. timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0)); timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0)); - if (logFlag) fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0))); + if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0))); if (nBitError<0) { blockErrorCumulative++; diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c index 5da223dc64..5988c9067d 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c @@ -494,7 +494,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int fprintf(fd," int i2;\n"); fprintf(fd2," int i2;\n"); fprintf(fd," for (i2=0; i2<%d; i2++) {\n",Zc>>shift); - fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1)); + if (shift > 0) + fprintf(fd2," for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1)); for (i2=0; i2 < 1; i2++) { //t=Kb*Zc+i2; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 7ec530242e..53119a1c2b 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -252,6 +252,7 @@ int8_t polar_decoder(double *input, nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1)); nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits); + free(tempECGM); return(-1); } @@ -522,6 +523,7 @@ int8_t polar_decoder_dci(double *input, nr_free_uint8_3D_array(bit, polarParams->N, (polarParams->n+1)); nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); nr_free_uint8_2D_array(crcChecksum, polarParams->crcParityBits); + free(tempECGM); return(-1); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c index bf8a90e0d9..daa2346098 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -470,7 +470,7 @@ void computeBeta(const t_nrPolar_params *pp,decoder_node_t *node) { int ssr4len = node->Nv/2/8; register __m128i allones=*((__m128i*)all1); for (int i=0;i ERROR\n",nushift); +#ifdef DEBUG_CH + if (debug_ch_est) + fclose(debug_ch_est); + +#endif return(-1); break; } @@ -193,7 +197,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - fprintf(debug_ch_est, "pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + fprintf(debug_ch_est, "pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); //printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, @@ -208,7 +212,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fmm, ch, @@ -225,7 +229,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -243,7 +247,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fmr, ch, @@ -258,7 +262,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, ch, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index d982a17ea7..77d5c6802f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -80,7 +80,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, time_stats_t *dlsch_modulation_stats); -void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); +void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr); void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 244e29a243..dae5586224 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -48,11 +48,12 @@ //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 -void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) +void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr) { int i; int r; - + + NR_gNB_DLSCH_t *dlsch = *dlschptr; if (dlsch) { #ifdef DEBUG_DLSCH_FREE printf("Freeing dlsch %p\n",dlsch); @@ -232,7 +233,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of %ld\n", exit_flag, sizeof(NR_gNB_DLSCH_t)); - free_gNB_dlsch(dlsch); + free_gNB_dlsch(&dlsch); return(NULL); @@ -278,7 +279,7 @@ int nr_dlsch_encoding(unsigned char *a, unsigned int G; unsigned int crc=1; - uint8_t harq_pid = dlsch->harq_ids[frame%2][slot]; + uint8_t harq_pid = dlsch->harq_ids[frame&2][slot]; AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid); nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; uint16_t nb_rb = rel15.n_prb; @@ -458,7 +459,7 @@ int nr_dlsch_encoding(unsigned char *a, #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) - printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); + printf("output ratematching e[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); #endif nr_interleaving_ldpc(E, @@ -469,7 +470,7 @@ int nr_dlsch_encoding(unsigned char *a, #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) - printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset); + printf("output interleaving f[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset); if (r==dlsch->harq_processes[harq_pid]->C-1) write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->f,G,1,4); diff --git a/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c b/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c index 98248d02dd..b2a7471d82 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/cic_filter_nr.c @@ -438,6 +438,7 @@ void cic_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, in fir_filter_basic(input, output, new_length, FIR_TAPS_NUMBER, filter_taps, SHARPENED_FIR_SCALING_ACC); #endif + free(filter_taps_fixed_point); } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 7559115a29..97010a3185 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -61,7 +61,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch); NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag); -void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch); +void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch); NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index cbe0a816ff..cacc9f92d0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -42,9 +42,10 @@ -void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) +void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr) { int i, r; + NR_UE_ULSCH_t *ulsch = *ulschptr; if (ulsch) { #ifdef DEBUG_ULSCH_FREE @@ -80,7 +81,7 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) } } free16(ulsch,sizeof(NR_UE_ULSCH_t)); - ulsch = NULL; + *ulschptr = NULL; } } @@ -179,7 +180,7 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, } LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t)); - free_nr_ue_ulsch(ulsch); + free_nr_ue_ulsch(&ulsch); return(NULL); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index e838b4b747..351c4ea22a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -77,7 +77,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, // initialization to be removed PUCCH_GroupHopping=neither; n_id=10; - printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%d, n_id=%d -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id); + printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%u, n_id=%u -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id); #endif uint8_t f_ss=0,f_gh=0; *u=0; @@ -159,14 +159,14 @@ double nr_cyclic_shift_hopping(uint32_t n_id, #ifdef DEBUG_NR_PUCCH_TX // initialization to be remo.ved c_init=10; - printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init); + printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%u -> variable initialization TO BE REMOVED\n",c_init); #endif uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint8_t n_cs=0; int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX - printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%d -> \n",c_init); + printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init); #endif for (int m=0; m<8; m++) { @@ -306,7 +306,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15; //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -330,7 +330,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, uint8_t timeDomainOCC, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", + printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%lu m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); #endif /* @@ -368,7 +368,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, } // printf("d_re=%d\td_im=%d\n",(int)d_re,(int)d_im); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); + printf("\t [nr_generate_pucch1] sequence modulation: payload=%lx \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); #endif /* * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 @@ -625,7 +625,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n]; ((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -635,7 +635,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n]; ((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -961,7 +961,7 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id, x2 = ((rnti)<<15)+n_id; s = lte_gold_generic(&x1, &x2, 1); #ifdef DEBUG_NR_PUCCH_TX - printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%lx\n",s); + printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x\n",s); #endif for (i=0; iofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+k,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -1222,7 +1222,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>((2*m)+1))&1)))))>>15); m++; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch2] (n=%d,i=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + printf("\t [nr_generate_pucch2] (n=%d,i=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+kk,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -1240,6 +1240,9 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, } } } + free(d_re); + free(d_im); + free(btilde); } //#if 0 void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, @@ -1260,7 +1263,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, uint8_t occ_length_format4, uint8_t occ_index_format4) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] start function at slot(nr_tti_tx)=%d with payload=%d and nr_bit=%d\n", nr_tti_tx, payload, nr_bit); + printf("\t [nr_generate_pucch3_4] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n", nr_tti_tx, payload, nr_bit); #endif // b is the block of bits transmitted on the physical channel after payload coding uint64_t b; @@ -1665,7 +1668,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, } #ifdef DEBUG_NR_PUCCH_TX - printf("re_offset=%d,(rb+startingPRB)=%d\n",re_offset,(rb+startingPRB)); + printf("re_offset=%u,(rb+startingPRB)=%d\n",re_offset,(rb+startingPRB)); #endif //txptr = &txdataF[0][re_offset]; @@ -1679,7 +1682,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ((int16_t *)&txdataF[0][re_offset])[0] = z_re[n+k]; ((int16_t *)&txdataF[0][re_offset])[1] = z_im[n+k]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(z(l=%d,n=%d)=(%d,%d))\n", + printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(z(l=%d,n=%d)=(%d,%d))\n", l,rb,n,k,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+k,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -1691,7 +1694,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15) + (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15)); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(r_u_v(l=%d,n=%d)=(%d,%d))\n", + printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(r_u_v(l=%d,n=%d)=(%d,%d))\n", l,rb,n,j,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+j,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif @@ -1705,5 +1708,8 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) j+=12; } } + free(z_re); + free(z_im); + free(btilde); } diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 778070b347..66ac415872 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -345,9 +345,9 @@ void phy_scope_gNB(FD_phy_scope_gnb *form, I_pucch[ind] = (float)pucch1ab_comp[2*(ind)]; Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1]; - A_pucch[ind] = 10*log10(pucch1_comp[ind]); + A_pucch[ind] = pucch1_comp?(10*log10(pucch1_comp[ind])):0; B_pucch[ind] = ind; - C_pucch[ind] = (float)pucch1_thres[ind]; + C_pucch[ind] = pucch1_thres?(float)pucch1_thres[ind]:0; } fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); @@ -840,7 +840,7 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form, free(bit); free(bit_pdcch); free(llr_pdcch); - + free(chest_t_abs); /* free(chest_f_abs); for (arx=0; arxactive == 0) return; - if (dlsch0 && (!dlsch1)) { + if (!dlsch1) { int harq_pid = dlsch0->current_harq_pid; uint16_t pdsch_start_rb = dlsch0->harq_processes[harq_pid]->start_rb; uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index aab762b9e2..7820ed8417 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -621,9 +621,9 @@ int main(int argc, char **argv) for (i = 0; i < 2; i++) { printf("gNB %d\n", i); - free_gNB_dlsch(gNB->dlsch[0][i]); + free_gNB_dlsch(&(gNB->dlsch[0][i])); printf("UE %d\n", i); - free_nr_ue_dlsch(UE->dlsch[0][0][i]); + free_nr_ue_dlsch(&(UE->dlsch[0][0][i])); } for (i = 0; i < 2; i++) { diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b56e8b11e9..8ee8cdc1c0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -221,7 +221,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, nr_rlc_ue_t *ue; nr_rlc_entity_t *rb; - LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %d mui %d confirm %d sdu_size %d MBMS_flag %d\n", + LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n", __FUNCTION__, rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP); @@ -824,24 +824,24 @@ rlc_op_status_t rrc_rlc_config_req ( } if ((srb_flagP && !(rb_idP >= 1 && rb_idP <= 2)) || (!srb_flagP && !(rb_idP >= 1 && rb_idP <= 5))) { - LOG_E(RLC, "%s:%d:%s: bad rb_id (%d) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); + LOG_E(RLC, "%s:%d:%s: bad rb_id (%ld) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); exit(1); } nr_rlc_manager_lock(nr_rlc_ue_manager); - LOG_D(RLC, "%s:%d:%s: remove rb %d (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); + LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rnti); if (srb_flagP) { if (ue->srb[rb_idP-1] != NULL) { ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]); ue->srb[rb_idP-1] = NULL; } else - LOG_W(RLC, "removing non allocated SRB %d, do nothing\n", rb_idP); + LOG_W(RLC, "removing non allocated SRB %ld, do nothing\n", rb_idP); } else { if (ue->drb[rb_idP-1] != NULL) { ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]); ue->drb[rb_idP-1] = NULL; } else - LOG_W(RLC, "removing non allocated DRB %d, do nothing\n", rb_idP); + LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP); } /* remove UE if it has no more RB configured */ for (i = 0; i < 2; i++) diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 0d66f42357..3e2c000e40 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -193,7 +193,7 @@ ue_ip_common_class_wireless2ip( break; default: - printk("[UE_IP_DRV][%s] begin RB %d Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP); + printk("[UE_IP_DRV][%s] begin RB %ld Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP); printk("[UE_IP_DRV][%s] Inst %d: receive unknown message (version=%d)\n",__FUNCTION__,instP,ipv_p->version); } @@ -326,7 +326,7 @@ ue_ip_common_ip2wireless( bytes_wrote += ue_ip_netlink_send((char *)skb_pP->data,skb_pP->len); if (bytes_wrote != skb_pP->len+UE_IP_PDCPH_SIZE) { - printk("[UE_IP_DRV][%s] Inst %d, RB_ID %d: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n", + printk("[UE_IP_DRV][%s] Inst %d, RB_ID %ld: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n", __FUNCTION__, instP, pdcph.rb_id, From 4da175f5149cce6fde77eab7e6504bd92930a58c Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 19 Dec 2019 10:06:15 +0100 Subject: [PATCH 102/134] [nr_ulsim] don't break out of SNR loop just because number_of_frames==1 --- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 3cea63975f..10365c8619 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -677,7 +677,7 @@ int main(int argc, char **argv) break; } // frame loop - if(is_frame_in_error == 0 || number_of_frames==1) + if(is_frame_in_error == 0) break; } // SNR loop From 82aebfa6279244fd3797f3c6db8bad43d7dde1ea Mon Sep 17 00:00:00 2001 From: Hongzhi Wang Date: Thu, 7 Nov 2019 11:33:58 +0100 Subject: [PATCH 103/134] add thread pool for dlsch --- executables/nr-uesoftmodem.c | 7 ++++++- executables/nr-uesoftmodem.h | 1 + openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 14 +++++++------- openair1/PHY/defs_common.h | 6 +++--- openair1/SCHED_NR_UE/defs.h | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 32dca26a45..95ec330055 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -206,6 +206,7 @@ int oaisim_flag=0; int emulate_rf = 0; tpool_t *Tpool; +tpool_t *Tpool_dl; char *usrp_args=NULL; @@ -672,8 +673,12 @@ int main( int argc, char **argv ) { set_taus_seed (0); tpool_t pool; Tpool = &pool; - char params[]="-1,-1"; + char params[]="-1,-1,-1"; initTpool(params, Tpool, false); + tpool_t pool_dl; + Tpool_dl = &pool_dl; + char params_dl[]="-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1"; + initTpool(params_dl, Tpool_dl, false); cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 2434a1c23c..cad8e726f4 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -103,4 +103,5 @@ extern void print_opp_meas(void); void *UE_thread(void *arg); PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); extern tpool_t *Tpool; +extern tpool_t *Tpool_dl; #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 6a277cdc42..c1ccaf2f1e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -531,7 +531,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); - //printf("harq process dr iteration %d\n", p_decParams->numMaxIter); + printf("harq process dr iteration %d\n", p_decParams->numMaxIter); memset(pv,0,2*harq_process->Z*sizeof(int16_t)); //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); @@ -570,7 +570,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ret = no_iteration_ldpc; } else { - printf("\x1B[33m" "CRC NOK\n\033[0m"); + printf("\x1B[33m" "Segment %d CRC NOK\n",r); ret = 1 + dlsch->max_ldpc_iterations; } @@ -943,7 +943,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, opp_enabled=1; if (harq_process->C>1) { for (int nb_seg =1 ; nb_segC; nb_seg++){ - if ( (res=tryPullTpool(&nf, Tpool)) != NULL ) { + if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) { pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); } @@ -961,7 +961,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, curMsg->proc.llr8_flag = llr8_flag; msgToPush->key=nb_seg; - pushTpool(Tpool, msgToPush); + pushTpool(Tpool_dl, msgToPush); /*Qm= harq_process->Qm; Nl=harq_process->Nl; @@ -1112,7 +1112,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); #endif - LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + LOG_I(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ inv_d[cnt] = (1)*harq_process->d[r][cnt]; @@ -1689,7 +1689,7 @@ void *nr_dlsch_decoding_process(void *arg) ret = 2; } else { - printf("CRC NOK\n"); + printf("Segment %d CRC NOK\n",r); ret = 1+dlsch->max_ldpc_iterations; } @@ -1757,7 +1757,7 @@ void *dlsch_thread(void *arg) { notifiedFIFO_elt_t *res; while (nbDlProcessing >= RX_NB_TH_DL) { - if ( (res=tryPullTpool(&nf, Tpool)) != NULL ) { + if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) { nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData; nbDlProcessing--; pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 811ae17e71..d008696929 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -76,9 +76,9 @@ #include "defs_RU.h" -#define RX_NB_TH_MAX 2 -#define RX_NB_TH 2 -#define RX_NB_TH_DL 2 +#define RX_NB_TH_MAX 3 +#define RX_NB_TH 3 +#define RX_NB_TH_DL 12 #define LTE_SLOTS_PER_SUBFRAME 2 diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 8e42149add..cd61302304 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -44,7 +44,7 @@ #define OPENAIR_THREAD_STACK_SIZE PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6 //#define DLC_THREAD_STACK_SIZE 4096 //DLC stack size //#define UE_SLOT_PARALLELISATION -//#define UE_DLSCH_PARALLELISATION +#define UE_DLSCH_PARALLELISATION /*enum openair_SCHED_STATUS { openair_SCHED_STOPPED=1, From f4772f2ba21825f95d9e47950dcb3237b0099197 Mon Sep 17 00:00:00 2001 From: Hongzhi Wang Date: Tue, 17 Dec 2019 13:51:00 +0100 Subject: [PATCH 104/134] bug fix dlsch thread --- executables/nr-uesoftmodem.c | 4 +-- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 31 ++++++++++--------- openair1/PHY/defs_common.h | 6 ++-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 95ec330055..0655af8de0 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -673,11 +673,11 @@ int main( int argc, char **argv ) { set_taus_seed (0); tpool_t pool; Tpool = &pool; - char params[]="-1,-1,-1"; + char params[]="-1,-1"; initTpool(params, Tpool, false); tpool_t pool_dl; Tpool_dl = &pool_dl; - char params_dl[]="-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1"; + char params_dl[]="-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1"; initTpool(params_dl, Tpool_dl, false); cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index c1ccaf2f1e..ec35e76272 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -775,16 +775,16 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, int16_t z [68*384]; int8_t l [68*384]; //__m128i l; - int16_t inv_d [68*384]; + //int16_t inv_d [68*384]; //int16_t *p_invd =&inv_d; uint8_t kb, kc; uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; double Coderate = 0.0; - nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config; - uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; - uint8_t nb_re_dmrs = (dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; + //nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config; + //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; + uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value; uint32_t i,j; @@ -1034,7 +1034,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if (harq_process->Nl < Nl) Nl = harq_process->Nl; - Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C); + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C); if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, @@ -1323,7 +1323,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #endif #ifdef UE_DLSCH_PARALLELISATION -void *nr_dlsch_decoding_process(void *arg) +void nr_dlsch_decoding_process(void *arg) { nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; @@ -1340,8 +1340,8 @@ void *nr_dlsch_decoding_process(void *arg) int16_t z [68*384]; int8_t l [68*384]; //__m128i l; - int16_t inv_d [68*384]; - int16_t *p_invd =&inv_d; + //int16_t inv_d [68*384]; + //int16_t *p_invd =&inv_d; uint8_t kb, kc; uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; @@ -1463,6 +1463,7 @@ void *nr_dlsch_decoding_process(void *arg) } } + harq_process->round =0; if (harq_process->round == 0) { // This is a new packet, so compute quantities regarding segmentation if (A > 3824) @@ -1482,8 +1483,9 @@ void *nr_dlsch_decoding_process(void *arg) p_decParams->Z = harq_process->Z; } + + //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG); - p_decParams->numMaxIter = dlsch->max_ldpc_iterations; p_decParams->outMode= 0; @@ -1654,9 +1656,9 @@ void *nr_dlsch_decoding_process(void *arg) #endif // LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); - for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ + /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ inv_d[cnt] = (1)*harq_process->d[r][cnt]; - } + }*/ memset(pv,0,2*p_decParams->Z*sizeof(int16_t)); //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); @@ -1746,11 +1748,9 @@ void *dlsch_thread(void *arg) { int nbDlProcessing=0; initNotifiedFIFO_nothreadSafe(&freeBlocks); - for (int i=0; i Date: Thu, 19 Dec 2019 09:06:08 +0100 Subject: [PATCH 105/134] adding vcd --- executables/nr-uesoftmodem.c | 6 +++ .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 54 +++++++++---------- openair1/SCHED_NR_UE/defs.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 8 ++- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 0655af8de0..221606c5ee 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -27,6 +27,7 @@ #include "assertions.h" #include "PHY/types.h" #include "PHY/defs_nr_UE.h" +#include "SCHED_NR_UE/defs.h" #include "common/ran_context.h" #include "common/config/config_userapi.h" //#include "common/utils/threadPool/thread-pool.h" @@ -206,7 +207,10 @@ int oaisim_flag=0; int emulate_rf = 0; tpool_t *Tpool; +#ifdef UE_DLSCH_PARALLELISATION tpool_t *Tpool_dl; +#endif + char *usrp_args=NULL; @@ -675,10 +679,12 @@ int main( int argc, char **argv ) { Tpool = &pool; char params[]="-1,-1"; initTpool(params, Tpool, false); +#ifdef UE_DLSCH_PARALLELISATION tpool_t pool_dl; Tpool_dl = &pool_dl; char params_dl[]="-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1"; initTpool(params_dl, Tpool_dl, false); +#endif cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index ec35e76272..15a7e2a8a7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -257,6 +257,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, __m128i *pv = (__m128i*)&z; __m128i *pl = (__m128i*)&l; + + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0]; @@ -312,8 +314,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, LOG_I(PHY,"DLSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); - if ((harq_process->R)<1024) Coderate = (float) (harq_process->R) /(float) 1024; else @@ -374,7 +374,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #endif } - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); p_decParams->Z = harq_process->Z; //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); @@ -424,14 +424,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, start_meas(dlsch_deinterleaving_stats); #endif - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN); nr_deinterleaving_ldpc(E, harq_process->Qm, harq_process->w[r], // [hna] w is e dlsch_llr+r_offset); - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT); //for (int i =0; i<16; i++) // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); @@ -456,7 +456,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->round); #endif - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN); if ((harq_process->Nl)<4) Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C); @@ -473,7 +473,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->rvidx, (harq_process->round==0)?1:0, E)==-1) { - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif @@ -481,7 +481,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations + 1); } else { - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif @@ -552,7 +551,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); no_iteration_ldpc = nrLDPC_decoder(p_decParams, (int8_t*)&pl[0], @@ -560,7 +559,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, p_nrLDPC_procBuf[r], p_procTime); - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT); // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { @@ -686,7 +685,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, printf("C %d\n",harq_process->C); */ - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN); for (r=0; rC; r++) { @@ -721,7 +720,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT); dlsch->last_iteration_cnt = ret; @@ -794,6 +793,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_t nf; initNotifiedFIFO(&nf); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); if (!dlsch_llr) { printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); @@ -845,7 +845,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, G = harq_process->G; - LOG_I(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); + LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); proc->decoder_main_available = 1; @@ -1112,7 +1112,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); #endif - LOG_I(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ inv_d[cnt] = (1)*harq_process->d[r][cnt]; @@ -1162,9 +1162,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, ret = 1+dlsch->max_ldpc_iterations; } - //if (!nb_total_decod%10000){ - printf("Error number of iteration LPDC %d %lu/%lu \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); - //} + if (!nb_total_decod%10000){ + printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); + } //else //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); @@ -1269,21 +1269,13 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3); printf("C %d\n",harq_process->C); */ - uint32_t wait = 0; - /*if (harq_process->C==2){ - while((proc->decoder_thread_available == 0) ) + //uint32_t wait = 0; + + /* while((proc->decoder_thread_available == 0) ) { usleep(1); - wait++; } - } - else if ((harq_process->C==3) ){ - while((proc->decoder_thread_available == 0) || (proc->decoder_thread_available1 == 0)) - { - usleep(1); - wait++; - } - }*/ + proc->decoder_thread_available == 0;*/ /*notifiedFIFO_elt_t *res1=tryPullTpool(&nf, Tpool); if (!res1) { @@ -1291,6 +1283,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, usleep(1); wait++; }*/ + + //usleep(50); proc->decoder_main_available = 0; Kr = harq_process->K; //to check if same K in all segments @@ -1313,6 +1307,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, harq_process->c[r]); #endif } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); dlsch->last_iteration_cnt = ret; //proc->decoder_thread_available = 0; diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index cd61302304..8e42149add 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -44,7 +44,7 @@ #define OPENAIR_THREAD_STACK_SIZE PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6 //#define DLC_THREAD_STACK_SIZE 4096 //DLC stack size //#define UE_SLOT_PARALLELISATION -#define UE_DLSCH_PARALLELISATION +//#define UE_DLSCH_PARALLELISATION /*enum openair_SCHED_STATUS { openair_SCHED_STOPPED=1, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 60378d81fc..9bb582dd6e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2624,6 +2624,8 @@ void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0 //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[eNB_id]); phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[eNB_id],eNB_id); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT); } @@ -4146,6 +4148,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, uint8_t dci_cnt = 0; fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); + LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); /* @@ -4278,7 +4282,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, #endif // do procedures for C-RNTI if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, proc, eNB_id, @@ -4298,7 +4302,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0); */ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } // do procedures for SI-RNTI From 896463a9a8297cd2e321278bb5a2fe41b55e0511 Mon Sep 17 00:00:00 2001 From: Hongzhi Wang Date: Thu, 19 Dec 2019 17:03:23 +0100 Subject: [PATCH 106/134] update dlsch thread --- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 15a7e2a8a7..b3a95e313e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -51,8 +51,9 @@ static uint64_t nb_total_decod =0; static uint64_t nb_error_decod =0; -notifiedFIFO_t freeBlocks; -notifiedFIFO_elt_t *msgToPush; +notifiedFIFO_t freeBlocks_dl; +notifiedFIFO_elt_t *msgToPush_dl; +int nbDlProcessing =0; //extern double cpuf; @@ -787,6 +788,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value; uint32_t i,j; +// int nbDlProcessing =0; __m128i *pv = (__m128i*)&z; __m128i *pl = (__m128i*)&l; @@ -939,17 +941,20 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif - notifiedFIFO_elt_t *res; + notifiedFIFO_elt_t *res_dl; opp_enabled=1; if (harq_process->C>1) { for (int nb_seg =1 ; nb_segC; nb_seg++){ - if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) { - pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); + if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) { + pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl); } - AssertFatal((msgToPush=pullNotifiedFIFO_nothreadSafe(&freeBlocks)) != NULL,"chained list failure"); - nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush); + AssertFatal((msgToPush_dl=pullNotifiedFIFO_nothreadSafe(&freeBlocks_dl)) != NULL,"chained list failure"); + nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush_dl); curMsg->UE=phy_vars_ue; + + nbDlProcessing++; + memset(&curMsg->proc, 0, sizeof(curMsg->proc)); curMsg->proc.frame_rx = proc->frame_rx; @@ -960,8 +965,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, curMsg->proc.harq_pid=harq_pid; curMsg->proc.llr8_flag = llr8_flag; - msgToPush->key=nb_seg; - pushTpool(Tpool_dl, msgToPush); + msgToPush_dl->key= (nr_tti_rx%2) ? (nb_seg+30): nb_seg; + pushTpool(Tpool_dl, msgToPush_dl); /*Qm= harq_process->Qm; Nl=harq_process->Nl; @@ -1741,11 +1746,11 @@ void *dlsch_thread(void *arg) { PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; notifiedFIFO_t nf; initNotifiedFIFO(&nf); - int nbDlProcessing=0; - initNotifiedFIFO_nothreadSafe(&freeBlocks); + notifiedFIFO_elt_t *res_dl; + initNotifiedFIFO_nothreadSafe(&freeBlocks_dl); for (int i=0; i= RX_NB_TH_DL) { if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) { nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData; - nbDlProcessing--; - pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); + //nbDlProcessing--; + pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res); } usleep(200); } + + res_dl=pullTpool(&nf, Tpool_dl); + nbDlProcessing--; + pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl); + - nbDlProcessing++; //msgToPush->key=0; //pushTpool(Tpool, msgToPush); From a99612a536dd2926309096caf2bded59e1f8f3ea Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 20 Dec 2019 12:40:26 +0100 Subject: [PATCH 107/134] make nb_re_dmrs a parameter of nr_ulsch_decoding() --- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 2 ++ openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/defs_gNB.h | 2 -- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 8 ++++---- openair1/SIMULATION/NR_PHY/ulschsim.c | 5 +++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index dc7489ea51..d56c298e4f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -43,6 +43,7 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 @param ulsch_llr, Pointer to received llr in ulsch @param frame_parms, Pointer to frame descriptor structure @param nb_symb_sch, number of symbols used in the uplink shared channel + @param nb_re_dmrs, number of DMRS resource elements in one RB @param nr_tti_rx, current received TTI @param harq_pid, harq process id @param is_crnti @@ -54,6 +55,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, NR_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint16_t nb_symb_sch, + uint16_t nb_re_dmrs, uint8_t nr_tti_rx, uint8_t harq_pid, uint8_t is_crnti); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index c3197abe66..39c6d8f5ba 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -281,6 +281,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, NR_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint16_t nb_symb_sch, + uint16_t nb_re_dmrs, uint8_t nr_tti_rx, uint8_t harq_pid, uint8_t is_crnti) @@ -323,7 +324,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint16_t R = nfapi_ulsch_pdu_rel15->R; uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs; uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers; - uint16_t nb_re_dmrs = harq_process->nb_re_dmrs; uint8_t length_dmrs = nfapi_ulsch_pdu_rel15->length_dmrs; // ------------------------------------------------------------------ diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 6e5382add6..3c0f0db8da 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -246,8 +246,6 @@ typedef struct { /// This is needed for PHICH generation which /// is done after a new scheduling uint8_t previous_n_DMRS; - /// number of DMRS resource elements in one RB - uint16_t nb_re_dmrs; ////////////////////////////////////////////////////////////// diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9c36ae740f..cc338a5738 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -229,10 +229,9 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id uint8_t mapping_type; uint32_t G; int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled) - uint16_t start_symbol, number_symbols; + uint16_t start_symbol, number_symbols, nb_re_dmrs; mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; - gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs = 0; start_symbol = nfapi_ulsch_pdu_rel15->start_symbol; number_symbols = nfapi_ulsch_pdu_rel15->number_symbols; @@ -249,11 +248,11 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id mapping_type, frame_parms->ofdm_symbol_size); - gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; + nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, number_symbols, - gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->nb_re_dmrs, + nb_re_dmrs, nfapi_ulsch_pdu_rel15->length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers); @@ -279,6 +278,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id frame_parms, frame_rx, number_symbols, + nb_re_dmrs, slot_rx, harq_pid, 0); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 5e1a8d2158..19d84e8f8f 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -382,7 +382,8 @@ int main(int argc, char **argv) uint8_t UE_id = 0; NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; - nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + NR_UL_gNB_HARQ_t *harq_process_gNB = ulsch_gNB->harq_processes[harq_pid]; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &harq_process_gNB->ulsch_pdu.ulsch_pdu_rel15; NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; @@ -524,7 +525,7 @@ int main(int argc, char **argv) #endif ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, - frame, nb_symb_sch, subframe, harq_pid, is_crnti); + frame, nb_symb_sch, nb_re_dmrs, subframe, harq_pid, is_crnti); if (ret > ulsch_gNB->max_ldpc_iterations) n_errors++; From aaaa6d5c51fa2dd985e1dde8be9802d189717b02 Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 20 Dec 2019 16:44:25 +0100 Subject: [PATCH 108/134] more cppcheck fixes --- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 21 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 33 +-- openair2/ENB_APP/enb_config.c | 199 ++++++++-------- openair2/ENB_APP/enb_paramdef.h | 220 +++++++++--------- openair2/ENB_APP/enb_paramdef_emtc.h | 162 ++++++------- openair2/NETWORK_DRIVER/UE_IP/common.c | 2 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 11 +- targets/RT/USER/lte-hwlat2.c | 2 +- 8 files changed, 326 insertions(+), 324 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 3c6784be7e..ea90111bcc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -253,6 +253,7 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext, avg128P = _mm_setzero_si128(); dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][0]; #elif defined(__arm__) + dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][0]; #endif for (rb=0; rb<(nb_rb*3)>>2; rb++) { @@ -375,7 +376,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, * then the IQ symbol is going to be found at the position 0+c_rb-N_RB_DL/2 in rxdataF and * we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF */ - LOG_DDD("n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); + LOG_DDD("n_BWP_start=%u, coreset_nbr_rb=%u\n",n_BWP_start,coreset_nbr_rb); for (c_rb = n_BWP_start; c_rb < (n_BWP_start + coreset_nbr_rb + (BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN * offset_discontiguous)); c_rb++) { //c_rb_tmp = 0; @@ -762,8 +763,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } } - LOG_DD("symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); - LOG_DD("coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", + LOG_DD("symbol_mon=(%u) and start_symbol=(%u)\n",symbol_mon,start_symbol); + LOG_DD("coreset_freq_dom=(%lu) n_rb_offset=(%u) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R,pdcch_DMRS_scrambling_id); // // according to 38.213 v15.1.0: a PDCCH monitoring pattern within a slot, @@ -780,7 +781,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // for (int j=0; j < coreset_nbr_act; j++) { // for each active CORESET (max number of active CORESETs in a BWP is 3), // we calculate the number of RB for each CORESET bitmap - LOG_DD("coreset_freq_dom=(%ld)\n",coreset_freq_dom); + LOG_DD("coreset_freq_dom=(%lu)\n",coreset_freq_dom); int i; //for each bit in the coreset_freq_dom bitmap for (i = 0; i < 45; i++) { @@ -789,8 +790,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_nbr_rb has to be multiplied by 6 to indicate the number of PRB or REG(=12 RE) within the CORESET - LOG_DD("coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); - LOG_DD("coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", + LOG_DD("coreset_freq_dom=(%lu,%lx), coreset_nbr_rb=%u\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); + LOG_DD("coreset_nbr_rb=%u, coreset_nbr_reg=%u, coreset_C=(%u/(%d*%d))=%u\n", coreset_nbr_rb, coreset_time_dur * coreset_nbr_rb, coreset_time_dur * coreset_nbr_rb, @@ -1163,9 +1164,9 @@ void nr_dci_decoding_procedure0(int s, LOG_DDD("debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",nCCE[p] / L2,p,nCCE[p],L2); LOG_DDD("debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",L2*m_p_s_L_max,L2,m_p_s_L_max); CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2); - LOG_DDD("CCEind(%d) = (((Yk(%u) + ((m(%u)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n", + LOG_DDD("CCEind(%u) = (((Yk(%u) + ((m(%u)*nCCE[p](%u))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n", CCEind,Yk,m,nCCE[p],L2,m_p_s_L_max); - LOG_DDD("n_candidate(m)=%u | CCEind=%d |",m,CCEind); + LOG_DDD("n_candidate(m)=%u | CCEind=%u |",m,CCEind); if (CCEind < 32) CCEmap = CCEmap0; @@ -1173,7 +1174,7 @@ void nr_dci_decoding_procedure0(int s, CCEmap = CCEmap1; else if (CCEind < 96) CCEmap = CCEmap2; - else AssertFatal(1==0,"Illegal CCEind %d (Yk %u, m %u, nCCE %d, L2 %d\n", CCEind, Yk, m, nCCE[p], L2); + else AssertFatal(1==0,"Illegal CCEind %u (Yk %u, m %u, nCCE %u, L2 %u\n", CCEind, Yk, m, nCCE[p], L2); switch (L2) { case 1: @@ -1220,7 +1221,7 @@ void nr_dci_decoding_procedure0(int s, LOG_DDD("... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); LOG_DDD("... we have to replace this part of the code by polar decoding\n"); // for (int m=0; m < (nCCE[p]*6*9*2); m++) - LOG_DDD("(polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", + LOG_DDD("(polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%u): \n", coreset_time_dur,coreset_nbr_rb,p,CCEind); /* int reg_p=0,reg_e=0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 8f810d36d3..1089c08542 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -380,10 +380,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", + printf("[AbsSFN %u.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", frame,nr_tti_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", frame,nr_tti_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -404,9 +404,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -483,9 +483,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -596,9 +596,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif // MRC @@ -641,9 +641,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -1018,9 +1018,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif // Please keep it: useful for debugging @@ -1091,7 +1091,7 @@ void nr_dlsch_deinterleaving(uint8_t symbol, uint32_t *bundle_deint = malloc(N_bundle*sizeof(uint32_t)); - printf("N_bundle %d L %d nb_rb_pdsch %d\n",N_bundle, L,nb_rb_pdsch); + printf("N_bundle %u L %d nb_rb_pdsch %d\n",N_bundle, L,nb_rb_pdsch); if (symbol==start_symbol) nb_re = 6; @@ -1117,6 +1117,7 @@ void nr_dlsch_deinterleaving(uint8_t symbol, //printf("k %d m %d bundle_deint %d llr_deint %d\n", k, m, bundle_deint[k], llr_deint[bundle_deint[k]*nb_re*L+m]); } } + free(bundle_deint); } //============================================================================================== @@ -2455,7 +2456,7 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, int prb,nb_rb=0; unsigned short k; int i,j,aarx; - int32_t *dl_ch0=NULL,*dl_ch0p=NULL,*dl_ch0_ext=NULL,*dl_ch1=NULL,*dl_ch1p=NULL,*dl_ch1_ext=NULL,*rxF=NULL,*rxF_ext=NULL; + int32_t *dl_ch0=NULL,*dl_ch0_ext=NULL,*dl_ch1=NULL,*dl_ch1_ext=NULL,*rxF=NULL,*rxF_ext=NULL; k = frame_parms->first_carrier_offset + 516; //0 @@ -2511,8 +2512,8 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, if ((i&1)!=frame_parms->nushift) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0p[i]; - dl_ch1_ext[j++]=dl_ch1p[i]; + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; } } dl_ch0_ext+=6; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2082663fce..06386adbb7 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -183,7 +183,7 @@ void RCconfig_L1(void) { if (RC.eNB[j] == NULL) { RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB **)); LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); - memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB ** *)); + memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***)); } for (i=0; i0) { // Output a list of all eNBs. @@ -334,7 +335,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) { paramdef_t SCTPParams[] = SCTPPARAMS_DESC; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,i,ENB_CONFIG_STRING_SCTP_CONFIG); + sprintf(aprefix,"%s.[%u].%s",ENB_CONFIG_STRING_ENB_LIST,i,ENB_CONFIG_STRING_SCTP_CONFIG); config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); rrc->node_id = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr); LOG_I(ENB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id); @@ -443,16 +444,16 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { // Cell params, MIB/SIB1 in DU RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config; AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", + "Failed to parse eNB configuration file %s, enb %u illegal tdd_config %d (should be 0-%d)!", RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6); RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s; AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", + "Failed to parse eNB configuration file %s, enb %u illegal tdd_config_s %d (should be 0-%d)!", RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8); if (!ccparams_lte.prefix_type) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: NORMAL,EXTENDED!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) { RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; @@ -460,13 +461,13 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", RC.config_file_name, i, ccparams_lte.prefix_type); } if (!ccparams_lte.pbch_repetition) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: TRUE,FALSE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION); else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) { RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1; @@ -474,7 +475,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n", RC.config_file_name, i, ccparams_lte.pbch_repetition); } @@ -485,7 +486,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if (ccparams_lte.Nid_cell>503) { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for Nid_cell choice: 0...503 !\n", RC.config_file_name, i, ccparams_lte.Nid_cell); } @@ -498,7 +499,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", RC.config_file_name, i, ccparams_lte.N_RB_DL); } @@ -508,7 +509,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for frame_type choice: FDD or TDD !\n", RC.config_file_name, i, ccparams_lte.frame_type); } @@ -522,7 +523,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n", RC.config_file_name, i, ccparams_lte.nb_antenna_ports); RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports; @@ -533,19 +534,19 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.prach_root <0) || (ccparams_lte.prach_root > 1023)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_root choice: 0..1023 !\n", RC.config_file_name, i, ccparams_lte.prach_root); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_config_index = ccparams_lte.prach_config_index; if ((ccparams_lte.prach_config_index <0) || (ccparams_lte.prach_config_index > 63)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", RC.config_file_name, i, ccparams_lte.prach_config_index); if (!ccparams_lte.prach_high_speed) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE; @@ -553,7 +554,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.prach_high_speed); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_zero_correlation = ccparams_lte.prach_zero_correlation; @@ -561,7 +562,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.prach_zero_correlation <0) || (ccparams_lte.prach_zero_correlation > 15)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", RC.config_file_name, i, ccparams_lte.prach_zero_correlation); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_freq_offset = ccparams_lte.prach_freq_offset; @@ -569,7 +570,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.prach_freq_offset <0) || (ccparams_lte.prach_freq_offset > 94)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", RC.config_file_name, i, ccparams_lte.prach_freq_offset); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_delta_shift = ccparams_lte.pucch_delta_shift-1; @@ -577,7 +578,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pucch_delta_shift <1) || (ccparams_lte.pucch_delta_shift > 3)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", RC.config_file_name, i, ccparams_lte.pucch_delta_shift); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nRB_CQI = ccparams_lte.pucch_nRB_CQI; @@ -585,7 +586,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pucch_nRB_CQI <0) || (ccparams_lte.pucch_nRB_CQI > 98)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", RC.config_file_name, i, ccparams_lte.pucch_nRB_CQI); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nCS_AN = ccparams_lte.pucch_nCS_AN; @@ -593,7 +594,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pucch_nCS_AN <0) || (ccparams_lte.pucch_nCS_AN > 7)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", RC.config_file_name, i, ccparams_lte.pucch_nCS_AN); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_n1_AN = ccparams_lte.pucch_n1_AN; @@ -601,7 +602,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pucch_n1_AN <0) || (ccparams_lte.pucch_n1_AN > 2047)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", RC.config_file_name, i, ccparams_lte.pucch_n1_AN); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_referenceSignalPower = ccparams_lte.pdsch_referenceSignalPower; @@ -609,7 +610,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pdsch_referenceSignalPower <-60) || (ccparams_lte.pdsch_referenceSignalPower > 50)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", RC.config_file_name, i, ccparams_lte.pdsch_referenceSignalPower); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_p_b = ccparams_lte.pdsch_p_b; @@ -617,7 +618,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pdsch_p_b <0) || (ccparams_lte.pdsch_p_b > 3)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", RC.config_file_name, i, ccparams_lte.pdsch_p_b); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_n_SB = ccparams_lte.pusch_n_SB; @@ -625,12 +626,12 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pusch_n_SB <1) || (ccparams_lte.pusch_n_SB > 4)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", RC.config_file_name, i, ccparams_lte.pusch_n_SB); if (!ccparams_lte.pusch_hoppingMode) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: interSubframe,intraAndInterSubframe!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE); else if (strcmp(ccparams_lte.pusch_hoppingMode,"interSubFrame")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; @@ -638,7 +639,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", RC.config_file_name, i, ccparams_lte.pusch_hoppingMode); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingOffset = ccparams_lte.pusch_hoppingOffset; @@ -646,12 +647,12 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pusch_hoppingOffset<0) || (ccparams_lte.pusch_hoppingOffset>98)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", RC.config_file_name, i, ccparams_lte.pusch_hoppingMode); if (!ccparams_lte.pusch_enable64QAM) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE; @@ -659,12 +660,12 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", RC.config_file_name, i, ccparams_lte.pusch_enable64QAM); if (!ccparams_lte.pusch_groupHoppingEnabled) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE; @@ -672,7 +673,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", RC.config_file_name, i, ccparams_lte.pusch_groupHoppingEnabled); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupAssignment = ccparams_lte.pusch_groupAssignment; @@ -680,12 +681,12 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pusch_groupAssignment<0)|| (ccparams_lte.pusch_groupAssignment>29)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", RC.config_file_name, i, ccparams_lte.pusch_groupAssignment); if (!ccparams_lte.pusch_sequenceHoppingEnabled) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE; @@ -693,7 +694,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", RC.config_file_name, i, ccparams_lte.pusch_sequenceHoppingEnabled); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_nDMRS1= ccparams_lte.pusch_nDMRS1; //cyclic_shift in RRC! @@ -701,7 +702,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pusch_nDMRS1 <0) || (ccparams_lte.pusch_nDMRS1>7)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", RC.config_file_name, i, ccparams_lte.pusch_nDMRS1); if (strcmp(ccparams_lte.phich_duration,"NORMAL")==0) { @@ -710,7 +711,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_extended; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", RC.config_file_name, i, ccparams_lte.phich_duration); if (strcmp(ccparams_lte.phich_resource,"ONESIXTH")==0) { @@ -723,7 +724,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_two; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", RC.config_file_name, i, ccparams_lte.phich_resource); printf("phich.resource %ld (%s), phich.duration %ld (%s)\n", @@ -736,7 +737,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_enable); if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) { @@ -744,7 +745,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.srs_BandwidthConfig < 0) || (ccparams_lte.srs_BandwidthConfig >7)) - AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n", + AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value %d for srs_BandwidthConfig choice: 0...7\n", RC.config_file_name, i, ccparams_lte.srs_BandwidthConfig); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_SubframeConfig= ccparams_lte.srs_SubframeConfig; @@ -752,7 +753,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.srs_SubframeConfig<0) || (ccparams_lte.srs_SubframeConfig>15)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", RC.config_file_name, i, ccparams_lte.srs_SubframeConfig); if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) { @@ -761,7 +762,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_ackNackST); if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) { @@ -770,7 +771,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_MaxUpPts); } @@ -779,7 +780,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pusch_p0_Nominal<-126) || (ccparams_lte.pusch_p0_Nominal>24)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", RC.config_file_name, i, ccparams_lte.pusch_p0_Nominal); if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) { @@ -800,7 +801,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al1; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", RC.config_file_name, i, ccparams_lte.pusch_alpha); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_p0_Nominal= ccparams_lte.pucch_p0_Nominal; @@ -808,7 +809,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.pucch_p0_Nominal<-127) || (ccparams_lte.pucch_p0_Nominal>-96)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", RC.config_file_name, i, ccparams_lte.pucch_p0_Nominal); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].msg3_delta_Preamble= ccparams_lte.msg3_delta_Preamble; @@ -816,7 +817,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.msg3_delta_Preamble<-1) || (ccparams_lte.msg3_delta_Preamble>6)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", RC.config_file_name, i, ccparams_lte.msg3_delta_Preamble); if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF_2")==0) { @@ -827,7 +828,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1); if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF1")==0) { @@ -838,7 +839,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1b); if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF_2")==0) { @@ -851,7 +852,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2); if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF_2")==0) { @@ -862,7 +863,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2a); if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF_2")==0) { @@ -873,7 +874,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2b); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_numberOfRA_Preambles= (ccparams_lte.rach_numberOfRA_Preambles/4)-1; @@ -882,7 +883,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.rach_numberOfRA_Preambles>64) || ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles); if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) { @@ -893,7 +894,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.rach_numberOfRA_Preambles>60) || ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", RC.config_file_name, i, ccparams_lte.rach_sizeOfRA_PreamblesGroupA); switch (ccparams_lte.rach_messageSizeGroupA) { @@ -915,7 +916,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", RC.config_file_name, i, ccparams_lte.rach_messageSizeGroupA); break; } @@ -938,13 +939,13 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB); } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE; } else AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.rach_preamblesGroupAConfig); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleInitialReceivedTargetPower= (ccparams_lte.rach_preambleInitialReceivedTargetPower+120)/2; @@ -953,7 +954,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.rach_preambleInitialReceivedTargetPower>-90) || ((ccparams_lte.rach_preambleInitialReceivedTargetPower&1)!=0)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", RC.config_file_name, i, ccparams_lte.rach_preambleInitialReceivedTargetPower); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_powerRampingStep= ccparams_lte.rach_powerRampingStep/2; @@ -962,7 +963,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.rach_powerRampingStep>6) || ((ccparams_lte.rach_powerRampingStep&1)!=0)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", RC.config_file_name, i, ccparams_lte.rach_powerRampingStep); switch (ccparams_lte.rach_preambleTransMax) { @@ -1012,7 +1013,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); break; } @@ -1023,7 +1024,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.rach_raResponseWindowSize==9)|| (ccparams_lte.rach_raResponseWindowSize>10)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_macContentionResolutionTimer= (ccparams_lte.rach_macContentionResolutionTimer/8)-1; @@ -1032,7 +1033,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { (ccparams_lte.rach_macContentionResolutionTimer>64) || ((ccparams_lte.rach_macContentionResolutionTimer&7)!=0)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_maxHARQ_Msg3Tx= ccparams_lte.rach_maxHARQ_Msg3Tx; @@ -1040,7 +1041,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.rach_maxHARQ_Msg3Tx<0) || (ccparams_lte.rach_maxHARQ_Msg3Tx>8)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); switch (ccparams_lte.pcch_defaultPagingCycle) { @@ -1062,7 +1063,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", RC.config_file_name, i, ccparams_lte.pcch_defaultPagingCycle); break; } @@ -1084,7 +1085,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { } else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT; } else { - AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", + AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", RC.config_file_name, i, ccparams_lte.pcch_nB); @@ -1098,7 +1099,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_setup; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_Config_present choice: prNothing, prRelease, prSetup!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_Config_present choice: prNothing, prRelease, prSetup!\n", RC.config_file_name, i, ccparams_lte.drx_Config_present); } @@ -1136,7 +1137,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf200; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_onDurationTimer choice !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_onDurationTimer choice !\n", RC.config_file_name, i, ccparams_lte.drx_onDurationTimer); break; } @@ -1207,7 +1208,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare1; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_InactivityTimer choice !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_InactivityTimer choice !\n", RC.config_file_name, i, ccparams_lte.drx_InactivityTimer); break; } @@ -1216,7 +1217,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if (!ccparams_lte.mbms_dedicated_serving_cell) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", + "Failed to parse eNB configuration file %s, enb %u define %s: TRUE,FALSE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL); else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = TRUE; @@ -1224,7 +1225,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = FALSE; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for mbms_dedicated_serving_cell choice: TRUE or FALSE !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for mbms_dedicated_serving_cell choice: TRUE or FALSE !\n", RC.config_file_name, i, ccparams_lte.mbms_dedicated_serving_cell); } @@ -1233,7 +1234,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.ue_multiple_max < 1) || (ccparams_lte.ue_multiple_max > 4)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", RC.config_file_name, i, ccparams_lte.ue_multiple_max); break; @@ -1242,7 +1243,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.ue_multiple_max < 1) || (ccparams_lte.ue_multiple_max > 8)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", RC.config_file_name, i, ccparams_lte.ue_multiple_max); break; @@ -1251,14 +1252,14 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.ue_multiple_max < 1) || (ccparams_lte.ue_multiple_max > 16)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", RC.config_file_name, i, ccparams_lte.ue_multiple_max); break; default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", RC.config_file_name, i, ccparams_lte.N_RB_DL); break; } @@ -1281,7 +1282,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf33; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_RetransmissionTimer choice !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_RetransmissionTimer choice !\n", RC.config_file_name, i, ccparams_lte.drx_RetransmissionTimer); break; } @@ -1339,7 +1340,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { offsetMaxLimit = 2560; } else { AssertFatal (0, - "Failed to parse eNB configuration file \"%s\", enb %d unknown string value \"%s\" for drx_longDrx_CycleStartOffset_present choice !\n", + "Failed to parse eNB configuration file \"%s\", enb %u unknown string value \"%s\" for drx_longDrx_CycleStartOffset_present choice !\n", RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset_present); } @@ -1347,7 +1348,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset = ccparams_lte.drx_longDrx_CycleStartOffset; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d incoherent value \"%d\" for drx_longDrx_CycleStartOffset !\n", + "Failed to parse eNB configuration file %s, enb %u incoherent value \"%d\" for drx_longDrx_CycleStartOffset !\n", RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset); } } @@ -1355,7 +1356,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") == 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer == 0) { if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") != 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer != 0) { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d incoherent values \"%s\" - \"%d\" for drx_shortDrx_Cycle or drx_shortDrx_ShortCycleTimer choice !\n", + "Failed to parse eNB configuration file %s, enb %u incoherent values \"%s\" - \"%d\" for drx_shortDrx_Cycle or drx_shortDrx_ShortCycleTimer choice !\n", RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle, ccparams_lte.drx_shortDrx_ShortCycleTimer); } else { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = -1; @@ -1412,13 +1413,13 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf640; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d incoherent value \"%s\" for drx_shortDrx_Cycle !\n", + "Failed to parse eNB configuration file %s, enb %u incoherent value \"%s\" for drx_shortDrx_Cycle !\n", RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle); } if (cycleNb > 0 && (offsetMaxLimit % cycleNb != 0 || cycleNb == offsetMaxLimit)) { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d incompatible (not multiple) values \"%d\" - \"%d\" for drx_shortDrx_Cycle and drx_longDrx_CycleStartOffset choice !\n", + "Failed to parse eNB configuration file %s, enb %u incompatible (not multiple) values \"%d\" - \"%d\" for drx_shortDrx_Cycle and drx_longDrx_CycleStartOffset choice !\n", RC.config_file_name, i, cycleNb, offsetMaxLimit); } @@ -1426,7 +1427,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = ccparams_lte.drx_shortDrx_ShortCycleTimer; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for drx_shortDrx_ShortCycleTimer choice !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for drx_shortDrx_ShortCycleTimer choice !\n", RC.config_file_name, i, ccparams_lte.drx_shortDrx_ShortCycleTimer ); } } @@ -1450,7 +1451,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", RC.config_file_name, i, ccparams_lte.bcch_modificationPeriodCoeff); break; } @@ -1493,7 +1494,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", RC.config_file_name, i, ccparams_lte.ue_TransmissionMode); break; } @@ -1505,7 +1506,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.ue_multiple_max < 1) || (ccparams_lte.ue_multiple_max > 4)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", RC.config_file_name, i, ccparams_lte.ue_multiple_max); break; @@ -1514,7 +1515,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.ue_multiple_max < 1) || (ccparams_lte.ue_multiple_max > 8)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", RC.config_file_name, i, ccparams_lte.ue_multiple_max); break; @@ -1523,14 +1524,14 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { if ((ccparams_lte.ue_multiple_max < 1) || (ccparams_lte.ue_multiple_max > 16)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", RC.config_file_name, i, ccparams_lte.ue_multiple_max); break; default: AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", + "Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", RC.config_file_name, i, ccparams_lte.N_RB_DL); break; } @@ -1599,7 +1600,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_max_retx_threshold %u!\n", + "Bad config value when parsing eNB configuration file %s, enb %u srb1_max_retx_threshold %d!\n", RC.config_file_name, i, srb1_params.srb1_max_retx_threshold); } @@ -1637,7 +1638,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity; else AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_pdu %u!\n", + "Bad config value when parsing eNB configuration file %s, enb %u srb1_poll_pdu %d!\n", RC.config_file_name, i, srb1_params.srb1_poll_pdu); } @@ -1705,7 +1706,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { rrc->srb1_poll_byte = LTE_PollByte_kBinfinity; else AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_byte %u!\n", + "Bad config value when parsing eNB configuration file %s, enb %u srb1_poll_byte %d!\n", RC.config_file_name, i, srb1_params.srb1_poll_byte); } @@ -1715,7 +1716,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 300)/50 + 50; } else { AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_poll_retransmit %u!\n", + "Bad config value when parsing eNB configuration file %s, enb %u srb1_timer_poll_retransmit %d!\n", RC.config_file_name, i, srb1_params.srb1_timer_poll_retransmit); } @@ -1725,7 +1726,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { rrc->srb1_timer_status_prohibit = (srb1_params.srb1_timer_status_prohibit - 300)/50 + 51; } else { AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_status_prohibit %u!\n", + "Bad config value when parsing eNB configuration file %s, enb %u srb1_timer_status_prohibit %d!\n", RC.config_file_name, i, srb1_params.srb1_timer_status_prohibit); } @@ -1856,7 +1857,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { default: AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_reordering %u!\n", + "Bad config value when parsing eNB configuration file %s, enb %u srb1_timer_reordering %d!\n", RC.config_file_name, i, srb1_params.srb1_timer_reordering); } } @@ -1879,13 +1880,13 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) { config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); int num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; AssertFatal (i0) { // Output a list of all eNBs. config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); AssertFatal(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr != NULL, - "eNB id %d is not defined in configuration file\n",i); + "eNB id %u is not defined in configuration file\n",i); F1AP_SETUP_REQ (msg_p).num_cells_available = 0; for (k=0; k stats.tx_dropped ++; return; } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index b15299418e..48cc432a06 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -187,9 +187,8 @@ uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_ LTE_BCCH_BCH_Message_MBMS_t *mib_fembms=&carrier->mib_fembms; uint8_t sfn = (uint8_t)((frame>>2)&0xff); uint16_t *spare = calloc(1,sizeof(uint16_t)); - uint16_t *additionalNonMBSFNSubframes = calloc(1,sizeof(uint16_t)); - if( spare == NULL || additionalNonMBSFNSubframes == NULL ) abort(); + if( spare == NULL ) abort(); switch (N_RB_DL) { case 6: @@ -217,7 +216,7 @@ uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_ break; default: - AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); + AssertFatal(1==0,"Unknown dl_Bandwidth %u\n",N_RB_DL); } LOG_I(RRC,"[MIB] systemBandwidth %x, additional non MBMS subframes %x, sfn %x\n", @@ -287,7 +286,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich break; default: - AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); + AssertFatal(1==0,"Unknown dl_Bandwidth %u\n",N_RB_DL); } AssertFatal(phich_Resource <= LTE_PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n"); @@ -1021,7 +1020,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13 = calloc(1, sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13)); memset(sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13, 0, - sizeof(sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13))); + sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13)); if (*configuration->fdd_DownlinkOrTddSubframeBitmapBR_r13[CC_id]) { sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13->present @@ -1183,7 +1182,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13 = calloc(1, sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13)); memset(sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13, 0, - sizeof(sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13))); + sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13)); sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13->present = LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__fdd_DownlinkOrTddSubframeBitmapBR_r13_PR_subframePattern10_r13; sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13->choice.subframePattern10_r13.buf = calloc(2, sizeof(uint8_t)); diff --git a/targets/RT/USER/lte-hwlat2.c b/targets/RT/USER/lte-hwlat2.c index 57d2dbaad1..85ec61e44f 100644 --- a/targets/RT/USER/lte-hwlat2.c +++ b/targets/RT/USER/lte-hwlat2.c @@ -1197,7 +1197,7 @@ void histogram_save_in_csv( histo_time_t *histo , char *file_sufix) fprintf( fp, "%d-%.0f;%u\n", min_val, histo[i].max, histo[i].count ); min_val = histo[i].max; } - + free(csv_filename); fclose( fp ); } From e0f509841c8b33aa4eb0ca327300317d58de694b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jan 2020 12:45:37 +0100 Subject: [PATCH 109/134] hotfix: fix value of MAX_MOBILES_PER_ENB set MAX_MOBILES_PER_ENB to 4, to be same value as NUMBER_OF_UE_MAX. Maybe we should set NUMBER_OF_UE_MAX to 16 instead? --- openair2/COMMON/platform_constants.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index ec257f5ceb..4c4348dce9 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -81,9 +81,9 @@ #define MAX_eNB 2 #define MAX_gNB 2 #else - #define MAX_MOBILES_PER_ENB 16 - #define MAX_MOBILES_PER_ENB_NB_IoT 16 - #define MAX_MOBILES_PER_GNB 16 + #define MAX_MOBILES_PER_ENB 4 + #define MAX_MOBILES_PER_ENB_NB_IoT 4 + #define MAX_MOBILES_PER_GNB 4 #define MAX_eNB 2 #define MAX_gNB 2 #endif From 477631bd23c1337e883deced6f165aee47116ebc Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jan 2020 12:45:37 +0100 Subject: [PATCH 110/134] hotfix: fix value of MAX_MOBILES_PER_ENB set MAX_MOBILES_PER_ENB to 4, to be same value as NUMBER_OF_UE_MAX. Maybe we should set NUMBER_OF_UE_MAX to 16 instead? --- openair2/COMMON/platform_constants.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index ec257f5ceb..4c4348dce9 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -81,9 +81,9 @@ #define MAX_eNB 2 #define MAX_gNB 2 #else - #define MAX_MOBILES_PER_ENB 16 - #define MAX_MOBILES_PER_ENB_NB_IoT 16 - #define MAX_MOBILES_PER_GNB 16 + #define MAX_MOBILES_PER_ENB 4 + #define MAX_MOBILES_PER_ENB_NB_IoT 4 + #define MAX_MOBILES_PER_GNB 4 #define MAX_eNB 2 #define MAX_gNB 2 #endif From c256932fe59ed8f1dcdef884cd0d035c3e60c9dd Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 11:47:42 +0100 Subject: [PATCH 111/134] CI: pipeline workaround for GitLab 'cancelled' status notification when failure See https://github.com/jenkinsci/pipeline-build-step-plugin/blob/master/CHANGELOG.md#210 for more details Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 74 ++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index d201405255..1ef73cac30 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -680,48 +680,50 @@ OAI CI Team''', // ---- Slave Job functions def triggerSlaveJob (jobName, gitlabStatusName) { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: gitlabStatusName) { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] + // Workaround for the "cancelled" GitLab pipeline notification + // The slave job is triggered with the propagate false so the following commands are executed + // Its status is now PASS/SUCCESS from a stage pipeline point of view + // localStatus variable MUST be analyzed to properly assess the status + localStatus = build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ], propagate: false + localResult = localStatus.getResult() + echo "${jobName} Slave Job status is ${localResult}" + gitlabCommitStatus(name: gitlabStatusName) { + if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) { + echo "${jobName} Slave Job is OK" + } else { + echo "${jobName} Slave Job is KO" + sh "ci-scripts/fail.sh" } - } else { - gitlabCommitStatus(name: gitlabStatusName) { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } } } def triggerSlaveJobNoGitLab (jobName) { - if ("MERGE".equals(env.gitlabActionType)) { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] + // Workaround for the "cancelled" GitLab pipeline notification + // The slave job is triggered with the propagate false so the following commands are executed + // Its status is now PASS/SUCCESS from a stage pipeline point of view + // localStatus variable MUST be analyzed to properly assess the status + localStatus = build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ], propagate: false + localResult = localStatus.getResult() + echo "${jobName} Slave Job status is ${localResult}" + if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) { + echo "${jobName} Slave Job is OK" } else { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] + echo "${jobName} Slave Job is KO" + sh "ci-scripts/fail.sh" } } From b8f58c5f928dbbc8ab29c99d2ffc3c7c8d291807 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 11:47:42 +0100 Subject: [PATCH 112/134] CI: pipeline workaround for GitLab 'cancelled' status notification when failure See https://github.com/jenkinsci/pipeline-build-step-plugin/blob/master/CHANGELOG.md#210 for more details Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 74 ++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index d16de8b7ab..efd574efc9 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -733,48 +733,50 @@ OAI CI Team''', // ---- Slave Job functions def triggerSlaveJob (jobName, gitlabStatusName) { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: gitlabStatusName) { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] + // Workaround for the "cancelled" GitLab pipeline notification + // The slave job is triggered with the propagate false so the following commands are executed + // Its status is now PASS/SUCCESS from a stage pipeline point of view + // localStatus variable MUST be analyzed to properly assess the status + localStatus = build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ], propagate: false + localResult = localStatus.getResult() + echo "${jobName} Slave Job status is ${localResult}" + gitlabCommitStatus(name: gitlabStatusName) { + if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) { + echo "${jobName} Slave Job is OK" + } else { + echo "${jobName} Slave Job is KO" + sh "ci-scripts/fail.sh" } - } else { - gitlabCommitStatus(name: gitlabStatusName) { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } } } def triggerSlaveJobNoGitLab (jobName) { - if ("MERGE".equals(env.gitlabActionType)) { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] + // Workaround for the "cancelled" GitLab pipeline notification + // The slave job is triggered with the propagate false so the following commands are executed + // Its status is now PASS/SUCCESS from a stage pipeline point of view + // localStatus variable MUST be analyzed to properly assess the status + localStatus = build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ], propagate: false + localResult = localStatus.getResult() + echo "${jobName} Slave Job status is ${localResult}" + if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) { + echo "${jobName} Slave Job is OK" } else { - build job: jobName, - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] + echo "${jobName} Slave Job is KO" + sh "ci-scripts/fail.sh" } } From 90e54318b5f83fcbb3288daecd0dc20cf3bb8c26 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 16:57:17 +0100 Subject: [PATCH 113/134] RFSIMULATOR: fixes based on Laurent Thomas's feedback Signed-off-by: Raphael Defosseux --- executables/nr-ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 24288d76d3..ca48554229 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -574,7 +574,7 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { } int computeSamplesShift(PHY_VARS_NR_UE *UE) { - if ( getenv("RFSIMULATOR") != 0) { + if (IS_SOFTMODEM_RFSIM) { LOG_E(PHY,"SET rx_offset %d \n",UE->rx_offset); //UE->rx_offset_diff=0; return 0; @@ -791,7 +791,7 @@ if (slot_nr==18) msgToPush->key=slot_nr; pushTpool(Tpool, msgToPush); - if (getenv("RFSIMULATOR") || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") + if (IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") // FixMe: Wait previous thread is done, because race conditions seems too bad // in case of actual RF board, the overlap between threads mitigate the issue // We must receive one message, that proves the slot processing is done From e156e232fc956daeb69d2fd1deca9f9e3b89e2bc Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 16:57:46 +0100 Subject: [PATCH 114/134] HOTFIX: missing UHD set_thread_priority_safe call (based on Cedric's feedback) Signed-off-by: Raphael Defosseux --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index abff420436..e2418bcb76 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -945,6 +945,8 @@ extern "C" { std::cerr << "USRP device initialized in subframes replay mode for " << s->recplay_state->u_sf_loops << " loops. Use mmap=" << s->recplay_state->use_mmap << std::endl; } else { + // hotfix! to be checked later + uhd::set_thread_priority_safe(1.0); // Initialize USRP device int vers=0,subvers=0,subsubvers=0; int bw_gain_adjust=0; From 2cd6a40b9ea4dd5ac267a9f9917928a06fe4a9c7 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 16:58:46 +0100 Subject: [PATCH 115/134] CI: list of Gitlab notifications split into several lines to ease maintenance DOC: CI documentation updated for 5G-NR Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 25 +++++++++++++++++-- ci-scripts/doc/vm_based_simulator_build.md | 22 ++++++++-------- .../doc/vm_based_simulator_check_build.md | 1 + ci-scripts/doc/vm_based_simulator_create.md | 24 ++++++++++-------- ci-scripts/doc/vm_based_simulator_test.md | 22 ++++++++-------- 5 files changed, 61 insertions(+), 33 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index efd574efc9..2792e3556a 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -44,7 +44,28 @@ pipeline { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-IF4p5-TDD-Band38-Multi-RRU" , "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"]) + gitlabBuilds(builds: [ + "Build gNB-USRP", + "Build nr-UE-USRP", + "Build eNB-USRP", + "Build basic-sim", + "Build phy-sim", + "Build eNB-ethernet", + "Build UE-ethernet", + "Analysis with cppcheck", + "Test phy-sim", + "Test basic-sim", + "Test L2-sim", + "Test-Mono-FDD-Band7", + "Test-Mono-TDD-Band40", + "Test-IF4p5-FDD-Band7", + "Test-IF4p5-TDD-Band40", + "Test-Mono-FDD-Band13-LTE-M", + "Test-IF4p5-TDD-Band38-Multi-RRU", + "Test-eNB-OAI-UE-FDD-Band7", + "Test-Mono-FDD-Band13-X2-HO", + "Test-TDD-Band78-gNB-NR-UE" + ]) ansiColor('xterm') } @@ -542,7 +563,7 @@ pipeline { steps { script { sh "sleep 60" - triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13') + triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13-LTE-M') } } post { diff --git a/ci-scripts/doc/vm_based_simulator_build.md b/ci-scripts/doc/vm_based_simulator_build.md index ca3ab356ea..28fbc955d5 100644 --- a/ci-scripts/doc/vm_based_simulator_build.md +++ b/ci-scripts/doc/vm_based_simulator_build.md @@ -51,18 +51,20 @@ Mandatory Options: Options: -------- # OpenAirInterface Build Variants - --variant enb-usrp OR -v1 - --variant basic-sim OR -v2 - --variant phy-sim OR -v3 - --variant cppcheck OR -v4 - --variant enb-ethernet OR -v7 - --variant ue-ethernet OR -v8 + --variant enb-usrp OR -v1 ( build and test ) + --variant basic-sim OR -v2 ( build and test ) + --variant phy-sim OR -v3 ( build and test ) + --variant cppcheck OR -v4 ( build and test ) + --variant gnb-usrp OR -v5 ( build and test ) + --variant nr-ue-usrp OR -v6 ( build and test ) + --variant enb-ethernet OR -v7 ( build and test ) + --variant ue-ethernet OR -v8 ( build and test ) # non-OSA Build Variants - --variant flexran-rtc OR -v10 + --variant flexran-rtc OR -v10 ( build and test non-OSA ) # OpenAirInterface Test Variants - --variant l1-sim OR -v20 - --variant rf-sim OR -v21 - --variant l2-sim OR -v22 + --variant l1-sim OR -v20 ( test ) + --variant rf-sim OR -v21 ( test ) + --variant l2-sim OR -v22 ( test ) Specify the variant to build. --keep-vm-alive OR -k diff --git a/ci-scripts/doc/vm_based_simulator_check_build.md b/ci-scripts/doc/vm_based_simulator_check_build.md index d66b8ff2a0..86d26ff8ed 100644 --- a/ci-scripts/doc/vm_based_simulator_check_build.md +++ b/ci-scripts/doc/vm_based_simulator_check_build.md @@ -34,6 +34,7 @@ Source file concerned: `ci-scripts/waitBuildOnVM.sh` * and copy them locally in the workspace at $ARCHIVES_LOC * List all log files that match the pattern. Each should have * the `Built target` pattern (the library/executable SHALL link) +* Evaluate the remaining space on VM disk * The number of patterned log files SHALL match $NB_PATTERN_FILES defined in `ci-scripts/oai-ci-vm-tool` script for the variant --- diff --git a/ci-scripts/doc/vm_based_simulator_create.md b/ci-scripts/doc/vm_based_simulator_create.md index c54d69ca14..09ce26c553 100644 --- a/ci-scripts/doc/vm_based_simulator_create.md +++ b/ci-scripts/doc/vm_based_simulator_create.md @@ -44,18 +44,20 @@ Mandatory Options: Specify the build ID of the Jenkins job. # OpenAirInterface Build Variants - --variant enb-usrp OR -v1 - --variant basic-sim OR -v2 - --variant phy-sim OR -v3 - --variant cppcheck OR -v4 - --variant enb-ethernet OR -v7 - --variant ue-ethernet OR -v8 + --variant enb-usrp OR -v1 ( build and test ) + --variant basic-sim OR -v2 ( build and test ) + --variant phy-sim OR -v3 ( build and test ) + --variant cppcheck OR -v4 ( build and test ) + --variant gnb-usrp OR -v5 ( build and test ) + --variant nr-ue-usrp OR -v6 ( build and test ) + --variant enb-ethernet OR -v7 ( build and test ) + --variant ue-ethernet OR -v8 ( build and test ) # non-OSA Build Variants - --variant flexran-rtc OR -v10 + --variant flexran-rtc OR -v10 ( build and test non-OSA ) # OpenAirInterface Test Variants - --variant l1-sim OR -v20 - --variant rf-sim OR -v21 - --variant l2-sim OR -v22 + --variant l1-sim OR -v20 ( test ) + --variant rf-sim OR -v21 ( test ) + --variant l2-sim OR -v22 ( test ) Specify the variant to build. --help OR -h @@ -73,7 +75,7 @@ This is the function that is being called from the main oai-vm-tool script. The main purpose is to start a VM instance: ```bash -uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml +uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml ``` Variables are set in the main script based on the options. diff --git a/ci-scripts/doc/vm_based_simulator_test.md b/ci-scripts/doc/vm_based_simulator_test.md index 0be7ae5d3a..73308b972e 100644 --- a/ci-scripts/doc/vm_based_simulator_test.md +++ b/ci-scripts/doc/vm_based_simulator_test.md @@ -72,18 +72,20 @@ Options: Specify the workspace. # OpenAirInterface Build Variants - --variant enb-usrp OR -v1 - --variant basic-sim OR -v2 - --variant phy-sim OR -v3 - --variant cppcheck OR -v4 - --variant enb-ethernet OR -v7 - --variant ue-ethernet OR -v8 + --variant enb-usrp OR -v1 ( build and test ) + --variant basic-sim OR -v2 ( build and test ) + --variant phy-sim OR -v3 ( build and test ) + --variant cppcheck OR -v4 ( build and test ) + --variant gnb-usrp OR -v5 ( build and test ) + --variant nr-ue-usrp OR -v6 ( build and test ) + --variant enb-ethernet OR -v7 ( build and test ) + --variant ue-ethernet OR -v8 ( build and test ) # non-OSA Build Variants - --variant flexran-rtc OR -v10 + --variant flexran-rtc OR -v10 ( build and test non-OSA ) # OpenAirInterface Test Variants - --variant l1-sim OR -v20 - --variant rf-sim OR -v21 - --variant l2-sim OR -v22 + --variant l1-sim OR -v20 ( test ) + --variant rf-sim OR -v21 ( test ) + --variant l2-sim OR -v22 ( test ) Specify the variant to build. --keep-vm-alive OR -k From c409da3bb8c0540f4bd1fe45c7a495a581cf8466 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 9 Jan 2020 14:10:04 +0100 Subject: [PATCH 116/134] Patch provided by Gabriel Arrobo. Mainly comestics and integer type management Signed-off-by: Raphael Defosseux --- cmake_targets/build_oai | 2 +- common/config/config_load_configmodule.c | 8 +- common/utils/LOG/log.c | 1 + common/utils/LOG/log.h | 10 +- common/utils/ocp_itti/intertask_interface.h | 2 +- common/utils/system.c | 6 +- executables/nr-gnb.c | 2 +- executables/nr-ru.c | 20 +-- executables/nr-softmodem.c | 32 ++--- executables/nr-ue.c | 8 +- executables/nr-uesoftmodem.c | 14 +- openair1/PHY/INIT/init_top.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/defs_RU.h | 10 +- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 2 +- openair2/COMMON/sctp_messages_types.h | 8 +- openair2/F1AP/f1ap_du_interface_management.c | 8 +- openair2/GNB_APP/gnb_app.c | 2 +- openair2/GNB_APP/gnb_config.c | 8 +- openair2/GNB_APP/gnb_paramdef.h | 4 +- openair2/RRC/NAS/nas_config.c | 2 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/NR_UE/main_ue.c | 5 +- openair2/RRC/NR_UE/rrc_UE.c | 4 +- openair2/UTIL/OMV/structures.h | 2 +- openair3/NAS/UE/UEprocess.c | 60 +++++---- openair3/NAS/UE/nas_network.c | 46 +++---- openair3/NAS/UE/nas_parser.c | 121 +++++++++--------- openair3/SCTP/sctp_common.c | 2 +- targets/ARCH/COMMON/common_lib.h | 4 +- 30 files changed, 199 insertions(+), 200 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 227e8d888d..e450a40da5 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -147,7 +147,7 @@ Options --uhd-images-dir Download UHD images in the indicated location --build-eclipse - Build eclipse project files. Paths are auto corrected by fixprj.sh + Build eclipse project files. --build-lib Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES or \"all\" --usrp-recplay diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index fcee9c3238..61a3984347 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -158,7 +158,7 @@ int config_cmdlineonly_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) break; default: - fprintf(stderr,"[CONFIG] %s.%s type %i not supported\n",prefix, cfgoptions[i].optname,cfgoptions[i].type); + fprintf(stderr,"[CONFIG] %s.%s type %i not supported\n",prefix, cfgoptions[i].optname,cfgoptions[i].type); fatalerror=1; break; } /* switch on param type */ @@ -214,7 +214,7 @@ configmodule_interface_t *load_configmodule(int argc, } } - /* look for the OAI_CONFIGMODULE environement variable */ + /* look for the OAI_CONFIGMODULE environment variable */ if ( cfgparam == NULL ) { cfgparam = getenv("OAI_CONFIGMODULE"); } @@ -265,8 +265,8 @@ configmodule_interface_t *load_configmodule(int argc, atoken=strtok_r(modeparams,":",&strtokctx); while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { - /* look for debug level in the config parameters, it is commom to all config mode - and will be removed frome the parameter array passed to the shared module */ + /* look for debug level in the config parameters, it is common to all config mode + and will be removed from the parameter array passed to the shared module */ char *aptr; aptr=strcasestr(atoken,"dbgl"); diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 7f177b90ce..5a5f334602 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -421,6 +421,7 @@ int logInit (void) register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT); register_log_component("PROTO_AGENT","log",PROTO_AGENT); register_log_component("TMR","",TMR); + register_log_component("EMU","log",EMU); register_log_component("USIM","txt",USIM); register_log_component("SIM","txt",SIM); /* following log component are used for the localization*/ diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 111f2c58ce..096c001203 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -363,7 +363,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOG globalconfiguration parameters */ +/* LOG global configuration parameters */ /* optname help paramflags XXXptr defXXXval type numelt */ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOG_GLOBALPARAMS_DESC { \ @@ -385,7 +385,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int // debugging macros #define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */ # if T_TRACER -/* per component, level dependant macros */ +/* per component, level dependent macros */ # define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0) # define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0) # define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0) @@ -394,10 +394,10 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define VLOG(c,l, f, args) do { if (T_stdout) { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ;} } while (0) /* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */ # define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ -/* bitmask dependant macros, to isolate debugging code */ +/* bitmask dependent macros, to isolate debugging code */ # define LOG_DEBUGFLAG(D) (g_log->debug_mask & D) -/* bitmask dependant macros, to generate debug file such as matlab file or message dump */ +/* bitmask dependent macros, to generate debug file such as matlab file or message dump */ # define LOG_DUMPFLAG(D) (g_log->dump_mask & D) # define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */ /* define variable only used in LOG macro's */ @@ -420,7 +420,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define GCC_NOTUSED __attribute__((unused)) #define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B -/* unfiltered macros, usefull for simulators or messages at init time, before log is configured */ +/* unfiltered macros, useful for simulators or messages at init time, before log is configured */ #define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) #define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0) #define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x) ;} while (0) /* */ diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 80493dc816..20cd82efca 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -1,6 +1,6 @@ /* Author: Laurent THOMAS, Open Cells - Copyleft: OpenAirInterface software alliance and it's licence + Copyleft: OpenAirInterface software alliance and it's license */ #ifndef INTERTASK_INTERFACE_H_ #define INTERTASK_INTERFACE_H_ diff --git a/common/utils/system.c b/common/utils/system.c index 31c1035129..3a8fe7be3d 100644 --- a/common/utils/system.c +++ b/common/utils/system.c @@ -229,7 +229,7 @@ void configure_linux(void) { if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) { ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value)); if (ret == 0) { - printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno)); + printf("# error setting cpu_dma_latency to %u!: %s\n", latency_target_value, strerror(errno)); close(latency_target_fd); latency_target_fd=-1; return; @@ -237,9 +237,9 @@ void configure_linux(void) { } } if (latency_target_fd != -1) - LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value); + LOG_I(HW,"# /dev/cpu_dma_latency set to %u us\n", latency_target_value); else - LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value); + LOG_E(HW,"Can't set /dev/cpu_dma_latency to %u us\n", latency_target_value); // Set CPU frequency to it's maximum if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done")) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index cb1d45adc2..062cec07ab 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -926,7 +926,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { int CC_id; int inst; PHY_VARS_gNB *gNB; - LOG_I(PHY,"[nr-softmodem.c] gNB structure about to allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]); + LOG_I(PHY,"[nr-softmodem.c] gNB structure about to be allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]); if (RC.gNB == NULL) RC.gNB = (PHY_VARS_gNB ***) malloc(RC.nb_nr_L1_inst*sizeof(PHY_VARS_gNB **)); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index a9c306461c..37e6b71d85 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -992,7 +992,7 @@ void wakeup_gNB_L1s(RU_t *ru) { if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { // call gNB function directly char string[20]; - sprintf(string,"Incoming RU %d",ru->idx); + sprintf(string,"Incoming RU %u",ru->idx); LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx); ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru); } else { @@ -1172,7 +1172,7 @@ int setup_RU_buffers(RU_t *ru) { for (i=0; inb_rx; i++) { card = i/4; ant = i%4; - printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + printf("Mapping RU id %u, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); free(ru->common.rxdata[i]); ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); @@ -1186,7 +1186,7 @@ int setup_RU_buffers(RU_t *ru) { for (i=0; inb_tx; i++) { card = i/4; ant = i%4; - printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + printf("Mapping RU id %u, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); free(ru->common.txdata[i]); ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); @@ -1336,7 +1336,7 @@ static void *ru_thread_tx( void *param ) { for (int j=0; jnum_RU; j++) { if (ru == gNB->RU_list[j]) { if ((gNB_proc->RU_mask_tx&(1< 0) - LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", + LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx); gNB_proc->RU_mask_tx |= (1<idx); + sprintf(threadname,"ru_thread %u",ru->idx); LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); @@ -2009,7 +2009,7 @@ void set_function_spec_param(RU_t *ru) { reset_meas(&ru->compression); reset_meas(&ru->transport); ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + printf("openair0_transport_init returns %d for ru_id %u\n", ret, ru->idx); if (ret<0) { printf("Exiting, cannot initialize transport protocol\n"); @@ -2033,7 +2033,7 @@ void set_function_spec_param(RU_t *ru) { reset_meas(&ru->compression); reset_meas(&ru->transport); ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + printf("openair0_transport_init returns %d for ru_id %u\n", ret, ru->idx); if (ret<0) { printf("Exiting, cannot initialize transport protocol\n"); @@ -2056,7 +2056,7 @@ void set_function_spec_param(RU_t *ru) { ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface ru->stop_rf = stop_rf; - printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); + printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf); /* if (ru->function == gNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise fill_rf_config(ru,rf_config_file); @@ -2086,7 +2086,7 @@ void set_function_spec_param(RU_t *ru) { ru->ifdevice.eth_params = &ru->eth_params; ru->ifdevice.configure_rru = configure_ru; ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + printf("openair0_transport_init returns %d for ru_id %u\n", ret, ru->idx); if (ret<0) { printf("Exiting, cannot initialize transport protocol\n"); @@ -2112,7 +2112,7 @@ void set_function_spec_param(RU_t *ru) { ru->ifdevice.eth_params = &ru->eth_params; ru->ifdevice.configure_rru = configure_ru; ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + printf("openair0_transport_init returns %d for ru_id %u\n", ret, ru->idx); if (ret<0) { printf("Exiting, cannot initialize transport protocol\n"); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 8ba711dd23..dac2fa6d19 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -116,7 +116,7 @@ static int8_t threequarter_fs=0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -//Temp fix for inexisting NR upper layer +//Temp fix for inexistent NR upper layer unsigned char NB_gNB_INST = 1; #if defined(ENABLE_ITTI) @@ -354,7 +354,7 @@ void *l2l1_task(void *arg) { switch (ITTI_MSG_ID(message_p)) { case INITIALIZE_MESSAGE: - /* Start eNB thread */ + /* Start gNB thread */ LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); start_gNB = 1; break; @@ -411,7 +411,7 @@ void *l2l1_task(void *arg) { #endif int create_gNB_tasks(uint32_t gnb_nb) { - LOG_D(GNB_APP, "%s(gnb_nb:%d\n", __FUNCTION__, gnb_nb); + LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); itti_wait_ready(1); if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { @@ -506,7 +506,7 @@ static void get_options(void) { NRRCConfig(); NB_gNB_INST = RC.nb_nr_inst; NB_RU = RC.nb_RU; - printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %d\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU); + printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhu\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU); } if(parallel_config != NULL) set_parallel_conf(parallel_config); @@ -707,7 +707,7 @@ void wait_gNBs(void) { * helper function to terminate a certain ITTI task */ void terminate_task(task_id_t task_id, module_id_t mod_id) { - LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); MessageDef *msg; msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); @@ -717,11 +717,11 @@ void terminate_task(task_id_t task_id, module_id_t mod_id) { extern void nr_phy_free_RU(RU_t *); int stop_L1L2(module_id_t gnb_id) { - LOG_W(ENB_APP, "stopping nr-softmodem\n"); + LOG_W(GNB_APP, "stopping nr-softmodem\n"); oai_exit = 1; if (!RC.ru) { - LOG_F(ENB_APP, "no RU configured\n"); + LOG_F(GNB_APP, "no RU configured\n"); return -1; } @@ -729,28 +729,28 @@ int stop_L1L2(module_id_t gnb_id) { if (RC.ru[gnb_id]) { if (RC.ru[gnb_id]->rfdevice.trx_stop_func) { RC.ru[gnb_id]->rfdevice.trx_stop_func(&RC.ru[gnb_id]->rfdevice); - LOG_I(ENB_APP, "turned off RU rfdevice\n"); + LOG_I(GNB_APP, "turned off RU rfdevice\n"); } else { - LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n"); + LOG_W(GNB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceeding anyway!\n"); } if (RC.ru[gnb_id]->ifdevice.trx_stop_func) { RC.ru[gnb_id]->ifdevice.trx_stop_func(&RC.ru[gnb_id]->ifdevice); - LOG_I(ENB_APP, "turned off RU ifdevice\n"); + LOG_I(GNB_APP, "turned off RU ifdevice\n"); } else { - LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n"); + LOG_W(GNB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceeding anyway!\n"); } } else { - LOG_W(ENB_APP, "no RU found for index %d\n", gnb_id); + LOG_W(GNB_APP, "no RU found for index %d\n", gnb_id); return -1; } /* these tasks need to pick up new configuration */ terminate_task(TASK_RRC_ENB, gnb_id); terminate_task(TASK_L2L1, gnb_id); - LOG_I(ENB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id); + LOG_I(GNB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id); kill_gNB_proc(gnb_id); - LOG_I(ENB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id); + LOG_I(GNB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id); kill_NR_RU_proc(gnb_id); oai_exit = 0; @@ -771,7 +771,7 @@ int restart_L1L2(module_id_t gnb_id) { RU_t *ru = RC.ru[gnb_id]; int cc_id; MessageDef *msg_p = NULL; - LOG_W(ENB_APP, "restarting nr-softmodem\n"); + LOG_W(GNB_APP, "restarting nr-softmodem\n"); /* block threads */ sync_var = -1; @@ -784,7 +784,7 @@ int restart_L1L2(module_id_t gnb_id) { /* TODO this should be done for all RUs associated to this gNB */ memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id][0]->frame_parms, sizeof(NR_DL_FRAME_PARMS)); set_function_spec_param(RC.ru[gnb_id]); - LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); + LOG_I(GNB_APP, "attempting to create ITTI tasks\n"); if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { LOG_E(RRC, "Create task for RRC eNB failed\n"); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index ca48554229..92bcc743bc 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -539,7 +539,7 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { UE->frame_parms.samples_per_subframe, UE->frame_parms.nb_antennas_rx); if (IS_SOFTMODEM_RFSIM ) { - usleep(1000); // slow down, as would do actuall rf to let cpu for the synchro thread + usleep(1000); // slow down, as would do actual rf to let cpu for the synchro thread } } @@ -639,7 +639,7 @@ void *UE_thread(void *arg) { } } - AssertFatal( !syncRunning, "At this point synchronisation can't be running\n"); + AssertFatal( !syncRunning, "At this point synchronization can't be running\n"); if (!UE->is_synchronized) { readFrame(UE, ×tamp); @@ -668,7 +668,7 @@ void *UE_thread(void *arg) { // we have the decoded frame index in the return of the synch process // and we shifted above to the first slot of next frame decoded_frame_rx++; - // we do ++ first in the regular processing, so it will be beging of frame; + // we do ++ first in the regular processing, so it will be begin of frame; absolute_slot=decoded_frame_rx*nb_slot_frame + nb_slot_frame -1; continue; } @@ -832,7 +832,7 @@ void init_NR_UE(int nb_inst) { mac_inst->initial_bwp_ul.scs = UE->frame_parms.subcarrier_spacing; mac_inst->initial_bwp_ul.N_RB = UE->frame_parms.N_RB_UL; mac_inst->initial_bwp_ul.cyclic_prefix = UE->frame_parms.Ncp; - LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); + LOG_I(PHY,"Initializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX); #ifdef UE_DLSCH_PARALLELISATION diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 32dca26a45..d3e9300053 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -82,7 +82,7 @@ unsigned short config_frames[4] = {2,9,11,13}; /* Callbacks, globals and object handlers */ extern void reset_stats( FL_OBJECT *, long ); -//extern void initTpool(char *params,tpool_t *pool, bool performanceMeas); +//extern void initTpool(char *params, tpool_t *pool, bool performanceMeas); /* Forms and Objects */ @@ -433,19 +433,19 @@ static void get_options(void) { /*if (frame_parms[0]->N_RB_DL !=0) { if ( frame_parms[0]->N_RB_DL < 6 ) { frame_parms[0]->N_RB_DL = 6; - printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); + printf ( "%i: Invalid number of resource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); } if ( frame_parms[0]->N_RB_DL > 100 ) { frame_parms[0]->N_RB_DL = 100; - printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); + printf ( "%i: Invalid number of resource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); } if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { frame_parms[0]->N_RB_DL = 50; - printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); + printf ( "%i: Invalid number of resource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); } if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { frame_parms[0]->N_RB_DL = 25; - printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); + printf ( "%i: Invalid number of resource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); } UE_scan = 0; frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; @@ -588,7 +588,7 @@ void init_openair0(void) { else //FDD openair0_cfg[card].duplex_mode = duplex_mode_FDD; - printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, + printf("HW: Configuring card %d, nb_antennas_tx/rx %hhu/%hhu\n",card, PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); openair0_cfg[card].Mod_id = 0; @@ -714,7 +714,7 @@ int main( int argc, char **argv ) { PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs); for (int CC_id=0; CC_idofdm_symbol_size); + printf("frame_parms %hu\n",frame_parms[CC_id]->ofdm_symbol_size); nr_init_frame_parms_ue(frame_parms[CC_id],numerology,NORMAL,frame_parms[CC_id]->N_RB_DL,(frame_parms[CC_id]->N_RB_DL-20)>>1,0); PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag); UE[CC_id] = PHY_vars_UE_g[0][CC_id]; diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 6421eebe28..0990a58266 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -19,7 +19,7 @@ contact@openairinterface.org */ -/*!\brief Initilization and reconfiguration routines for LTE PHY */ +/*!\brief Initialization and reconfiguration routines for LTE PHY */ #include "phy_init.h" #include "PHY/phy_extern.h" #include "PHY/CODING/coding_extern.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index e78d7aadee..7b783ace5b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -166,7 +166,7 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 return(ulsch); } - printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); + printf("new_gNB_ulsch with size %zu: exit_flag = %hhu\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); free_gNB_ulsch(&ulsch); return(NULL); } diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 0ec04dd537..adcc1470d9 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -412,7 +412,7 @@ typedef enum { } rru_state_t; -/// Some commamds to RRU. Not sure we should do it like this ! +/// Some commands to RRU. Not sure we should do it like this ! typedef enum { EMPTY = 0, STOP_RU = 1, @@ -434,7 +434,7 @@ typedef struct RU_t_s { node_function_t function; /// Ethernet parameters for fronthaul interface eth_params_t eth_params; - /// flag to indicate the RU is in synch with a master reference + /// flag to indicate the RU is in sync with a master reference int in_synch; /// timing offset int rx_offset; @@ -565,7 +565,7 @@ typedef struct RU_t_s { time_stats_t rx_fhaul; /// Timing statistics (TX Fronthaul + Compression) time_stats_t tx_fhaul; - /// Timong statistics (Compression) + /// Timing statistics (Compression) time_stats_t compression; /// Timing statistics (Fronthaul transport) time_stats_t transport; @@ -676,7 +676,7 @@ typedef struct RRU_config_s { uint32_t tx_freq[MAX_BANDS_PER_RRU]; /// RX frequency uint32_t rx_freq[MAX_BANDS_PER_RRU]; - /// TX attenation w.r.t. max + /// TX attenuation w.r.t. max uint8_t att_tx[MAX_BANDS_PER_RRU]; /// RX attenuation w.r.t. max uint8_t att_rx[MAX_BANDS_PER_RRU]; @@ -695,7 +695,7 @@ typedef struct RRU_config_s { int emtc_prach_FreqOffset[MAX_BANDS_PER_RRU][4]; /// emtc_prach_ConfigIndex for IF4p5 per CE Level int emtc_prach_ConfigIndex[MAX_BANDS_PER_RRU][4]; - /// mutex for asynch RX/TX thread + /// mutex for async RX/TX thread pthread_mutex_t mutex_asynch_rxtx; /// mutex for RU access to eNB processing (PDSCH/PUSCH) pthread_mutex_t mutex_RU; diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index 396c76f8e6..5735aa33a5 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -163,7 +163,7 @@ int netlink_init(void) { } } - printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd[0]); + printf("[NETLINK] Opened socket with fd %d\n",nas_sock_fd[0]); ret = fcntl(nas_sock_fd[0],F_SETFL,O_NONBLOCK); if (ret == -1) { diff --git a/openair2/COMMON/sctp_messages_types.h b/openair2/COMMON/sctp_messages_types.h index 9e363c0d8d..c2561c0424 100644 --- a/openair2/COMMON/sctp_messages_types.h +++ b/openair2/COMMON/sctp_messages_types.h @@ -41,7 +41,7 @@ enum sctp_state_e { }; typedef struct sctp_new_association_req_s { - /* Upper layer connexion identifier */ + /* Upper layer connection identifier */ uint16_t ulp_cnx_id; /* The port to connect to */ @@ -60,7 +60,7 @@ typedef struct sctp_new_association_req_s { } sctp_new_association_req_t; typedef struct sctp_new_association_req_multi_s { - /* Upper layer connexion identifier */ + /* Upper layer connection identifier */ uint16_t ulp_cnx_id; /* The port to connect to */ @@ -98,7 +98,7 @@ typedef struct sctp_new_association_ind_s { } sctp_new_association_ind_t; typedef struct sctp_new_association_resp_s { - /* Upper layer connexion identifier */ + /* Upper layer connection identifier */ uint16_t ulp_cnx_id; /* SCTP Association ID */ @@ -149,7 +149,7 @@ typedef struct sctp_listener_register_upper_layer_s { /* Port to listen to */ uint16_t port; /* Payload protocol identifier - * Any data receveid on PPID != will be discarded + * Any data received on PPID != will be discarded */ uint32_t ppid; } sctp_listener_register_upper_layer_t; diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 83f3da57b2..341c050f55 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -117,7 +117,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) { ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ - /* c2. GNB_DU_ID (integrer value) */ + /* c2. GNB_DU_ID (integer value) */ ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t)); ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_ID; ie->criticality = F1AP_Criticality_reject; @@ -138,7 +138,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) { } /* mandatory */ - /* c4. serverd cells list */ + /* c4. served cells list */ ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t)); ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List; ie->criticality = F1AP_Criticality_reject; @@ -150,7 +150,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) { ieth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); RC.nrmac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; - //sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + //sf_ahead = 2; // Cannot cope with 4 subframes between RX and TX - set it to 2 printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); configure_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc); @@ -682,7 +682,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { gnb_id = *(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr); } - printf("NRRRC %d: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr)); + printf("NRRRC %u: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr)); if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { @@ -2684,7 +2684,7 @@ int RCconfig_nr_gtpu(void ) { paramdef_t GNBSParams[] = GNBSPARAMS_DESC; - paramdef_t GTPUParams[] = GNBGTPUPARAMS_DESC; + paramdef_t GTPUParams[] = GNBGTPUPARAMS_DESC; LOG_I(GTPU,"Configuring GTPu\n"); /* get number of active eNodeBs */ @@ -2976,7 +2976,7 @@ void NRRCConfig(void) { /* get global parameters, defined outside any section in the config file */ - printf("Getting GNBSParams\n"); + LOG_I(GNB_APP, "Getting GNBSParams\n"); config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); RC.nb_nr_inst = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 8a55c61cd7..4041338251 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -122,8 +122,8 @@ typedef enum { {GNB_CONFIG_STRING_CELL_TYPE, NULL, 0, strptr:NULL, defstrval:"CELL_MACRO_GNB", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_NAME, NULL, 0, strptr:NULL, defstrval:"OAIgNodeB", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_LOCAL_S_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index ab4dbfc119..75d83fa52e 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -257,7 +257,7 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) returnValue=bringInterfaceUp(interfaceName, 1); if(!returnValue) - LOG_I(OIP,"Interface %s successfuly configured, ip address %s, mask %s broadcast address %s\n", + LOG_I(OIP,"Interface %s successfully configured, ip address %s, mask %s broadcast address %s\n", interfaceName, ipAddress, netMask, broadcastAddress); else LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n", diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index d9829a46dc..44fe980ebe 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -125,7 +125,7 @@ typedef struct xer_sprint_string_s { size_t string_index; } xer_sprint_string_t; -//repplace LTE +//replace LTE //extern unsigned char NB_eNB_INST; extern unsigned char NB_gNB_INST; extern uint8_t usim_test; diff --git a/openair2/RRC/NR_UE/main_ue.c b/openair2/RRC/NR_UE/main_ue.c index 8188b4f572..6929040034 100644 --- a/openair2/RRC/NR_UE/main_ue.c +++ b/openair2/RRC/NR_UE/main_ue.c @@ -32,11 +32,12 @@ #include "defs.h" #include "rrc_proto.h" +#include "common/utils/LOG/log.h" int nr_l3_init_ue(void){ - //LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n"); + LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n"); - openair_rrc_top_init_ue_nr(); + openair_rrc_top_init_ue_nr(); return 0; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 756be3963a..7db6be499e 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -400,14 +400,14 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message( case NR_DL_DCCH_MessageType__c1_PR_spare2: case NR_DL_DCCH_MessageType__c1_PR_spare1: default: - // not support or unuse + // not supported or unused break; } break; case NR_DL_DCCH_MessageType_PR_NOTHING: case NR_DL_DCCH_MessageType_PR_messageClassExtension: default: - // not support or unuse + // not supported or unused break; } diff --git a/openair2/UTIL/OMV/structures.h b/openair2/UTIL/OMV/structures.h index ee33632059..5c48641f86 100644 --- a/openair2/UTIL/OMV/structures.h +++ b/openair2/UTIL/OMV/structures.h @@ -49,7 +49,7 @@ typedef struct Geo { int node_type; int Neighbors; // number of neighboring nodes (distance between the node and its neighbors < 100) int Neighbor[NUMBER_OF_UE_MAX]; // array of its neighbors - //relavent to UE only + //relevant to UE only unsigned short state; unsigned short rnti; unsigned int connected_eNB; diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 7fe1435960..7b9a1be422 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -188,17 +188,16 @@ int main(int argc, const char *argv[]) /**************************************************************************** ** ** - ** Name: _nas_user_mngr() ** + ** Name: _nas_user_mngr() ** ** ** ** Description: Manages the connection endpoint use to communicate with ** - ** the user application layer ** + ** the user application layer ** ** ** - ** Inputs: fd: The descriptor of the user connection end- ** - ** point ** - ** Others: None ** + ** Inputs: fd: The descriptor of the user connection end-point ** + ** Others: None ** ** ** - ** Outputs: Return: None ** - ** Others: None ** + ** Outputs: Return: None ** + ** Others: None ** ** ** ***************************************************************************/ static void *_nas_user_mngr(void *args) @@ -227,17 +226,16 @@ static void *_nas_user_mngr(void *args) /**************************************************************************** ** ** - ** Name: _nas_network_mngr() ** + ** Name: _nas_network_mngr() ** ** ** ** Description: Manages the connection endpoint use to communicate with ** - ** the network sublayer ** + ** the network sublayer ** ** ** - ** Inputs: fd: The descriptor of the network connection ** - ** endpoint ** - ** Others: None ** + ** Inputs: fd: The descriptor of the network connection endpoint ** + ** Others: None ** ** ** - ** Outputs: Return: None ** - ** Others: None ** + ** Outputs: Return: None ** + ** Others: None ** ** ** ***************************************************************************/ static void *_nas_network_mngr(void *args) @@ -302,16 +300,16 @@ static void *_nas_network_mngr(void *args) /**************************************************************************** ** ** - ** Name: _nas_set_signal_handler() ** + ** Name: _nas_set_signal_handler() ** ** ** ** Description: Set up a signal handler ** ** ** - ** Inputs: signal: Signal number ** - ** handler: Signal handler ** - ** Others: None ** + ** Inputs: signal: Signal number ** + ** handler: Signal handler ** + ** Others: None ** ** ** - ** Outputs: Return: RETURNerror, RETURNok ** - ** Others: None ** + ** Outputs: Return: RETURNerror, RETURNok ** + ** Others: None ** ** ** ***************************************************************************/ static int _nas_set_signal_handler(int signal, void (handler)(int)) @@ -351,15 +349,15 @@ static int _nas_set_signal_handler(int signal, void (handler)(int)) /**************************************************************************** ** ** - ** Name: _nas_signal_handler() ** + ** Name: _nas_signal_handler() ** ** ** ** Description: Signal handler ** ** ** - ** Inputs: signal: Signal number ** - ** Others: None ** + ** Inputs: signal: Signal number ** + ** Others: None ** ** ** - ** Outputs: Return: None ** - ** Others: None ** + ** Outputs: Return: None ** + ** Others: None ** ** ** ***************************************************************************/ static void _nas_signal_handler(int signal) @@ -377,16 +375,16 @@ static void _nas_signal_handler(int signal) /**************************************************************************** ** ** - ** Name: _nas_clean() ** + ** Name: _nas_clean() ** ** ** ** Description: Performs termination cleanup ** ** ** - ** Inputs: usr_fd: User's connection file descriptor ** - ** net_fd: Network's connection file descriptor ** - ** Others: None ** + ** Inputs: usr_fd: User's connection file descriptor ** + ** net_fd: Network's connection file descriptor ** + ** Others: None ** ** ** - ** Outputs: Return: None ** - ** Others: None ** + ** Outputs: Return: None ** + ** Others: None ** ** ** ***************************************************************************/ static void _nas_clean(user_api_id_t *user_api_id, int net_fd) diff --git a/openair3/NAS/UE/nas_network.c b/openair3/NAS/UE/nas_network.c index f7a292df3f..f8abba4900 100644 --- a/openair3/NAS/UE/nas_network.c +++ b/openair3/NAS/UE/nas_network.c @@ -59,16 +59,16 @@ Description NAS procedure functions triggered by the network /**************************************************************************** ** ** - ** Name: nas_network_initialize() ** + ** Name: nas_network_initialize() ** ** ** ** Description: Initializes network internal data ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ void nas_network_initialize(void) @@ -80,16 +80,16 @@ void nas_network_initialize(void) /**************************************************************************** ** ** - ** Name: nas_network_cleanup() ** + ** Name: nas_network_cleanup() ** ** ** ** Description: Performs clean up procedure before the system is shutdown ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** + ** Outputs: None ** + ** Return: None ** + ** Others: None ** ** ** ***************************************************************************/ void nas_network_cleanup(nas_user_t *user) @@ -103,20 +103,20 @@ void nas_network_cleanup(nas_user_t *user) /**************************************************************************** ** ** - ** Name: nas_network_process_data() ** + ** Name: nas_network_process_data() ** ** ** ** Description: Process Access Stratum messages received from the network ** - ** and call applicable NAS procedure function. ** + ** and call applicable NAS procedure function. ** ** ** - ** Inputs: msg_id: AS message identifier ** - ** data: Generic pointer to data structure that has ** - ** to be processed ** - ** Others: None ** + ** Inputs: msg_id: AS message identifier ** + ** data: Generic pointer to data structure that has ** + ** to be processed ** + ** Others: None ** ** ** - ** Outputs: None ** - ** Return: RETURNok if the message has been success- ** - ** fully processed; RETURNerror otherwise ** - ** Others: None ** + ** Outputs: None ** + ** Return: RETURNok if the message has been success- ** + ** fully processed; RETURNerror otherwise ** + ** Others: None ** ** ** ***************************************************************************/ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) @@ -173,7 +173,7 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) } case AS_NAS_RELEASE_IND: - /* Received NAS signalling connection releaase indication */ + /* Received NAS signalling connection release indication */ rc = nas_proc_release_ind(user, msg->msg.nas_release_ind.cause); break; diff --git a/openair3/NAS/UE/nas_parser.c b/openair3/NAS/UE/nas_parser.c index d62ebc3529..beba47f64a 100644 --- a/openair3/NAS/UE/nas_parser.c +++ b/openair3/NAS/UE/nas_parser.c @@ -54,7 +54,7 @@ Description NAS command line parser * Identifiers of the NAS command line options */ enum { - NAS_PARSER_UE_ID, /* User Equipement Identifier */ + NAS_PARSER_UE_ID, /* User Equipment Identifier */ NAS_PARSER_TRACE_LEVEL, /* Logging trace level */ NAS_PARSER_USER_HOST, /* User app layer's hostname */ NAS_PARSER_NETWORK_HOST, /* Network layer's hostname */ @@ -118,17 +118,16 @@ static int atohex(const char *a_char); /**************************************************************************** ** ** - ** Name: nas_parser_print_usage() ** + ** Name: nas_parser_print_usage() ** ** ** ** Description: Displays the command line options used to run the NAS ** - ** process and the firmware version defined at compilation ** - ** time ** + ** process and the firmware version defined at compilation time ** ** ** - ** Inputs: version: Firmware version ** - ** Others: None ** + ** Inputs: version: Firmware version ** + ** Others: None ** ** ** - ** Outputs: Return: None ** - ** Others: None ** + ** Outputs: Return: None ** + ** Others: None ** ** ** ***************************************************************************/ void nas_parser_print_usage(const char *version) @@ -139,16 +138,16 @@ void nas_parser_print_usage(const char *version) /**************************************************************************** ** ** - ** Name: nas_parser_get_options() ** + ** Name: nas_parser_get_options() ** ** ** ** Description: Gets the command line options used to run the NAS process ** ** ** - ** Inputs: argc: Number of options ** - ** argv: Pointer to the list of options ** - ** Others: None ** + ** Inputs: argc: Number of options ** + ** argv: Pointer to the list of options ** + ** Others: None ** ** ** - ** Outputs: Return: RETURNerror, RETURNok ** - ** Others: None ** + ** Outputs: Return: RETURNerror, RETURNok ** + ** Others: None ** ** ** ***************************************************************************/ int nas_parser_get_options(int argc, const char **argv) @@ -158,16 +157,16 @@ int nas_parser_get_options(int argc, const char **argv) /**************************************************************************** ** ** - ** Name: nas_parser_get_nb_options() ** + ** Name: nas_parser_get_nb_options() ** ** ** ** Description: Returns the number of the command line options used to ** - ** run the NAS process ** + ** run the NAS process ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Number of command line options ** - ** Others: None ** + ** Outputs: Return: Number of command line options ** + ** Others: None ** ** ** ***************************************************************************/ int nas_parser_get_nb_options(void) @@ -177,15 +176,15 @@ int nas_parser_get_nb_options(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_trace_level() ** + ** Name: nas_parser_get_trace_level() ** ** ** ** Description: Returns the value of the logging trace level ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the logging trace level ** - ** Others: None ** + ** Outputs: Return: Value of the logging trace level ** + ** Others: None ** ** ** ***************************************************************************/ int nas_parser_get_trace_level(void) @@ -195,15 +194,15 @@ int nas_parser_get_trace_level(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_network_host() ** + ** Name: nas_parser_get_network_host() ** ** ** ** Description: Returns the value of the network layer hostname ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the network layer hostname ** - ** Others: None ** + ** Outputs: Return: Value of the network layer hostname ** + ** Others: None ** ** ** ***************************************************************************/ const char *nas_parser_get_network_host(void) @@ -213,15 +212,15 @@ const char *nas_parser_get_network_host(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_network_port() ** + ** Name: nas_parser_get_network_port() ** ** ** ** Description: Returns the value of the network layer port number ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the network layer port number ** - ** Others: None ** + ** Outputs: Return: Value of the network layer port number ** + ** Others: None ** ** ** ***************************************************************************/ const char *nas_parser_get_network_port(void) @@ -231,15 +230,15 @@ const char *nas_parser_get_network_port(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_ueid() ** + ** Name: nas_parser_get_ueid() ** ** ** ** Description: Returns the value of the UE identifier option ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the UE identifier option ** - ** Others: None ** + ** Outputs: Return: Value of the UE identifier option ** + ** Others: None ** ** ** ***************************************************************************/ int nas_parser_get_ueid(void) @@ -249,15 +248,15 @@ int nas_parser_get_ueid(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_user_host() ** + ** Name: nas_parser_get_user_host() ** ** ** ** Description: Returns the value of the user application layer hostname ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the user app layer hostname ** - ** Others: None ** + ** Outputs: Return: Value of the user app layer hostname ** + ** Others: None ** ** ** ***************************************************************************/ const char *nas_parser_get_user_host(void) @@ -267,16 +266,16 @@ const char *nas_parser_get_user_host(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_user_port() ** + ** Name: nas_parser_get_user_port() ** ** ** ** Description: Returns the value of the user application layer port ** - ** number ** + ** number ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the user app layer port number ** - ** Others: None ** + ** Outputs: Return: Value of the user app layer port number ** + ** Others: None ** ** ** ***************************************************************************/ const char *nas_parser_get_user_port(void) @@ -286,15 +285,15 @@ const char *nas_parser_get_user_port(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_device_path() ** + ** Name: nas_parser_get_device_path() ** ** ** ** Description: Returns the value of the device pathname ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the device pathname ** - ** Others: None ** + ** Outputs: Return: Value of the device pathname ** + ** Others: None ** ** ** ***************************************************************************/ const char *nas_parser_get_device_path(void) @@ -304,15 +303,15 @@ const char *nas_parser_get_device_path(void) /**************************************************************************** ** ** - ** Name: nas_parser_get_device_params() ** + ** Name: nas_parser_get_device_params() ** ** ** ** Description: Returns the value of the device attribute parameters ** ** ** - ** Inputs: None ** - ** Others: None ** + ** Inputs: None ** + ** Others: None ** ** ** - ** Outputs: Return: Value of the device attribute parameters ** - ** Others: None ** + ** Outputs: Return: Value of the device attribute parameters ** + ** Others: None ** ** ** ***************************************************************************/ const char *nas_parser_get_device_params(void) diff --git a/openair3/SCTP/sctp_common.c b/openair3/SCTP/sctp_common.c index 55a2943924..66ffbec18a 100644 --- a/openair3/SCTP/sctp_common.c +++ b/openair3/SCTP/sctp_common.c @@ -41,7 +41,7 @@ #include "sctp_common.h" /* Pre-bind socket options configuration. - * See http://linux.die.net/man/7/sctp for more informations on these options. + * See http://linux.die.net/man/7/sctp for more information on these options. */ int sctp_set_init_opt(int sd, uint16_t instreams, uint16_t outstreams, uint16_t max_attempts, uint16_t init_timeout) diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 7052d6d40b..2325a7034b 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -56,7 +56,7 @@ typedef int64_t openair0_timestamp; typedef volatile int64_t openair0_vtimestamp; -/*!\brief structrue holds the parameters to configure USRP devices*/ +/*!\brief structure holds the parameters to configure USRP devices*/ typedef struct openair0_device_t openair0_device; //#define USRP_GAIN_OFFSET (56.0) // 86 calibrated for USRP B210 @ 2.6 GHz to get equivalent RS EPRE in OAI to SMBV100 output @@ -287,7 +287,7 @@ struct openair0_device_t { /*!brief Type of this device */ dev_type_t type; - /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */ + /*!brief Transport protocol type that the device supports (in case I/Q samples need to be transported) */ transport_type_t transp_type; /*!brief Type of the device's host (RAU/RRU) */ From 6835ac82d8661682f3b809855a20bd78bfa6d1cd Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 9 Jan 2020 14:32:33 +0100 Subject: [PATCH 117/134] RFSIMULATOR: final integration of Laurent Thomas's review feedback Signed-off-by: Raphael Defosseux --- targets/RT/USER/lte-ue.c | 113 ++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 8a4172965e..3dd13a0f22 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -59,6 +59,7 @@ #include "UTIL/MATH/oml.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" +#include "lte-softmodem.h" #include "common/config/config_userapi.h" #include "T.h" @@ -208,10 +209,10 @@ char uecap_xer[1024]; void init_thread(int sched_runtime, - int sched_deadline, - int sched_fifo, - cpu_set_t *cpuset, - char *name) + int sched_deadline, + int sched_fifo, + cpu_set_t *cpuset, + char *name) { #ifdef DEADLINE_SCHEDULER @@ -255,16 +256,16 @@ void init_thread(int sched_runtime, } void init_UE(int nb_inst, - int eMBMS_active, - int uecap_xer_in, - int timing_correction, - int phy_test, - int UE_scan, - int UE_scan_carrier, - runmode_t mode, - int rxgain, - int txpowermax, - LTE_DL_FRAME_PARMS *fp0) + int eMBMS_active, + int uecap_xer_in, + int timing_correction, + int phy_test, + int UE_scan, + int UE_scan_carrier, + runmode_t mode, + int rxgain, + int txpowermax, + LTE_DL_FRAME_PARMS *fp0) { PHY_VARS_UE *UE; int inst; @@ -397,9 +398,9 @@ void init_UE(int nb_inst, // Initiating all UEs within a single set of threads for PHY_STUB. Future extensions -> multiple // set of threads for multiple UEs. void init_UE_stub_single_thread(int nb_inst, - int eMBMS_active, - int uecap_xer_in, - char *emul_iface) + int eMBMS_active, + int uecap_xer_in, + char *emul_iface) { int inst; LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst); @@ -423,9 +424,9 @@ void init_UE_stub_single_thread(int nb_inst, void init_UE_stub(int nb_inst, - int eMBMS_active, - int uecap_xer_in, - char *emul_iface) + int eMBMS_active, + int uecap_xer_in, + char *emul_iface) { int inst; LOG_I(PHY,"UE : Calling Layer 2 for initialization\n"); @@ -899,7 +900,7 @@ static void *UE_thread_rxn_txnp4(void *arg) unsigned int emulator_absSF; void ue_stub_rx_handler(unsigned int num_bytes, - char *rx_buffer) + char *rx_buffer) { PHY_VARS_UE *UE; UE = PHY_vars_UE_g[0][0]; @@ -1511,6 +1512,23 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) * \param arg unused * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ +void write_dummy(PHY_VARS_UE *UE, openair0_timestamp timestamp) { + // we have to write to tell explicitly to the eNB, else it will wait for us forever + // we write the next subframe (always write in future of what we received) + // + struct complex16 v= {0}; + void *samplesVoid[UE->frame_parms.nb_antennas_tx]; + + for ( int i=0; i < UE->frame_parms.nb_antennas_tx; i++) + samplesVoid[i]=(void *)&v; + + AssertFatal(1 == UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+2*UE->frame_parms.samples_per_tti, + samplesVoid, + 1, + UE->frame_parms.nb_antennas_tx, + 1),""); +} void *UE_thread(void *arg) { @@ -1564,16 +1582,20 @@ void *UE_thread(void *arg) if (is_synchronized == 0) { if (instance_cnt_synch < 0) { // we can invoke the synch // grab 10 ms of signal and wakeup synch thread - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void *)&UE->common_vars.rxdata[i][0]; + if (UE->mode != loop_through_memory) { + for(int sf=0; sf<10; sf++) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf]; - if (UE->mode != loop_through_memory) - AssertFatal( UE->frame_parms.samples_per_tti*10 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx), ""); + AssertFatal(UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx), ""); + if (IS_SOFTMODEM_RFSIM ) + write_dummy(UE, timestamp); + } + } AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); instance_cnt_synch = ++UE->proc.instance_cnt_synch; @@ -1591,21 +1613,22 @@ void *UE_thread(void *arg) (void)dummy_rx; /* avoid gcc warnings */ usleep(500); #else - // grab 10 ms of signal into dummy buffer if (UE->mode != loop_through_memory) { for (int i=0; iframe_parms.nb_antennas_rx; i++) rxp[i] = (void *)&dummy_rx[i][0]; - for (int sf=0; sf<10; sf++) + for (int sf=0; sf<10; sf++) { // printf("Reading dummy sf %d\n",sf); UE->rfdevice.trx_read_func(&UE->rfdevice, ×tamp, rxp, UE->frame_parms.samples_per_tti, UE->frame_parms.nb_antennas_rx); + if (IS_SOFTMODEM_RFSIM ) + write_dummy(UE, timestamp); + } } - #endif } } // UE->is_synchronized==0 @@ -1616,12 +1639,17 @@ void *UE_thread(void *arg) if (UE->mode != loop_through_memory) { if (UE->no_timing_correction==0) { LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); - AssertFatal(UE->rx_offset == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void **)UE->common_vars.rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx),""); + while ( UE->rx_offset ) { + size_t s=min(UE->rx_offset,UE->frame_parms.samples_per_tti); + AssertFatal(s == UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + s, + UE->frame_parms.nb_antennas_rx),""); + if (IS_SOFTMODEM_RFSIM ) + write_dummy(UE, timestamp); + UE->rx_offset-=s; + } } UE->rx_offset=0; @@ -1662,6 +1690,7 @@ void *UE_thread(void *arg) pthread_mutex_unlock(&proc->mutex_rxtx); } + usleep(300); } LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); @@ -2014,7 +2043,7 @@ void fill_ue_band_info(void) #endif int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, - openair0_config_t *openair0_cfg) + openair0_config_t *openair0_cfg) { int i, CC_id; LTE_DL_FRAME_PARMS *frame_parms; @@ -2206,8 +2235,8 @@ int init_timer_thread(void) * fix it somehow */ int8_t find_dlsch(uint16_t rnti, - PHY_VARS_eNB *eNB, - find_type_t type) + PHY_VARS_eNB *eNB, + find_type_t type) { printf("you cannot read this\n"); abort(); From 6c3d5cf02d6a419a5f004bd10036a05d7bacc2a2 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 10 Jan 2020 13:27:02 +0100 Subject: [PATCH 118/134] Making the basic-sim on UE side able to synch! Signed-off-by: Raphael Defosseux --- ci-scripts/runTestOnVM.sh | 2 +- targets/RT/USER/lte-ue.c | 32 ++++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 32a1652783..1f9d945a63 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -522,7 +522,7 @@ function install_epc_on_vm { echo "############################################################" echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)" echo "############################################################" - echo "sudo [ -f 01proxy ] && cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS + echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 3dd13a0f22..5a8afc2358 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1582,18 +1582,30 @@ void *UE_thread(void *arg) if (is_synchronized == 0) { if (instance_cnt_synch < 0) { // we can invoke the synch // grab 10 ms of signal and wakeup synch thread - if (UE->mode != loop_through_memory) { - for(int sf=0; sf<10; sf++) { - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf]; - AssertFatal(UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx), ""); - if (IS_SOFTMODEM_RFSIM ) + if (UE->mode != loop_through_memory) { + if (IS_SOFTMODEM_RFSIM) { + for(int sf=0; sf<10; sf++) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf]; + + AssertFatal(UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx), ""); write_dummy(UE, timestamp); + } + } else { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][0]; + + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); } } From 7aa35e874b193c2d8ff143c52d24bbc4a68ddf23 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 10 Jan 2020 15:38:13 +0100 Subject: [PATCH 119/134] Removing obsolete LTE_RRC_VERSION Signed-off-by: Raphael Defosseux --- openair1/PHY/INIT/lte_init.c | 2 - openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 - openair1/PHY/LTE_TRANSPORT/transport_eNB.h | 2 - openair2/LAYER2/MAC/config.c | 2 - openair2/LAYER2/MAC/mac.h | 4 - openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 35 +++---- openair2/RRC/LTE/rrc_UE.c | 17 +-- openair2/RRC/LTE/rrc_eNB_M2AP.c | 114 +++------------------ 8 files changed, 28 insertions(+), 150 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 4736ae765e..2d65521ab3 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -329,9 +329,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config) { } lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); -#endif } void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx, diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 2b6d998b73..ce409de131 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2014,10 +2014,8 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_processes[harq_pid]->frame = frame; ulsch->harq_processes[harq_pid]->subframe = subframe; ulsch->harq_processes[harq_pid]->handled = 0; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ulsch->harq_processes[harq_pid]->repetition_number = ulsch_pdu->ulsch_pdu_rel13.repetition_number ; ulsch->harq_processes[harq_pid]->total_number_of_repetitions = ulsch_pdu->ulsch_pdu_rel13.total_number_of_repetitions ; -#endif ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start; ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; ulsch->harq_processes[harq_pid]->dci_alloc = 1; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index a80023c744..7b9004ba80 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -314,12 +314,10 @@ typedef struct { // int calibration_flag; /// delta_TF for power control int32_t delta_TF; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // PUSCH Repetition Number for the current SF uint32_t repetition_number ; // PUSCH Total number of repetitions uint32_t total_number_of_repetitions; -#endif } LTE_UL_eNB_HARQ_t; typedef struct { diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 7eb323abab..76c8e33b16 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -703,9 +703,7 @@ config_sib13( int Mod_id, // } // lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn); // -//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); -//#endif // PHY_Config_t phycfg; phycfg.Mod_id = Mod_id; diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index d81010c267..ac9819cfe2 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -906,10 +906,8 @@ typedef struct { uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; sub_frame_t Msg2_subframe; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// Repetition column in pusch_repetition Table 8.2.b in TS36.213 uint8_t pusch_repetition_levels; -#endif LTE_PhysicalConfigDedicated_t *physicalConfigDedicated; } UE_TEMPLATE; @@ -1117,10 +1115,8 @@ typedef struct { uint8_t msg2_narrowband; uint8_t msg34_narrowband; int msg4_rrc_sdu_length; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// Repetition column in pusch_repetition Table 8.2.b in TS36.213 uint8_t pusch_repetition_levels; -#endif int32_t crnti_rrc_mui; int8_t crnti_harq_pid; } RA_t; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 8ee8cdc1c0..c3d872d493 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -92,11 +92,9 @@ tbs_size_t mac_rlc_data_req( const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, const tb_size_t tb_sizeP, - char *buffer_pP -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t sourceL2Id - ,const uint32_t destinationL2Id -#endif + char *buffer_pP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id ) { int ret; @@ -147,11 +145,9 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, - const tb_size_t tb_sizeP -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t sourceL2Id - ,const uint32_t destinationL2Id -#endif + const tb_size_t tb_sizeP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id ) { nr_rlc_ue_t *ue; @@ -210,11 +206,9 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, const mui_t muiP, confirm_t confirmP, sdu_size_t sdu_sizeP, - mem_block_t *sdu_pP -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t *const sourceL2Id - ,const uint32_t *const destinationL2Id -#endif + mem_block_t *sdu_pP, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id ) { int rnti = ctxt_pP->rnti; @@ -754,13 +748,10 @@ static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const LTE_SRB_ToAddModList_t * const srb2add_listP, const LTE_DRB_ToAddModList_t * const drb2add_listP, - const LTE_DRB_ToReleaseList_t * const drb2release_listP -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP - ,const uint32_t sourceL2Id - ,const uint32_t destinationL2Id -#endif - ) + const LTE_DRB_ToReleaseList_t * const drb2release_listP, + const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id) { int rnti = ctxt_pP->rnti; int i; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 9383a726fb..e2030e9da3 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -3624,9 +3624,7 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, -#endif (LTE_MeasObjectToAddMod_t **)NULL, (LTE_MAC_MainConfig_t *)NULL, 0, @@ -3640,27 +3638,18 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { NULL, NULL, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, (LTE_MBSFN_AreaInfoList_r9_t *)NULL, - (LTE_PMCH_InfoList_r9_t *)NULL -#endif + (LTE_PMCH_InfoList_r9_t *)NULL, #ifdef CBA - ,0, - 0 + 0,0, #endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , 0, NULL, - NULL -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , + NULL, 0, (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, (LTE_MBSFN_AreaInfoList_r9_t *)NULL -#endif ); } diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.c b/openair2/RRC/LTE/rrc_eNB_M2AP.c index ac68bbcbcd..5ef4e6e249 100644 --- a/openair2/RRC/LTE/rrc_eNB_M2AP.c +++ b/openair2/RRC/LTE/rrc_eNB_M2AP.c @@ -52,7 +52,6 @@ rrc_M2AP_openair_rrc_top_init_MBMS(int eMBMS_active){ LOG_D(RRC, "[OPENAIR][INIT] Init function start: NB_eNB_INST=%d\n", RC.nb_inst); if (RC.nb_inst > 0) { -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[eNB] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_idcarrier[CC_id].MBMS_flag = (uint8_t)eMBMS_active; } } - -#endif } } @@ -222,9 +219,7 @@ static void rrc_M2AP_init_MBMS( NULL, // LTE_DRB_ToAddModList NULL, // DRB_ToReleaseList &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 -#endif ); } //rrc_mac_config_req(); @@ -280,15 +275,11 @@ static void rrc_M2AP_init_MCCH( if (NODE_IS_MONOLITHIC(rrc->node_type)) { rrc_mac_config_req_eNB(enb_mod_idP, CC_id, 0,0,0,0,0, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, -#endif 0,//rnti (LTE_BCCH_BCH_Message_t *)NULL, (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#endif (struct LTE_PhysicalConfigDedicated *)NULL, (LTE_SCellToAddMod_r10_t *)NULL, //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, @@ -304,20 +295,14 @@ static void rrc_M2AP_init_MCCH( , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , + (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9), + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL, 0, (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL -#endif ); } @@ -343,14 +328,12 @@ static void rrc_M2AP_init_MCCH( // // LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; // -//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // if (ctxt_pP->brOption) { // buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB1_BR; // bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].siblock1_BR; // sib1 = &RC.rrc[Mod_id]->carrier[CC_id].sib1_BR; // } // else -//#endif // { // buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB1; // bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].siblock1; @@ -409,11 +392,9 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList/*,*MBSFNSubframeConfigList_copy*/; //LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list/*,*MBSFNArea_list_copy*/; -#endif asn_enc_rval_t enc_rval; @@ -422,15 +403,12 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( LTE_SystemInformationBlockType2_t **sib2; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if(ctxt_pP->brOption){ buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); - }else -#endif - { + } else { buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; } @@ -568,15 +546,11 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( if (NODE_IS_MONOLITHIC(rrc->node_type)) { rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, 0,0,0,0,0, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, -#endif 0,//rnti (LTE_BCCH_BCH_Message_t *)NULL, (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#endif (struct LTE_PhysicalConfigDedicated *)NULL, (LTE_SCellToAddMod_r10_t *)NULL, //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, @@ -593,20 +567,14 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList, carrier->MBMS_flag, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_PMCH_InfoList_r9_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , + (LTE_PMCH_InfoList_r9_t *) NULL, + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL, 0, (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL -#endif ); } @@ -627,11 +595,9 @@ static uint8_t rrc_M2AP_do_SIB23_SIB13( rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; //LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list; -#endif asn_enc_rval_t enc_rval; @@ -640,21 +606,15 @@ static uint8_t rrc_M2AP_do_SIB23_SIB13( LTE_SystemInformationBlockType2_t **sib2; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if(ctxt_pP->brOption){ buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; - LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); - - }else -#endif - { + LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); + } else { buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; } - - if (bcch_message) { //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); } else { @@ -701,20 +661,15 @@ static uint8_t rrc_M2AP_do_SIB23_SIB13( }*/ -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; -#endif struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1/*, *MBSFN_Area2*/; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; *sib13 = &sib13_part->choice.sib13_v920; -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; (*sib13)->notificationConfig_r9.notificationOffset_r9=0; (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; @@ -741,11 +696,8 @@ for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); } -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib13_part); -#endif //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message); @@ -767,15 +719,11 @@ for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ if (NODE_IS_MONOLITHIC(rrc->node_type)) { rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, 0,0,0,0,0, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, -#endif 0,//rnti (LTE_BCCH_BCH_Message_t *)NULL, (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#endif (struct LTE_PhysicalConfigDedicated *)NULL, (LTE_SCellToAddMod_r10_t *)NULL, //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, @@ -791,20 +739,14 @@ for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ , 0, (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9, - (LTE_PMCH_InfoList_r9_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , + (LTE_PMCH_InfoList_r9_t *) NULL, + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL, 0, (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL -#endif ); } @@ -829,10 +771,8 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList/*,*MBSFNSubframeConfigList_copy*/; -#endif asn_enc_rval_t enc_rval; @@ -840,29 +780,20 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( uint8_t *buffer; LTE_SystemInformationBlockType2_t **sib2; -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list/*,*MBSFNArea_list_copy*/; LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1; -#endif - - -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if(ctxt_pP->brOption){ buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); - }else -#endif - { + } else { buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; } - - if (bcch_message) { //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); } else { @@ -912,7 +843,6 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: *sib13=&typeandinfo->choice.sib13_v920; -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; (*sib13)->notificationConfig_r9.notificationOffset_r9=0; (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; @@ -938,7 +868,6 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mcs; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); } -#endif break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib14_v1130: break; @@ -1004,15 +933,10 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( } if(*sib13==NULL){ -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; - *sib13 = &sib13_part->choice.sib13_v920; -#endif - -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; (*sib13)->notificationConfig_r9.notificationOffset_r9=0; (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; @@ -1039,12 +963,8 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); } -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib13_part); -#endif - } @@ -1070,15 +990,11 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( if (NODE_IS_MONOLITHIC(rrc->node_type)) { rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, 0,0,0,0,0, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, -#endif 0,//rnti (LTE_BCCH_BCH_Message_t *)NULL, (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (LTE_RadioResourceConfigCommonSIB_t *) NULL, -#endif (struct LTE_PhysicalConfigDedicated *)NULL, (LTE_SCellToAddMod_r10_t *)NULL, //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, @@ -1095,20 +1011,14 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList, carrier->MBMS_flag, (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9, - (LTE_PMCH_InfoList_r9_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL -#endif -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , + (LTE_PMCH_InfoList_r9_t *) NULL, + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL, 0, (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL -#endif ); } From 2dfad4c065c9e2160cff59a18b49152c854e18aa Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 13 Jan 2020 16:46:21 +0100 Subject: [PATCH 120/134] Fix compilation issues for: - physical simulators - LTE eNB - LTE UE - 5G-NR gNB Still NR-UE does not build and eNB segs fault at start of program Signed-off-by: Raphael Defosseux --- cmake_targets/CMakeLists.txt | 2 +- openair1/PHY/defs_RU.h | 2 +- openair1/PHY/defs_common.h | 3 --- openair1/PHY/defs_eNB.h | 1 + openair1/SCHED/ru_procedures.c | 8 ++++---- openair2/ENB_APP/enb_paramdef.h | 1 - openair2/F1AP/f1ap_du_rrc_message_transfer.c | 3 +-- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 6 +++--- openair2/LAYER2/RLC/rlc_rrc.c | 2 +- openair2/MCE_APP/mce_config.h | 2 +- openair2/PHY_INTERFACE/IF_Module.h | 1 - .../MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 | 2 +- openair2/RRC/LTE/rrc_UE.c | 1 + openair2/RRC/LTE/rrc_eNB_M2AP.c | 12 ++++++++++++ openair3/MME_APP/mme_config.h | 2 +- targets/RT/USER/lte-ru.c | 4 ++-- targets/RT/USER/ru_control.c | 4 ++-- 17 files changed, 32 insertions(+), 24 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 273591c8e2..6f9e923939 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2589,7 +2589,7 @@ target_link_libraries (nr-softmodem UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - X2AP_LIB X2AP_ENB F1AP_LIB F1AP ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} + X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} -Wl,--end-group z dl) target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index aeada81d80..94afeed12f 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -37,7 +37,7 @@ #include "common_lib.h" #include "openairinterface5g_limits.h" #include "PHY/TOOLS/time_meas.h" -#include "openair1/PHY/defs_common.h" +#include "defs_common.h" #define MAX_BANDS_PER_RRU 4 diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 811ae17e71..463523a9ba 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -72,9 +72,6 @@ #include "types.h" #include "nfapi_interface.h" -//#include "defs.h" - -#include "defs_RU.h" #define RX_NB_TH_MAX 2 #define RX_NB_TH 2 diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index dba49b6a78..7b06f6c8c7 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -57,6 +57,7 @@ #include "common_lib.h" #include "msc.h" #include "defs_common.h" +#include "defs_RU.h" #include "impl_defs_top.h" #include "PHY/TOOLS/time_meas.h" //#include "PHY/CODING/coding_defs.h" diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 0188f5cab5..8e95f89250 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -80,7 +80,7 @@ void feptx0(RU_t *ru, slot_offset = slot*(fp->samples_per_tti>>1); //slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1)); - //LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d\n",ru->proc.frame_tx, ru->proc.subframe_tx,slot); + //LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d\n",ru->proc.frame_tx, ru->proc.tti_tx,slot); for (aa=0; aanb_tx; aa++) { if (fp->Ncp == EXTENDED) { @@ -105,7 +105,7 @@ void feptx0(RU_t *ru, CYCLIC_PREFIX); LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d F(%d) t(%d) IS PMCH(%d)\n", ru->proc.frame_tx, - ru->proc.subframe_tx, + ru->proc.tti_tx, slot, slot*slot_sizeF+fp->ofdm_symbol_size*2, slot_offset+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2), @@ -214,7 +214,7 @@ static void *feptx_thread(void *param) } /*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_mod_wakeup_stats,"fep wakeup",stderr); - printf("delay in fep wakeup in frame_tx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); + printf("delay in fep wakeup in frame_tx: %d subframe_rx: %d \n",proc->frame_tx,proc->tti_tx); }*/ } return(NULL); @@ -273,7 +273,7 @@ void feptx_ofdm_2thread(RU_t *ru, stop_meas(&ru->ofdm_mod_wait_stats); /*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr); - printf("delay in feptx wait on condition in frame_rx: %d subframe_rx: %d \n", proc->frame_tx, proc->subframe_tx); + printf("delay in feptx wait on condition in frame_rx: %d subframe_rx: %d \n", proc->frame_tx, proc->tti_tx); }*/ stop_meas(&ru->ofdm_mod_stats); diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 36ede04e34..2975cf4aea 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -1050,7 +1050,6 @@ typedef struct srb1_params_s { {ENB_CONFIG_STRING_MCE_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MCE_PORT_FOR_M2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \ } -} /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* GTPU configuration parameters */ diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 223155c98a..f93a6724a3 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -541,6 +541,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, if (pdcp_pdu_p != NULL) { memset(pdcp_pdu_p->data, 0, rrc_dl_sdu_len); memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, rrc_dl_sdu_len); + rlc_status = rlc_data_req(&ctxt , 1 , MBMS_FLAG_NO @@ -549,10 +550,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, , 0 , rrc_dl_sdu_len , pdcp_pdu_p -#ifdef Rel14 ,NULL ,NULL -#endif ); switch (rlc_status) { case RLC_OP_STATUS_OK: diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index df65240d62..f198a98b23 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -295,9 +295,9 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p ctxt.module_id, ctxt.rnti, ctxt.enb_flag); if (h_rc == HASH_TABLE_OK) { - LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", ctxt.frame, ctxt.instance, len, rab_id); - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id); MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, @@ -334,7 +334,7 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p MSC_AS_TIME_ARGS(ctxt_pP), ctxt.instance, rab_id, rab_id, len); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); //if (!UE_NAS_USE_TUN) { diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 73da0cdb66..85ee4e0571 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -379,7 +379,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP } } - LOG_I(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %ld SESSION ID %u SERVICE ID %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id, rb_id, diff --git a/openair2/MCE_APP/mce_config.h b/openair2/MCE_APP/mce_config.h index f339401540..3078b64e49 100644 --- a/openair2/MCE_APP/mce_config.h +++ b/openair2/MCE_APP/mce_config.h @@ -37,7 +37,7 @@ #include "commonDef.h" #include "platform_types.h" #include "platform_constants.h" -#include "PHY/impl_defs_lte.h" +#include "PHY/impl_defs_top.h" #include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" #include "f1ap_messages_types.h" diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index b964ab565d..f260222097 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -140,7 +140,6 @@ typedef struct IF_Module_s { void (*UL_indication)(UL_IND_t *UL_INFO); void (*schedule_response)(Sched_Rsp_t *Sched_INFO); void (*PHY_config_req)(PHY_Config_t *config_INFO); - void (*PHY_config_req)(PHY_Config_t* config_INFO); void (*PHY_config_update_sib2_req)(PHY_Config_t* config_INFO); void (*PHY_config_update_sib13_req)(PHY_Config_t* config_INFO); uint32_t CC_mask; diff --git a/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 index 91194c2ff5..02b8843c2b 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 +++ b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 @@ -126,7 +126,7 @@ DL-DCCH-MessageType ::= CHOICE { loggedMeasurementConfiguration-r10 LoggedMeasurementConfiguration-r10, rnReconfiguration-r10 RNReconfiguration-r10, rrcConnectionResume-r13 RRCConnectionResume-r13, - spare3 NULL, spare2 NULL, spare1 NULL + spare4 NULL, spare3 NULL, spare2 NULL, spare1 NULL }, messageClassExtension SEQUENCE {} } diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index e2030e9da3..4c0965b0ae 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -2165,6 +2165,7 @@ rrc_ue_decode_dcch( case LTE_DL_DCCH_MessageType__c1_PR_spare1: case LTE_DL_DCCH_MessageType__c1_PR_spare2: case LTE_DL_DCCH_MessageType__c1_PR_spare3: + case LTE_DL_DCCH_MessageType__c1_PR_spare4: break; default: diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.c b/openair2/RRC/LTE/rrc_eNB_M2AP.c index 5ef4e6e249..bd586dfc71 100644 --- a/openair2/RRC/LTE/rrc_eNB_M2AP.c +++ b/openair2/RRC/LTE/rrc_eNB_M2AP.c @@ -476,6 +476,12 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib24_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib25_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530: + break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2); @@ -885,6 +891,12 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib24_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib25_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530: + break; case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2); diff --git a/openair3/MME_APP/mme_config.h b/openair3/MME_APP/mme_config.h index 97b2fae032..4371ad55f6 100644 --- a/openair3/MME_APP/mme_config.h +++ b/openair3/MME_APP/mme_config.h @@ -36,7 +36,7 @@ #include "commonDef.h" #include "platform_types.h" #include "platform_constants.h" -#include "PHY/impl_defs_lte.h" +#include "PHY/impl_defs_top.h" #include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" #include "f1ap_messages_types.h" diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 084543e396..459732a30c 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1889,8 +1889,8 @@ static void *ru_thread( void *param ) { #ifdef MBMS_EXPERIMENTAL //Workaround ... this must be properly handled if(ru->if_south==LOCAL_RF && ru->function==eNodeB_3GPP && RC.eNB[0][0]!=NULL){ - if(ru->frame_parms.num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){ - ru->frame_parms = RC.eNB[0][0]->frame_parms;//->frame_parms; + if(ru->frame_parms->num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){ + ru->frame_parms = &RC.eNB[0][0]->frame_parms;//->frame_parms; LOG_W(PHY,"RU MBSFN SF PARAMS Updated\n"); } } diff --git a/targets/RT/USER/ru_control.c b/targets/RT/USER/ru_control.c index e01749b294..6daf0f4dfa 100644 --- a/targets/RT/USER/ru_control.c +++ b/targets/RT/USER/ru_control.c @@ -685,9 +685,9 @@ void* ru_thread_control( void* param ) msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); LOG_W(PHY,"New MBSFN config received from RAU --- num_MBSFN_config %d\n",((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config); - ru->frame_parms.num_MBSFN_config = ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config; + ru->frame_parms->num_MBSFN_config = ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config; for(int i=0; i < ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config; i++){ - ru->frame_parms.MBSFN_config[i].mbsfn_SubframeConfig=((RRU_config_t *)&rru_config_msg.msg[0])->MBSFN_config[i].mbsfn_SubframeConfig; + ru->frame_parms->MBSFN_config[i].mbsfn_SubframeConfig=((RRU_config_t *)&rru_config_msg.msg[0])->MBSFN_config[i].mbsfn_SubframeConfig; LOG_W(PHY,"Configuration received from RAU (num MBSFN %d, MBSFN_SubframeConfig[%d] pattern is %x )\n", ((RRU_config_t *)&rru_config_msg.msg[0])->num_MBSFN_config, i, From ffd80e2cafda3c796e5b477c3da18acc8b6332cb Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 14 Jan 2020 10:44:48 +0100 Subject: [PATCH 121/134] Fixing easy cppcheck errors Signed-off-by: Raphael Defosseux --- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- openair2/NR_PHY_INTERFACE/nfapi_5g_test.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 724faf1d7f..afd40c87e9 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -92,7 +92,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, const tb_size_t tb_sizeP, const uint32_t sourceL2Id, const uint32_t destinationL2Id) -{mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} +{mac_rlc_status_resp_t mac_rlc_status_resp = {0}; return mac_rlc_status_resp;} tbs_size_t mac_rlc_data_req( const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, diff --git a/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c b/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c index 7736252a07..5d2cf18974 100644 --- a/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c +++ b/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c @@ -8,8 +8,9 @@ int main ( int argc, char** argv) { nfapi_nr_cell_param_t nfapi_nr_cell_param_test; - nfapi_nr_param_tlv_t* tlvs_to_report_list; - nfapi_nr_cell_param_test.config_tlvs_to_report_list = tlvs_to_report_list; + nfapi_nr_param_tlv_t tlvs_to_report_list; + + nfapi_nr_cell_param_test.config_tlvs_to_report_list = &tlvs_to_report_list; nfapi_nr_cell_param_test.phy_state = 0; nfapi_nr_cell_param_test.release_capability = 0; nfapi_nr_cell_param_test.skip_blank_dl_config = 0; From 7292fb2505d257478e869f595427038d9cca7060 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 15 Jan 2020 12:56:52 +0100 Subject: [PATCH 122/134] NR-UE: fix temporarly the build. Quite dirty. Signed-off-by: Raphael Defosseux --- cmake_targets/CMakeLists.txt | 5 +- executables/nr-ue.c | 16 ++++++ executables/nr-uesoftmodem.c | 10 ++++ openair1/PHY/INIT/nr_init_ue.c | 2 + openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 7 +++ .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 12 +++-- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 20 +++---- .../nr_dlsch_llr_computation.c | 44 ++++++++-------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 16 +++--- openair1/PHY/phy_vars_nr_ue.h | 2 + openair1/SCHED_NR_UE/defs.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 52 ++++++++++--------- .../SCHED_NR_UE/pucch_power_control_ue_nr.c | 3 +- openair1/SCHED_NR_UE/pucch_uci_ue_nr.c | 11 ++-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 4 +- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 18 +++++++ 16 files changed, 148 insertions(+), 76 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6f9e923939..2bff30d5e7 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1722,6 +1722,7 @@ set(NR_L2_SRC_UE ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c + ${LTE_RLC_SRC} ) set (MAC_SRC @@ -2612,6 +2613,7 @@ add_executable(nr-uesoftmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c @@ -2627,7 +2629,8 @@ target_link_libraries (nr-uesoftmodem -Wl,--start-group RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} - PHY_COMMON PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON NFAPI_USER_LIB S1AP_LIB S1AP_ENB + PHY_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES}) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 92bcc743bc..e2ef2f6942 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -55,6 +55,9 @@ extern char do_forms; #endif +// Missing stuff? +int next_ra_frame = 0; +module_id_t next_Mod_id = 0; extern double cpuf; //static nfapi_nr_config_request_t config_t; @@ -845,3 +848,16 @@ void init_NR_UE(int nb_inst) { printf("UE threads created by %ld\n", gettid()); } +/* HACK: this function is needed to compile the UE + * fix it somehow + */ +int8_t find_dlsch(uint16_t rnti, + PHY_VARS_eNB *eNB, + find_type_t type) +{ + printf("you cannot read this\n"); + abort(); +} + +void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {} + diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index d3e9300053..0887a2ef21 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -111,6 +111,16 @@ static pthread_t forms_thread; //xforms #include "executables/softmodem-common.h" #include "executables/thread-common.h" +// Raphael : missing +pthread_cond_t nfapi_sync_cond; +pthread_mutex_t nfapi_sync_mutex; +int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex +uint16_t sf_ahead=6; //??? value ??? +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. +int config_sync_var=-1; + RAN_CONTEXT_t RC; volatile int start_eNB = 0; volatile int start_UE = 0; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 0c7ce1cdd6..ca92c384a5 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -357,6 +357,7 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id, } #endif +#if 0 void phy_config_harq_ue(module_id_t Mod_id, int CC_id, uint8_t eNB_id, @@ -368,6 +369,7 @@ void phy_config_harq_ue(module_id_t Mod_id, for (num_of_code_words=0; num_of_code_wordsulsch[num_of_threads][eNB_id][num_of_code_words]->Mlimit = max_harq_tx; } +#endif extern uint16_t beta_cqi[16]; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 3e1a579e89..ba328e39ec 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -90,4 +90,11 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id); +/*! \brief Function to return the path-loss based on the UE cell-specific reference signal strength and transmission power of eNB +@param Mod_id Module ID for UE +@param eNB_index Index of eNB on which to act +@returns Path loss in dB + */ +int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + #endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 092fdfd1fc..ac9713fec2 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -34,6 +34,7 @@ //#define DEBUG_MEAS_UE //#define DEBUG_RANK_EST +#if 0 int16_t cond_num_threshold = 0; void print_shorts(char *s,short *x) @@ -54,8 +55,9 @@ void print_ints(char *s,int *x) ); } +#endif -int16_t get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) +int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; @@ -69,7 +71,7 @@ int16_t get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) RSoffset = 3; */ - /* LOG_D(PHY,"get_PL : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", + /* LOG_D(PHY,"nr_get_PL : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", (1.0*dB_fixed_times10(ue->measurements.rsrp[eNB_index])-(10.0*ue->rx_total_gain_dB))/10.0, 10*log10((double)ue->measurements.rsrp[eNB_index]), ue->frame_parms.pdsch_config_common.referenceSignalPower);*/ @@ -79,9 +81,9 @@ int16_t get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) // dB_fixed_times10(RSoffset*12*ue_g[Mod_id][CC_id]->frame_parms.N_RB_DL) + //(ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10)); } + + #if 0 - - uint8_t get_n_adj_cells (module_id_t Mod_id,uint8_t CC_id) { @@ -456,6 +458,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, } #endif +#if 0 void conjch0_mult_ch1(int *ch0, int *ch1, int32_t *ch0conj_ch1, @@ -696,6 +699,7 @@ void numer(int32_t *Hh_h_00_sq, _m_empty(); } +#endif void nr_ue_measurements(PHY_VARS_NR_UE *ue, unsigned int subframe_offset, diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index ea90111bcc..69077f0276 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -197,7 +197,7 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, #endif - +#if 0 int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, char *pdcch_llr, @@ -229,11 +229,12 @@ int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, return(0); } +#endif //__m128i avg128P; //compute average channel_level on each (TX,RX) antenna pair -void pdcch_channel_level(int32_t **dl_ch_estimates_ext, +void nr_pdcch_channel_level(int32_t **dl_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, int32_t *avg, uint8_t nb_rb) { @@ -651,7 +652,7 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext, } -void pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, +void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, uint8_t symbol) { #if defined(__x86_64__) || defined(__i386__) @@ -686,6 +687,7 @@ void pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, #endif } +#if 0 void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, uint8_t l) { @@ -700,7 +702,7 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms, } } } - +#endif @@ -812,10 +814,10 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, coreset_freq_dom, coreset_nbr_rb, n_rb_offset); - LOG_DD("we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); - LOG_DD("in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); + LOG_DD("we enter nr_pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); + LOG_DD("in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); // compute channel level based on ofdm symbol 0 - pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, + nr_pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, avgP, coreset_nbr_rb); @@ -851,9 +853,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif if (frame_parms->nb_antennas_rx > 1) { - LOG_DD("we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", + LOG_DD("we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx); - pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s); + nr_pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s); } LOG_DD("we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c index 036316dbaa..35458f330f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c @@ -39,8 +39,8 @@ //#define DEBUG_LLR_SIC -int16_t zeros[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; -int16_t ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; +int16_t nr_zeros[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; +int16_t nr_ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; #if defined(__x86_64__) || defined(__i386__) __m128i rho_rpi __attribute__ ((aligned(16))); __m128i rho_rmi __attribute__ ((aligned(16))); @@ -604,11 +604,11 @@ __m128i tmp_result4 __attribute__ ((aligned(16))); #define prodsum_psi_a_epi16(psi_r,a_r,psi_i,a_i,psi_a) tmp_result = _mm_mulhi_epi16(psi_r,a_r); tmp_result = _mm_slli_epi16(tmp_result,1); tmp_result2 = _mm_mulhi_epi16(psi_i,a_i); tmp_result2 = _mm_slli_epi16(tmp_result2,1); psi_a = _mm_adds_epi16(tmp_result,tmp_result2); // calculate interference magnitude -#define interference_abs_epi16(psi,int_ch_mag,int_mag,c1,c2) tmp_result = _mm_cmplt_epi16(psi,int_ch_mag); tmp_result2 = _mm_xor_si128(tmp_result,(*(__m128i*)&ones[0])); tmp_result = _mm_and_si128(tmp_result,c1); tmp_result2 = _mm_and_si128(tmp_result2,c2); int_mag = _mm_or_si128(tmp_result,tmp_result2); +#define interference_abs_epi16(psi,int_ch_mag,int_mag,c1,c2) tmp_result = _mm_cmplt_epi16(psi,int_ch_mag); tmp_result2 = _mm_xor_si128(tmp_result,(*(__m128i*)&nr_ones[0])); tmp_result = _mm_and_si128(tmp_result,c1); tmp_result2 = _mm_and_si128(tmp_result2,c2); int_mag = _mm_or_si128(tmp_result,tmp_result2); // calculate interference magnitude -// tmp_result = ones in shorts corr. to interval 2<=x<=4, tmp_result2 interval < 2, tmp_result3 interval 46 -#define interference_abs_64qam_epi16(psi,int_ch_mag,int_two_ch_mag,int_three_ch_mag,a,c1,c3,c5,c7) tmp_result = _mm_cmplt_epi16(psi,int_two_ch_mag); tmp_result3 = _mm_xor_si128(tmp_result,(*(__m128i*)&ones[0])); tmp_result2 = _mm_cmplt_epi16(psi,int_ch_mag); tmp_result = _mm_xor_si128(tmp_result,tmp_result2); tmp_result4 = _mm_cmpgt_epi16(psi,int_three_ch_mag); tmp_result3 = _mm_xor_si128(tmp_result3,tmp_result4); tmp_result = _mm_and_si128(tmp_result,c3); tmp_result2 = _mm_and_si128(tmp_result2,c1); tmp_result3 = _mm_and_si128(tmp_result3,c5); tmp_result4 = _mm_and_si128(tmp_result4,c7); tmp_result = _mm_or_si128(tmp_result,tmp_result2); tmp_result3 = _mm_or_si128(tmp_result3,tmp_result4); a = _mm_or_si128(tmp_result,tmp_result3); +// tmp_result = nr_ones in shorts corr. to interval 2<=x<=4, tmp_result2 interval < 2, tmp_result3 interval 46 +#define interference_abs_64qam_epi16(psi,int_ch_mag,int_two_ch_mag,int_three_ch_mag,a,c1,c3,c5,c7) tmp_result = _mm_cmplt_epi16(psi,int_two_ch_mag); tmp_result3 = _mm_xor_si128(tmp_result,(*(__m128i*)&nr_ones[0])); tmp_result2 = _mm_cmplt_epi16(psi,int_ch_mag); tmp_result = _mm_xor_si128(tmp_result,tmp_result2); tmp_result4 = _mm_cmpgt_epi16(psi,int_three_ch_mag); tmp_result3 = _mm_xor_si128(tmp_result3,tmp_result4); tmp_result = _mm_and_si128(tmp_result,c3); tmp_result2 = _mm_and_si128(tmp_result2,c1); tmp_result3 = _mm_and_si128(tmp_result3,c5); tmp_result4 = _mm_and_si128(tmp_result4,c7); tmp_result = _mm_or_si128(tmp_result,tmp_result2); tmp_result3 = _mm_or_si128(tmp_result3,tmp_result4); a = _mm_or_si128(tmp_result,tmp_result3); // calculates a_sq = int_ch_mag*(a_r^2 + a_i^2)*scale_factor #define square_a_epi16(a_r,a_i,int_ch_mag,scale_factor,a_sq) tmp_result = _mm_mulhi_epi16(a_r,a_r); tmp_result = _mm_slli_epi16(tmp_result,1); tmp_result = _mm_mulhi_epi16(tmp_result,scale_factor); tmp_result = _mm_slli_epi16(tmp_result,1); tmp_result = _mm_mulhi_epi16(tmp_result,int_ch_mag); tmp_result = _mm_slli_epi16(tmp_result,1); tmp_result2 = _mm_mulhi_epi16(a_i,a_i); tmp_result2 = _mm_slli_epi16(tmp_result2,1); tmp_result2 = _mm_mulhi_epi16(tmp_result2,scale_factor); tmp_result2 = _mm_slli_epi16(tmp_result2,1); tmp_result2 = _mm_mulhi_epi16(tmp_result2,int_ch_mag); tmp_result2 = _mm_slli_epi16(tmp_result2,1); a_sq = _mm_adds_epi16(tmp_result,tmp_result2); @@ -1142,7 +1142,7 @@ int nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, // printf("nr_dlsch_qpsk_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); // printf("qpsk_qpsk: len %d, llr16 %p\n",len,llr16); - qpsk_qpsk((short *)rxF, + nr_qpsk_qpsk((short *)rxF, (short *)rxF_i, (short *)llr16, (short *)rho, @@ -1156,7 +1156,7 @@ int nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, //__m128i ONE_OVER_SQRT_8 __attribute__((aligned(16))); -void qpsk_qpsk(short *stream0_in, +void nr_qpsk_qpsk(short *stream0_in, short *stream1_in, short *stream0_out, short *rho01, @@ -1390,7 +1390,7 @@ int nr_dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - qpsk_qam16((short *)rxF, + nr_qpsk_qam16((short *)rxF, (short *)rxF_i, (short *)ch_mag_i, (short *)llr16, @@ -1413,7 +1413,7 @@ __m128i SQRT_10_OVER_FOUR __attribute__((aligned(16))); __m128i ch_mag_int; #endif */ -void qpsk_qam16(int16_t *stream0_in, +void nr_qpsk_qam16(int16_t *stream0_in, int16_t *stream1_in, int16_t *ch_mag_i, int16_t *stream0_out, @@ -1672,7 +1672,7 @@ int nr_dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - qpsk_qam64((short *)rxF, + nr_qpsk_qam64((short *)rxF, (short *)rxF_i, (short *)ch_mag_i, (short *)llr16, @@ -1695,7 +1695,7 @@ __m128i two_ch_mag_int_with_sigma2 __attribute__((aligned(16))); __m128i three_ch_mag_int_with_sigma2 __attribute__((aligned(16))); __m128i SQRT_42_OVER_FOUR __attribute__((aligned(16))); */ -void qpsk_qam64(short *stream0_in, +void nr_qpsk_qam64(short *stream0_in, short *stream1_in, short *ch_mag_i, short *stream0_out, @@ -1947,7 +1947,7 @@ __m128i ch_mag_over_2 __attribute__ ((aligned(16))); __m128i ch_mag_9_over_10 __attribute__ ((aligned(16))); */ -void qam16_qpsk(short *stream0_in, +void nr_qam16_qpsk(short *stream0_in, short *stream1_in, short *ch_mag, short *stream0_out, @@ -2440,7 +2440,7 @@ int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, // printf("symbol %d: qam16_llr, len %d (llr16 %p)\n",symbol,len,llr16); - qam16_qpsk((short *)rxF, + nr_qam16_qpsk((short *)rxF, (short *)rxF_i, (short *)ch_mag, (short *)llr16, @@ -2453,7 +2453,7 @@ int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, return(0); } -void qam16_qam16(short *stream0_in, +void nr_qam16_qam16(short *stream0_in, short *stream1_in, short *ch_mag, short *ch_mag_i, @@ -2981,7 +2981,7 @@ int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, // printf("symbol %d: qam16_llr, len %d (llr16 %p)\n",symbol,len,llr16); - qam16_qam16((short *)rxF, + nr_qam16_qam16((short *)rxF, (short *)rxF_i, (short *)ch_mag, (short *)ch_mag_i, @@ -2995,7 +2995,7 @@ int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, return(0); } -void qam16_qam64(int16_t *stream0_in, +void nr_qam16_qam64(int16_t *stream0_in, int16_t *stream1_in, int16_t *ch_mag, int16_t *ch_mag_i, @@ -3615,7 +3615,7 @@ int nr_dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, // printf("symbol %d: qam16_llr, len %d (llr16 %p)\n",symbol,len,llr16); - qam16_qam64((short *)rxF, + nr_qam16_qam64((short *)rxF, (short *)rxF_i, (short *)ch_mag, (short *)ch_mag_i, @@ -3670,7 +3670,7 @@ __m128i ch_mag_2_over_42_with_sigma2 __attribute__((aligned(16))); */ -void qam64_qpsk(int16_t *stream0_in, +void nr_qam64_qpsk(int16_t *stream0_in, int16_t *stream1_in, int16_t *ch_mag, int16_t *stream0_out, @@ -5175,7 +5175,7 @@ int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - qam64_qpsk((short *)rxF, + nr_qam64_qpsk((short *)rxF, (short *)rxF_i, (short *)ch_mag, (short *)llr16, @@ -5189,7 +5189,7 @@ int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, -void qam64_qam16(short *stream0_in, +void nr_qam64_qam16(short *stream0_in, short *stream1_in, short *ch_mag, short *ch_mag_i, @@ -6718,7 +6718,7 @@ int nr_dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - qam64_qam16((short *)rxF, + nr_qam64_qam16((short *)rxF, (short *)rxF_i, (short *)ch_mag, (short *)ch_mag_i, @@ -6731,6 +6731,7 @@ int nr_dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, return(0); } +#if 0 void qam64_qam64(short *stream0_in, short *stream1_in, short *ch_mag, @@ -8481,6 +8482,7 @@ void qam64_qam64(short *stream0_in, _m_empty(); #endif } +#endif int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index d5b993e391..ba4459a883 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -90,7 +90,7 @@ void dump_mch(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qpsk_qpsk(int16_t *stream0_in, +void nr_qpsk_qpsk(int16_t *stream0_in, int16_t *stream1_in, int16_t *stream0_out, int16_t *rho01, @@ -126,7 +126,7 @@ int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qpsk_qam16(int16_t *stream0_in, +void nr_qpsk_qam16(int16_t *stream0_in, int16_t *stream1_in, short *ch_mag_i, int16_t *stream0_out, @@ -164,7 +164,7 @@ int32_t nr_dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qpsk_qam64(int16_t *stream0_in, +void nr_qpsk_qam64(int16_t *stream0_in, int16_t *stream1_in, short *ch_mag_i, int16_t *stream0_out, @@ -202,7 +202,7 @@ int32_t nr_dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qam16_qpsk(short *stream0_in, +void nr_qam16_qpsk(short *stream0_in, short *stream1_in, short *ch_mag, short *stream0_out, @@ -240,7 +240,7 @@ int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qam16_qam16(short *stream0_in, +void nr_qam16_qam16(short *stream0_in, short *stream1_in, short *ch_mag, short *ch_mag_i, @@ -283,7 +283,7 @@ int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qam16_qam64(short *stream0_in, +void nr_qam16_qam64(short *stream0_in, short *stream1_in, short *ch_mag, short *ch_mag_i, @@ -324,7 +324,7 @@ int nr_dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qam64_qpsk(short *stream0_in, +void nr_qam64_qpsk(short *stream0_in, short *stream1_in, short *ch_mag, short *stream0_out, @@ -363,7 +363,7 @@ int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, @param stream0_out Output from LLR unit for stream0 @param rho01 Cross-correlation between channels (MR combined) @param length in complex channel outputs*/ -void qam64_qam16(short *stream0_in, +void nr_qam64_qam16(short *stream0_in, short *stream1_in, short *ch_mag, short *ch_mag_i, diff --git a/openair1/PHY/phy_vars_nr_ue.h b/openair1/PHY/phy_vars_nr_ue.h index c3eecb9008..7f9d20e624 100644 --- a/openair1/PHY/phy_vars_nr_ue.h +++ b/openair1/PHY/phy_vars_nr_ue.h @@ -141,4 +141,6 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32))); uint8_t scrambling_lut[65536*16] __attribute__((aligned(32))); uint8_t max_ldpc_iterations=4; +uint8_t max_turbo_iterations=4; + #endif /*__PHY_VARS_H__ */ diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 8e42149add..d38f962300 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -292,7 +292,7 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance); void nr_process_timing_advance_rar(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance); -unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); +unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5b4675fe39..f118498991 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -89,7 +89,7 @@ fifo_dump_emos_UE emos_dump_UE; #define NS_PER_SLOT 500000 -char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; +char nr_mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; extern double cpuf; @@ -565,8 +565,8 @@ void ue_compute_srs_occasion(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t // Simultaneous-AN-and-SRS is FALSE // check PUCCH format 2/2a/2b transmissions - is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0); - is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe; + is_pucch2_subframe = nr_is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0); + is_pucch2_subframe = (nr_is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe; // check ACK/SR transmission if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE) @@ -1474,7 +1474,7 @@ if (ue->prach_resources[eNB_id]!=NULL) { LOG_I(PHY,"mode %d\n",mode); if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) { - ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id); + ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id); } else { ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm; @@ -1486,7 +1486,7 @@ if (ue->prach_resources[eNB_id]!=NULL) { frame_tx, nr_tti_tx, ue->prach_resources[eNB_id]->ra_PreambleIndex, - get_PL(ue->Mod_id,ue->CC_id,eNB_id), + nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id), ue->tx_power_dBm[nr_tti_tx], ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, ue->prach_resources[eNB_id]->ra_TDD_map_index, @@ -1495,7 +1495,7 @@ if (ue->prach_resources[eNB_id]!=NULL) { ue->tx_total_RE[nr_tti_tx] = 96; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], + ue->prach_vars[eNB_id]->amp = nr_get_tx_amp(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, 6); @@ -1518,7 +1518,7 @@ if (ue->prach_resources[eNB_id]!=NULL) { // stop_meas(&ue->tx_prach); LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", ue->Mod_id, - get_PL(ue->Mod_id,ue->CC_id,eNB_id), + nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id), ue->tx_power_dBm[nr_tti_tx], dB_fixed(prach_power), ue->prach_vars[eNB_id]->amp); @@ -1537,8 +1537,8 @@ if (ue->prach_resources[eNB_id]!=NULL) { LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", ue->Mod_id,frame_tx,nr_tti_tx,eNB_id, ue->prach_resources[eNB_id]->ra_PreambleIndex, - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id), - get_PL(ue->Mod_id,ue->CC_id,eNB_id)); + ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id), + nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id)); } @@ -1560,6 +1560,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR #endif +#if 0 void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, @@ -1715,10 +1716,10 @@ void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, // check Periodic CQI/RI reporting cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& - (is_cqi_TXOp(ue,proc,eNB_id)==1)); + (nr_is_cqi_TXOp(ue,proc,eNB_id)==1)); ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && - (is_ri_TXOp(ue,proc,eNB_id)==1)); + (nr_is_ri_TXOp(ue,proc,eNB_id)==1)); // compute CQI/RI resources compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status); @@ -1923,7 +1924,7 @@ if (abstraction_flag == 0) { ue->tx_total_RE[nr_tti_tx] = nb_rb*12; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - tx_amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], + tx_amp = nr_get_tx_amp(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, nb_rb); @@ -1932,7 +1933,7 @@ if (abstraction_flag == 0) { #endif #if T_TRACER T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]), - T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); + T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(nr_get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif #ifdef UE_DEBUG_TRACE @@ -1982,6 +1983,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR #endif } +#endif #if 0 @@ -2014,7 +2016,7 @@ void ue_srs_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) if (ue->mac_enabled==1) { - tx_amp = get_tx_amp(Po_SRS, + tx_amp = nr_get_tx_amp(Po_SRS, ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, nb_rb_srs); @@ -2239,10 +2241,10 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ nb_cw = ( (ack_status_cw0 != 0) ? 1:0) + ( (ack_status_cw1 != 0) ? 1:0); cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& - (is_cqi_TXOp(ue,proc,eNB_id)==1)); + (nr_is_cqi_TXOp(ue,proc,eNB_id)==1)); ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && - (is_ri_TXOp(ue,proc,eNB_id)==1)); + (nr_is_ri_TXOp(ue,proc,eNB_id)==1)); // Part - II // if nothing to report ==> exit function @@ -2297,7 +2299,7 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ ue->tx_total_RE[nr_tti_tx] = 12; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - tx_amp = get_tx_amp(Po_PUCCH, + tx_amp = nr_get_tx_amp(Po_PUCCH, ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, 1); @@ -2306,7 +2308,7 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif #ifdef UE_DEBUG_TRACE @@ -2405,7 +2407,7 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ ue->tx_total_RE[nr_tti_tx] = 12; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - tx_amp = get_tx_amp(Po_PUCCH, + tx_amp = nr_get_tx_amp(Po_PUCCH, ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, 1); @@ -2414,7 +2416,7 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(nr_get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif #ifdef UE_DEBUG_TRACE LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", @@ -2785,7 +2787,7 @@ void nr_ue_pbch_procedures(uint8_t eNB_id, -unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) +unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) { int gain_dB = power_dBm - power_max_dBm; @@ -3039,7 +3041,7 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, */ LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n", - ue->Mod_id,frame_rx%1024,nr_tti_rx,mode_string[ue->UE_mode[eNB_id]], + ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[eNB_id]], dci_cnt, dci_alloc_rx[0].rnti, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti, @@ -3302,6 +3304,7 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, #endif +#if 0 void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t *current_harq_processes) { @@ -3338,6 +3341,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t harq_processes_dest->vrb_type = current_harq_processes->vrb_type ; } +#endif /*void copy_ack_struct(nr_harq_status_t *harq_ack_dest, nr_harq_status_t *current_harq_ack) { @@ -4535,7 +4539,7 @@ return (0); } -uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue, +uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { @@ -4557,7 +4561,7 @@ uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue, } -uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue, +uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c index 296d92969c..d388d6877b 100644 --- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c @@ -33,6 +33,7 @@ #include "SCHED_NR_UE/pucch_uci_ue_nr.h" #include "SCHED_NR_UE/pucch_power_control_ue_nr.h" #include +#include /**************** defines **************************************/ @@ -103,7 +104,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH; - int16_t PL = get_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ + int16_t PL = nr_get_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ int16_t delta_F_PUCCH = power_config->deltaF_PUCCH_f[pucch_format]; diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 21886418b0..512db60510 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -42,6 +42,7 @@ #ifndef NO_RAT_NR +#include "SCHED_NR_UE/defs.h" #include "SCHED_NR_UE/harq_nr.h" #include "SCHED_NR_UE/pucch_power_control_ue_nr.h" @@ -53,8 +54,8 @@ -uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); -uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); +uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); +uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); /* void nr_generate_pucch0(int32_t **txdataF, NR_DL_FRAME_PARMS *frame_parms, @@ -227,10 +228,10 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ &n_HARQ_ACK, reset_harq); // 1 to reset ACK/NACK status : 0 otherwise cqi_status = ((ue->cqi_report_config[gNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0) && - (is_cqi_TXOp(ue,proc,gNB_id) == 1)); + (nr_is_cqi_TXOp(ue,proc,gNB_id) == 1)); ri_status = ((ue->cqi_report_config[gNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && - (is_ri_TXOp(ue,proc,gNB_id) == 1)); + (nr_is_ri_TXOp(ue,proc,gNB_id) == 1)); csi_status = get_csi_nr(ue, gNB_id, &csi_payload); @@ -548,7 +549,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - tx_amp = get_tx_amp(pucch_tx_power, + tx_amp = nr_get_tx_amp(pucch_tx_power, ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL, nb_of_prbs); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 34a59e7000..1af9a630c6 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2208,7 +2208,7 @@ void nr_ue_process_mac_pdu( //--------------------------------------------------------------------------------- -unsigned char *parse_header(unsigned char *mac_header, +unsigned char *nr_parse_header(unsigned char *mac_header, unsigned char *num_ce, unsigned char *num_sdu, unsigned char *rx_ces, @@ -2336,7 +2336,7 @@ nr_ue_send_sdu(module_id_t module_idP, payload_ptr = - parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, + nr_parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_len); #ifdef DEBUG_HEADER_PARSING diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index c3d872d493..9c5c17e223 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -33,10 +33,13 @@ static nr_rlc_ue_manager_t *nr_rlc_ue_manager; /* TODO: handle time a bit more properly */ +#if 0 static uint64_t nr_rlc_current_time; static int nr_rlc_current_time_last_frame; static int nr_rlc_current_time_last_subframe; +#endif +#if 0 void mac_rlc_data_ind ( const module_id_t module_idP, const rnti_t rntiP, @@ -196,9 +199,11 @@ mac_rlc_status_resp_t mac_rlc_status_ind( ret.head_sdu_is_segmented = 0; return ret; } +#endif int oai_emulation; +#if 0 rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, @@ -250,7 +255,9 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } +#endif +#if 0 int rlc_module_init(int enb_flag) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; @@ -271,10 +278,13 @@ int rlc_module_init(int enb_flag) return 0; } +#endif +#if 0 void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP) { } +#endif static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) { @@ -745,6 +755,7 @@ static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) } } +#if 0 rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const LTE_SRB_ToAddModList_t * const srb2add_listP, const LTE_DRB_ToAddModList_t * const drb2add_listP, @@ -789,7 +800,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP return RLC_OP_STATUS_OK; } +#endif +#if 0 rlc_op_status_t rrc_rlc_config_req ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, @@ -848,12 +861,16 @@ rlc_op_status_t rrc_rlc_config_req ( nr_rlc_manager_unlock(nr_rlc_ue_manager); return RLC_OP_STATUS_OK; } +#endif +#if 0 void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP) { /* nothing to do */ } +#endif +#if 0 rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) { LOG_D(RLC, "%s:%d:%s: remove UE %d\n", __FILE__, __LINE__, __FUNCTION__, x->rnti); @@ -863,3 +880,4 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } +#endif From 2a92d27badc0791b9c51f2c6842a2c5f5f7c0044 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 15 Jan 2020 15:59:10 +0100 Subject: [PATCH 123/134] refix gNB build and eNB seg fault issue Signed-off-by: Raphael Defosseux --- cmake_targets/CMakeLists.txt | 2 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 2bff30d5e7..80587faa06 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2589,7 +2589,7 @@ target_link_libraries (nr-softmodem -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB - S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + S1AP_LIB S1AP_ENB L2 L2_LTE L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} -Wl,--end-group z dl) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 14368508f7..c9071806d2 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -872,7 +872,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, if (PLMN_identity_info == NULL) exit(1); - memset(&PLMN_identity_info,0,num_plmn * sizeof(LTE_PLMN_IdentityInfo_t)); + memset(PLMN_identity_info,0,num_plmn * sizeof(LTE_PLMN_IdentityInfo_t)); memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_t)); memset(&sib_type,0,sizeof(LTE_SIB_Type_t)); if(configuration->eMBMS_M2_configured){ From 4256251f24c210dada63fc90e09d58ac6cfb4952 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 15 Jan 2020 16:14:24 +0100 Subject: [PATCH 124/134] fix rrc asn file spare4 is not there in rrc 15.6. It leads to bad encoding. --- openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 index 02b8843c2b..91194c2ff5 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 +++ b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.6.0.asn1 @@ -126,7 +126,7 @@ DL-DCCH-MessageType ::= CHOICE { loggedMeasurementConfiguration-r10 LoggedMeasurementConfiguration-r10, rnReconfiguration-r10 RNReconfiguration-r10, rrcConnectionResume-r13 RRCConnectionResume-r13, - spare4 NULL, spare3 NULL, spare2 NULL, spare1 NULL + spare3 NULL, spare2 NULL, spare1 NULL }, messageClassExtension SEQUENCE {} } From f4f0fae00a9a6b8d0e02e8b6fcdf11b0b1e3a587 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 15 Jan 2020 17:18:15 +0100 Subject: [PATCH 125/134] Removing all spare4 references Signed-off-by: Raphael Defosseux --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 1 - openair2/RRC/LTE/L2_interface.c | 1 + openair2/RRC/LTE/rrc_UE.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index f93a6724a3..803551818a 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -509,7 +509,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, case LTE_DL_DCCH_MessageType__c1_PR_spare1: case LTE_DL_DCCH_MessageType__c1_PR_spare2: case LTE_DL_DCCH_MessageType__c1_PR_spare3: - case LTE_DL_DCCH_MessageType__c1_PR_spare4: break; case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: LOG_I(F1AP, "Received ueInformationRequest_r9\n"); diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 6e6eb0d1c9..356dd2e481 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -301,6 +301,7 @@ mac_rrc_data_ind( return (-1); } rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); + ue_context_p->ue_context.Status = RRC_RECONFIGURED; } } diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 4c0965b0ae..e2030e9da3 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -2165,7 +2165,6 @@ rrc_ue_decode_dcch( case LTE_DL_DCCH_MessageType__c1_PR_spare1: case LTE_DL_DCCH_MessageType__c1_PR_spare2: case LTE_DL_DCCH_MessageType__c1_PR_spare3: - case LTE_DL_DCCH_MessageType__c1_PR_spare4: break; default: From 90731a683a2df025d76ff297bcc052f1fba88d89 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 10 Jan 2020 18:14:47 +0100 Subject: [PATCH 126/134] minor modifications for rhel7.7 build --- cmake_targets/tools/build_helper | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 4af81a1a22..cdb7885945 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -103,6 +103,7 @@ check_supported_distribution() { "fedora24") return 0 ;; "rhel7") return 0 ;; "rhel7.6") return 0 ;; + "rhel7.7") return 0 ;; "centos7") return 0 ;; esac return 1 @@ -319,13 +320,13 @@ install_usrp_uhd_driver() { # quick workaround for RHE7.6 local distribution=$(get_distribution_release) if [ -z $1 ]; then - if [[ "$distribution" == "rhel7.6" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]]; then $SUDO /usr/local/bin/uhd_images_downloader else $SUDO uhd_images_downloader fi else - if [[ "$distribution" == "rhel7.6" ]]; then + if [[ "$OS_DISTRO" == "rhel" ]]; then $SUDO /usr/local/bin/uhd_images_downloader -i $1 else $SUDO uhd_images_downloader -i $1 From 7be64625cc88c47c7298fadeb6741a9bdca5d509 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 16 Jan 2020 09:58:34 +0100 Subject: [PATCH 127/134] CI: fix false negative report on 5G-NR RF simulator check Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index e087cc04e6..ff92460e35 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -460,10 +460,10 @@ function report_test { echo " $NAME_ENB --- $NAME_UE" >> ./test_simulator_results.html echo " N/A" >> ./test_simulator_results.html NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` - NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfuly configured" $ENB_LOG` + NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfully configured" $ENB_LOG` NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` NB_ENB_SYNCED_WITH_UE=`egrep -c "Initial sync: starting PBCH detection" $UE_LOG` - NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfuly configured" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG` if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] then echo " OK" >> ./test_simulator_results.html From c82fd2e444713e50fda0352f64cacbc855eb8c3a Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 16 Jan 2020 12:34:30 +0100 Subject: [PATCH 128/134] CI: fixing the check after UE mounted tunnel interfaces Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 32 +++++++++++++++++-- .../enb_ue_usrp210_band7_test_05mhz_tm1.xml | 4 +-- ...enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml | 4 +-- .../enb_usrp210_band13_test_10mhz_tm1.xml | 4 +-- openair2/LAYER2/MAC/ue_procedures.c | 6 ++-- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 2 +- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 62690ea8cb..1b106781f5 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -922,7 +922,8 @@ class SSHConnection(): if enbDidSync and eNBinNoS1: self.command('ifconfig oaitun_enb1', '\$', 4) - result = re.search('inet addr', str(self.ssh.before)) + self.command('ifconfig oaitun_enb1', '\$', 4) + result = re.search('inet addr:1|inet 1', str(self.ssh.before)) if result is not None: logging.debug('\u001B[1m oaitun_enb1 interface is mounted and configured\u001B[0m') else: @@ -1125,6 +1126,7 @@ class SSHConnection(): if fullSyncStatus and gotSyncStatus and self.air_interface == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: + self.command('ifconfig oaitun_ue1', '\$', 4) self.command('ifconfig oaitun_ue1', '\$', 4) # ifconfig output is different between ubuntu 16 and ubuntu 18 result = re.search('inet addr:1|inet 1', str(self.ssh.before)) @@ -3319,6 +3321,9 @@ class SSHConnection(): uciStatMsgCount = 0 pdcpDataReqFailedCount = 0 badDciCount = 0 + f1aRetransmissionCount = 0 + fatalErrorCount = 0 + macBsrTimerExpiredCount = 0 rrcConnectionRecfgComplete = 0 no_cell_sync_found = False mib_found = False @@ -3371,9 +3376,18 @@ class SSHConnection(): result = re.search('PDCP data request failed', str(line)) if result is not None and not exitSignalReceived: pdcpDataReqFailedCount += 1 - result = re.search('bad DCI 1A', str(line)) + result = re.search('bad DCI 1', str(line)) if result is not None and not exitSignalReceived: badDciCount += 1 + result = re.search('Format1A Retransmission but TBS are different', str(line)) + if result is not None and not exitSignalReceived: + f1aRetransmissionCount += 1 + result = re.search('FATAL ERROR', str(line)) + if result is not None and not exitSignalReceived: + fatalErrorCount += 1 + result = re.search('MAC BSR Triggered ReTxBSR Timer expiry', str(line)) + if result is not None and not exitSignalReceived: + macBsrTimerExpiredCount += 1 result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) if result is not None: rrcConnectionRecfgComplete += 1 @@ -3492,7 +3506,19 @@ class SSHConnection(): logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmlUEFailureMsg += statMsg + '\n' if badDciCount > 0: - statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)' + statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if f1aRetransmissionCount > 0: + statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if fatalErrorCount > 0: + statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if macBsrTimerExpiredCount > 0: + statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmlUEFailureMsg += statMsg + '\n' if self.eNBmbmsEnables[0]: diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml index 3eca883aa6..581858e44e 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -109,8 +109,8 @@ Iperf - iperf (5MHz - UL/8Mbps/UDP)(30 sec) - -c 10.0.1.1 -u -b 8M -t 30 -i 1 -fm -B 10.0.1.2 -R + iperf (5MHz - UL/4Mbps/UDP)(30 sec) + -c 10.0.1.1 -u -b 4M -t 30 -i 1 -fm -B 10.0.1.2 -R 50 balanced diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml index 9f7546cab3..2336f8e614 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml @@ -96,8 +96,8 @@ Iperf - iperf (5MHz - UL/8Mbps/UDP)(30 sec) - -u -b 8M -t 30 -i 1 -fm -R + iperf (5MHz - UL/4Mbps/UDP)(30 sec) + -u -b 4M -t 30 -i 1 -fm -R 50 balanced diff --git a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml index d72722aa8c..680f09c435 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml @@ -21,8 +21,8 @@ --> - test-10-tm1 - Test-10MHz-TM1 + test-lte-m-10-tm1 + Test-LTE-M-10MHz-TM1 tasks 2 diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index c340aa0b8f..d4277917eb 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2035,9 +2035,9 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, if (sdu_lengths[num_sdus]) { sdu_length_total += sdu_lengths[num_sdus]; sdu_lcids[num_sdus] = lcid; - LOG_I(MAC, - "[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n", - module_idP, sdu_lengths[num_sdus], lcid); + //LOG_I(MAC, + // "[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n", + // module_idP, sdu_lengths[num_sdus], lcid); if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index f198a98b23..68f8ab5f13 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -138,7 +138,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { else { ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); - LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); + //LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); } } else if (ENB_NAS_USE_TUN) { ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); From a25c06edf7a38bba0a9126b0b24c5b311af76df1 Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Javier Morgade" Date: Thu, 16 Jan 2020 23:15:13 +0100 Subject: [PATCH 129/134] BUGFIX feptx0 - New slot numbering approach was missing for PMCH case --- openair1/SCHED/ru_procedures.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 8e95f89250..6d392b0437 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -92,12 +92,12 @@ void feptx0(RU_t *ru, CYCLIC_PREFIX); } else { if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){ - if (slot == 0) {//just use one slot chance - normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], + if ((slot&1) == 0) {//just use one slot chance + normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF], (int*)&ru->common.txdata[aa][slot_offset], 2, fp); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF+fp->ofdm_symbol_size*2], + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF+fp->ofdm_symbol_size*2], (int*)&ru->common.txdata[aa][slot_offset+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2)], fp->ofdm_symbol_size, 10, From f2d90e79e392d33c71bf42f5de4708268279beb4 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 17 Jan 2020 21:39:34 +0100 Subject: [PATCH 130/134] CI: fix the git clone extension when creating the UE workspace Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 1b106781f5..e4618919ee 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -552,9 +552,14 @@ class SSHConnection(): else: self.air_interface = 'lte' ue_prefix = '' + result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) + if result is not None: + full_ran_repo_name = self.ranRepository + else: + full_ran_repo_name = self.ranRepository + '.git' self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) From c383b5e696b0dce9fd3b4f8fad5ba2b02ca0b27a Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 14 Jan 2020 13:27:34 +0100 Subject: [PATCH 131/134] CI: prepare release notes for release 1.2.0 Signed-off-by: Raphael Defosseux --- README.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.txt b/README.txt index db3ee53045..37bb115ade 100644 --- a/README.txt +++ b/README.txt @@ -43,6 +43,16 @@ openairinterface5g RELEASE NOTES: +v1.2.0 -> January 2020. This version adds the following implemented features: + * LTE-M : eNB support for Mode A repetitions + - PUSCH CE - 8 Repetitions + * Improved CDRX implementation for monolithic eNB + * Experimental eMBMS support (now also on eNB side) + * Bug fixes + This version also has an improved code quality: + * Better Test Coverage in Continuous Integration: + - Initial framework to do long-run testing at R2LAB + v1.1.1 -> November 2019. Bug fix in the TDD Fair Round-Robin scheduler v1.1.0 -> July 2019. This version adds the following implemented features: * Experimental support of LTE-M From 0ec5db48d3076a109d3964f43d99cead43126a4f Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Javier Morgade" Date: Tue, 14 Jan 2020 13:55:05 +0100 Subject: [PATCH 132/134] Update README.txt with MBMS features --- README.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 37bb115ade..579b084601 100644 --- a/README.txt +++ b/README.txt @@ -17,7 +17,7 @@ openairinterface5g ├── maketags : Script to generate emacs tags ├── nfapi : Contains the NFAPI code. A local Readme file provides more details. ├── openair1 : 3GPP LTE Rel-10/12 PHY layer + PHY RF simulation. A local Readme file provides more details. -├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation. +├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP + LTE Rel-14 M2AP implementation. ├── COMMON ├── DOCS ├── ENB_APP @@ -28,12 +28,15 @@ openairinterface5g ├── RRC/LITE ├── UTIL ├── X2AP + ├── M2AP + ├── MCE_APP ├── openair3: 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE. ├── COMMON ├── DOCS ├── GTPV1-U ├── NAS ├── S1AP + ├── M3AP ├── SCTP ├── SECU ├── UDP @@ -48,6 +51,7 @@ v1.2.0 -> January 2020. This version adds the following implemented features: - PUSCH CE - 8 Repetitions * Improved CDRX implementation for monolithic eNB * Experimental eMBMS support (now also on eNB side) + * Experimental MCE - Multicast Coordination Entity * Bug fixes This version also has an improved code quality: * Better Test Coverage in Continuous Integration: From 954c9d417347587b7d9e337bf45fbdf82b6234f0 Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Javier Morgade" Date: Tue, 14 Jan 2020 14:05:15 +0100 Subject: [PATCH 133/134] Update FEATURE_SET.md with MBMS features --- doc/FEATURE_SET.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index e9355e51d2..f63719f41f 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -148,6 +148,24 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following - Handover Cancel - X2-U interface implemented +## eNB/MCE M2AP ## +The M2AP layer is based on **3GPP 36.443** v14.0.1: + - M2 Setup Request + - M2 Setup Response + - M2 Setup Failure + - M2 Scheduling Information + - M2 Scheduling Information Response + - M2 Session Start Request + - M2 Session Start Response + +## MCE/MME M3AP ## +The M3AP layer is based on **3GPP 36.444** v14.0.1: + - M3 Setup Request + - M3 Setup Response + - M3 Setup Failure + - M3 Session Start Request + - M3 Session Start Response + ## eNB Advanced Features ## **To be completed** From 979fa3a659d24915c6b6149aa4b34d16db3f1692 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 15 Jan 2020 16:07:25 +0100 Subject: [PATCH 134/134] DOC: added hyper links to new sections Signed-off-by: Raphael Defosseux --- doc/FEATURE_SET.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index f63719f41f..f71b9acb33 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -7,15 +7,18 @@ 4. [eNB PDCP Layer](#enb-pdcp-layer) 5. [eNB RRC Layer](#enb-rrc-layer) 6. [eNB X2AP](#enb-x2ap) - 7. [eNB Advanced Features](#enb-advanced-features) -2. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set) + 7. [eNB/MCE M2AP](#enbmce-m2ap) + 8. [MCE/MME M3AP](#mcemme-m3ap) + 9. [eNB Advanced Features](#enb-advanced-features) +2. [OpenAirInterface Functional Split](#openairinterface-functional-split) +3. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set) 1. [LTE UE PHY Layer](#lte-ue-phy-layer) 2. [LTE UE MAC Layer](#lte-ue-mac-layer) 3. [LTE UE RLC Layer](#lte-ue-rlc-layer) 4. [LTE UE PDCP Layer](#lte-ue-pdcp-layer) 5. [LTE UE RRC Layer](#lte-ue-rrc-layer) -3. [OpenAirInterface Functional Split](#openairinterface-functional-split) -4. [OpenAirInterface 5G-NR Feature Set](#openairinterface-5g-nr-feature-set) +4. [OpenAirInterface Functional Split](#openairinterface-functional-split) +5. [OpenAirInterface 5G-NR Feature Set](#openairinterface-5g-nr-feature-set) 1. [General Parameters](#general-parameters) 2. [gNB Features](#gnb-features) 1. [gNB Physical Layer](#gnb-phy-layer) @@ -149,6 +152,7 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following - X2-U interface implemented ## eNB/MCE M2AP ## + The M2AP layer is based on **3GPP 36.443** v14.0.1: - M2 Setup Request - M2 Setup Response @@ -159,6 +163,7 @@ The M2AP layer is based on **3GPP 36.443** v14.0.1: - M2 Session Start Response ## MCE/MME M3AP ## + The M3AP layer is based on **3GPP 36.444** v14.0.1: - M3 Setup Request - M3 Setup Response @@ -301,4 +306,4 @@ For more details see [this document](https://gitlab.eurecom.fr/oai/openairinterf [OAI softmodem build procedure](BUILD.md) -[Running the OAI softmodem ](RUNMODEM.md) \ No newline at end of file +[Running the OAI softmodem ](RUNMODEM.md)