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/343] 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/343] 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/343] 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/343] 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 2a35715c9ebe45571eb63e9660b783bb038119cb Mon Sep 17 00:00:00 2001 From: "javier.morgade@ieee.org" Date: Sun, 8 Sep 2019 21:53:13 +0200 Subject: [PATCH 005/343] 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 006/343] 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 007/343] 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 008/343] 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 009/343] 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 010/343] 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 011/343] 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 012/343] 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 013/343] 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 014/343] *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 015/343] 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 016/343] -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 017/343] 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 018/343] 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 019/343] 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 020/343] 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 021/343] -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 022/343] 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 023/343] 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 024/343] 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 025/343] 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 026/343] 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 027/343] 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 028/343] 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 029/343] 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 030/343] 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 031/343] 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 032/343] 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 033/343] 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 034/343] 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 035/343] 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 036/343] 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 6f12c99131d43462a35b3d04c7fb32d96daf8242 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 19 Sep 2019 15:44:24 +0200 Subject: [PATCH 037/343] minor: change output directory's name for NR RRC it was 'NR_Rel15' and now it is 'RRC_NR_Rel15' --- cmake_targets/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index bd16f3efba..ec3f9f9ee8 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -346,7 +346,7 @@ if (${NR_RRC_ASN1_VERSION} STREQUAL "NR_Rel15") set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-15.6.0.asn1) endif (${NR_RRC_ASN1_VERSION} STREQUAL "NR_Rel15") add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION}) -set (NR_RRC_FULL_DIR ${asn1_generated_dir}/${NR_RRC_ASN1_VERSION}) +set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION}) # 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 "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice" From ff379fe08caccbbbff7168b46bcd3d4b14b93ca7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 20 Sep 2019 17:29:54 +0200 Subject: [PATCH 038/343] get NR UE capabilities (hardcoded bands) --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 2f09aafe8d..1fbc2adc29 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3701,6 +3701,8 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, { LTE_DL_DCCH_Message_t dl_dcch_msg; LTE_RAT_Type_t rat=LTE_RAT_Type_eutra; + LTE_RAT_Type_t rat_nr=LTE_RAT_Type_nr; + LTE_RAT_Type_t rat_eutra_nr=LTE_RAT_Type_eutra_nr; asn_enc_rval_t enc_rval; memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; @@ -3712,6 +3714,38 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0; ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); + ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, + &rat_nr); + ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, + &rat_eutra_nr); + + /* request NR configuration */ + LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8; + LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0; + LTE_UECapabilityEnquiry_v1180_IEs_t r11_80; + LTE_UECapabilityEnquiry_v1310_IEs_t r13_10; + LTE_UECapabilityEnquiry_v1430_IEs_t r14_30; + LTE_UECapabilityEnquiry_v1510_IEs_t r15_10; + + memset(&r8_a0, 0, sizeof(r8_a0)); + memset(&r11_80, 0, sizeof(r11_80)); + memset(&r13_10, 0, sizeof(r13_10)); + memset(&r14_30, 0, sizeof(r14_30)); + memset(&r15_10, 0, sizeof(r15_10)); + + r8->nonCriticalExtension = &r8_a0; + r8_a0.nonCriticalExtension = &r11_80; + r11_80.nonCriticalExtension = &r13_10; + r13_10.nonCriticalExtension = &r14_30; + r14_30.nonCriticalExtension = &r15_10; + + OCTET_STRING_t req_freq; + unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; + + req_freq.buf = req_freq_buf; + req_freq.size = 5; + + r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); From ddc336e2d8ba2d38f0f665cc5328a8bb5305515e Mon Sep 17 00:00:00 2001 From: Stefan Schaffelder Date: Tue, 3 Sep 2019 14:17:58 +0200 Subject: [PATCH 039/343] 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/343] 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/343] 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/343] 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/343] 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/343] [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 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 045/343] [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 dd760540ea101f5b090ce4e9d9ff04517c91c5fd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 3 Oct 2019 15:14:26 +0200 Subject: [PATCH 046/343] hacks for NR - send RRC Connection Reconfiguration with dummy ENDC data by doing: telnet localhost 9001 and press enter when the ENDC UE is connected to the eNB to send it --- cmake_targets/CMakeLists.txt | 1 + openair2/RRC/LTE/rrc_eNB.c | 9 + openair2/RRC/LTE/rrc_eNB_endc.c | 353 ++++++++++++++++++++++++++++++++ 3 files changed, 363 insertions(+) create mode 100644 openair2/RRC/LTE/rrc_eNB_endc.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index ec3f9f9ee8..931b009fef 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1568,6 +1568,7 @@ set(L2_SRC ${RLC_DIR}/rlc_mpls.c # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c + ${RRC_DIR}/rrc_eNB_endc.c ${RRC_DIR}/rrc_eNB_S1AP.c ${RRC_DIR}/rrc_eNB_UE_context.c ${RRC_DIR}/rrc_common.c diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 2c4dea77af..0050118c13 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -9121,11 +9121,20 @@ rrc_enb_task( //----------------------------------------------------------------------------- { rrc_enb_init(); + +void rrc_endc_hack_init(void); +rrc_endc_hack_init(); + itti_mark_task_ready(TASK_RRC_ENB); LOG_I(RRC,"Entering main loop of RRC message task\n"); while (1) { (void) rrc_enb_process_itti_msg(NULL); +{ + extern volatile int go_nr; + void rrc_go_nr(void); + if (go_nr) rrc_go_nr(); +} } } diff --git a/openair2/RRC/LTE/rrc_eNB_endc.c b/openair2/RRC/LTE/rrc_eNB_endc.c new file mode 100644 index 0000000000..aa2b3e76cf --- /dev/null +++ b/openair2/RRC/LTE/rrc_eNB_endc.c @@ -0,0 +1,353 @@ +/* + * 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 "rrc_defs.h" +#include "rrc_extern.h" +#include "rrc_eNB_UE_context.h" +#include "common/ran_context.h" +#include "LTE_DL-DCCH-Message.h" + +#include +#include +#include +#include +#include +#include + +extern RAN_CONTEXT_t RC; +extern mui_t rrc_eNB_mui; + +int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, + rrc_eNB_ue_context_t *ue_context, + unsigned char *buffer, + int buffer_size) +{ + asn_enc_rval_t enc_rval; + LTE_DL_DCCH_Message_t dl_dcch_msg; + LTE_RRCConnectionReconfiguration_t *r; + int trans_id; + LTE_RadioResourceConfigDedicated_t rrcd; + LTE_DRB_ToAddModList_t drb_list; + struct LTE_DRB_ToAddMod drb; + long eps_bearer_id; + struct LTE_RLC_Config rlc; + long lcid; + struct LTE_LogicalChannelConfig lc; + struct LTE_LogicalChannelConfig__ul_SpecificParameters ul_params; + long lcg; + struct LTE_RadioResourceConfigDedicated__mac_MainConfig mac; + struct LTE_MAC_MainConfig__ext4 mac_ext4; + struct LTE_MAC_MainConfig__ext4__dualConnectivityPHR dc_phr; + + memset(&rrcd, 0, sizeof(rrcd)); + memset(&drb_list, 0, sizeof(drb_list)); + memset(&drb, 0, sizeof(drb)); + memset(&rlc, 0, sizeof(rlc)); + memset(&lc, 0, sizeof(lc)); + memset(&ul_params, 0, sizeof(ul_params)); + memset(&mac, 0, sizeof(mac)); + memset(&mac_ext4, 0, sizeof(mac_ext4)); + memset(&dc_phr, 0, sizeof(dc_phr)); + + trans_id = rrc_eNB_get_next_transaction_identifier(ctxt->module_id); + + memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); + + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; + + r = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration; + + r->rrc_TransactionIdentifier = trans_id; + r->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1; + r->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8; + r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated = &rrcd; + + rrcd.drb_ToAddModList = &drb_list; + + eps_bearer_id = 5; + drb.eps_BearerIdentity = &eps_bearer_id; + drb.drb_Identity = 5; + drb.rlc_Config = &rlc; + lcid = 4; + drb.logicalChannelIdentity = &lcid; + drb.logicalChannelConfig = &lc; + + rlc.present = LTE_RLC_Config_PR_am; + rlc.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + rlc.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + rlc.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + rlc.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + rlc.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + rlc.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; + + lc.ul_SpecificParameters = &ul_params; + + ul_params.priority = 12; + ul_params.prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; + ul_params.bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300; + lcg = 3; + ul_params.logicalChannelGroup = &lcg; + + rrcd.mac_MainConfig = &mac; + + mac.present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; + mac.choice.explicitValue.timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_sf10240; + mac.choice.explicitValue.ext4 = &mac_ext4; + + mac_ext4.dualConnectivityPHR = &dc_phr; + + dc_phr.present = LTE_MAC_MainConfig__ext4__dualConnectivityPHR_PR_setup; + dc_phr.choice.setup.phr_ModeOtherCG_r12 = LTE_MAC_MainConfig__ext4__dualConnectivityPHR__setup__phr_ModeOtherCG_r12_virtual; + + /* NR config */ + struct LTE_RRCConnectionReconfiguration_v890_IEs cr_890; + struct LTE_RRCConnectionReconfiguration_v920_IEs cr_920; + struct LTE_RRCConnectionReconfiguration_v1020_IEs cr_1020; + struct LTE_RRCConnectionReconfiguration_v1130_IEs cr_1130; + struct LTE_RRCConnectionReconfiguration_v1250_IEs cr_1250; + struct LTE_RRCConnectionReconfiguration_v1310_IEs cr_1310; + struct LTE_RRCConnectionReconfiguration_v1430_IEs cr_1430; + struct LTE_RRCConnectionReconfiguration_v1510_IEs cr_1510; + struct LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15 nr; + + memset(&cr_890, 0, sizeof(cr_890)); + memset(&cr_920, 0, sizeof(cr_920)); + memset(&cr_1020, 0, sizeof(cr_1020)); + memset(&cr_1130, 0, sizeof(cr_1130)); + memset(&cr_1250, 0, sizeof(cr_1250)); + memset(&cr_1310, 0, sizeof(cr_1310)); + memset(&cr_1430, 0, sizeof(cr_1430)); + memset(&cr_1510, 0, sizeof(cr_1510)); + memset(&nr, 0, sizeof(nr)); + + r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = &cr_890; + cr_890.nonCriticalExtension = &cr_920; + cr_920.nonCriticalExtension = &cr_1020; + cr_1020.nonCriticalExtension = &cr_1130; + cr_1130.nonCriticalExtension = &cr_1250; + cr_1250.nonCriticalExtension = &cr_1310; + cr_1310.nonCriticalExtension = &cr_1430; + cr_1430.nonCriticalExtension = &cr_1510; + + cr_1510.nr_Config_r15 = &nr; + nr.present = LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15_PR_setup; + nr.choice.setup.endc_ReleaseAndAdd_r15 = 0; /* FALSE */ + + OCTET_STRING_t scg_conf; + unsigned char scg_conf_buf[4] = { 0, 0, 0, 0 }; + nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = &scg_conf; + scg_conf.buf = scg_conf_buf; + scg_conf.size = 4; + + long sk_counter = 0; + cr_1510.sk_Counter_r15 = &sk_counter; + + OCTET_STRING_t nr1_conf; + unsigned char nr1_buf[4] = { 0, 0, 0, 0 }; + cr_1510.nr_RadioBearerConfig1_r15 = &nr1_conf; + nr1_conf.buf = nr1_buf; + nr1_conf.size = 4; + + OCTET_STRING_t nr2_conf; + unsigned char nr2_buf[4] = { 0, 0, 0, 0 }; + cr_1510.nr_RadioBearerConfig2_r15 = &nr2_conf; + nr2_conf.buf = nr2_buf; + nr2_conf.size = 4; + + ASN_SEQUENCE_ADD(&drb_list.list, &drb); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + buffer, + buffer_size); + +{ +int len = (enc_rval.encoded + 7) / 8; +int i; +printf("len = %d\n", len); +for (i = 0; i < len; i++) printf(" %2.2x", buffer[i]); +printf("\n"); +} + + return (enc_rval.encoded + 7) / 8; +} + +volatile int go_nr; + +struct rrc_eNB_ue_context_s * +get_first_ue_context(eNB_RRC_INST *rrc_instance_pP) +{ + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { + return ue_context_p; + } + return NULL; +} + +void rrc_go_nr(void) +{ + protocol_ctxt_t ctxt; + rrc_eNB_ue_context_t *ue_context; + unsigned char buffer[8192]; + int size; + + go_nr = 0; + + ue_context = get_first_ue_context(RC.rrc[0]); + + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + 0, + ENB_FLAG_YES, + ue_context->ue_context.rnti, + 0, 0); + + size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192); + + rrc_data_req(&ctxt, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +} + +static void new_thread(void *(*f)(void *), void *data) { + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)) { + fprintf(stderr, "pthread_attr_init err\n"); + exit(1); + } + + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { + fprintf(stderr, "pthread_attr_setdetachstate err\n"); + exit(1); + } + + if (pthread_attr_setstacksize(&att, 10000000)) { + fprintf(stderr, "pthread_attr_setstacksize err\n"); + exit(1); + } + + if (pthread_create(&t, &att, f, data)) { + fprintf(stderr, "pthread_create err\n"); + exit(1); + } + + if (pthread_attr_destroy(&att)) { + fprintf(stderr, "pthread_attr_destroy err\n"); + exit(1); + } +} + +static int create_listen_socket(char *addr, int port) { + struct sockaddr_in a; + int s; + int v; + s = socket(AF_INET, SOCK_STREAM, 0); + + if (s == -1) { + perror("socket"); + exit(1); + } + + v = 1; + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int))) { + perror("setsockopt"); + exit(1); + } + + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = inet_addr(addr); + + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { + perror("bind"); + exit(1); + } + + if (listen(s, 5)) { + perror("listen"); + exit(1); + } + + return s; +} + +static int socket_accept(int s) { + struct sockaddr_in a; + socklen_t alen; + alen = sizeof(a); + return accept(s, (struct sockaddr *)&a, &alen); +} + +static 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 *nr_hack(void *_) +{ + int s = create_listen_socket("0.0.0.0", 9001); + int t; + +over: + t = socket_accept(s); + + while (1) { + char c; + + if (fullread(t, &c, 1) != 1) { + close(t); + goto over; + } + + if (c != '\n') continue; + + printf("setting go_nr to 1\n"); + go_nr = 1; + } + + return 0; +} + +void rrc_endc_hack_init(void) +{ + new_thread(nr_hack, NULL); +} From 2e8b93ef8b825cd4ce09576db71fc966638bdbb8 Mon Sep 17 00:00:00 2001 From: matzakos Date: Thu, 3 Oct 2019 18:11:58 +0200 Subject: [PATCH 047/343] ENDC: Reverse the role of eNB and gNB for the ENDC X2 setup procedure. Currently, gNB: slave sending the setup request, eNB:master. --- openair2/COMMON/s1ap_messages_types.h | 3 +- openair2/ENB_APP/enb_config.c | 12 +- openair2/X2AP/x2ap_eNB.c | 10 +- openair2/X2AP/x2ap_eNB_generate_messages.c | 339 ++++++++++----------- openair2/X2AP/x2ap_eNB_generate_messages.h | 4 +- openair2/X2AP/x2ap_eNB_handler.c | 309 ++++++++++--------- 6 files changed, 331 insertions(+), 346 deletions(-) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index 2615494d3b..bfceddb936 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -81,7 +81,8 @@ #ifndef OCP_FRAMEWORK typedef enum cell_type_e { CELL_MACRO_ENB, - CELL_HOME_ENB + CELL_HOME_ENB, + CELL_MACRO_GNB } cell_type_t; typedef enum paging_drx_e { diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 6174632fd6..2a66166762 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2126,6 +2126,11 @@ int RCconfig_S1( S1AP_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) { S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; + // Temporary option to be able to parse an eNB configuration file which is treated as gNB from + // the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to + // parse an actual gNB configuration file wrt. the X2AP parameters instead. + } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB; } 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", @@ -2355,7 +2360,12 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { X2AP_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) { X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; - } else { + // Temporary option to be able to parse an eNB configuration file which is treated as gNB from + // the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to + // parse an actual gNB configuration file wrt. the X2AP parameters instead. + } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB; + }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)); diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index b7ccb07461..c8f35d6d13 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -101,7 +101,6 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_enb_data_p; DevAssert(sctp_new_association_resp != NULL); - printf("x2ap_eNB_handle_sctp_association_resp at 1\n"); dump_trees(); instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -129,7 +128,6 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa x2ap_enb_data_p = x2ap_get_eNB(instance_p, -1, sctp_new_association_resp->ulp_cnx_id); DevAssert(x2ap_enb_data_p != NULL); - printf("x2ap_eNB_handle_sctp_association_resp at 2\n"); dump_trees(); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { @@ -142,17 +140,17 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa return; } - printf("x2ap_eNB_handle_sctp_association_resp at 3\n"); dump_trees(); /* Update parameters */ x2ap_enb_data_p->assoc_id = sctp_new_association_resp->assoc_id; x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; x2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams; - printf("x2ap_eNB_handle_sctp_association_resp at 4\n"); dump_trees(); /* Prepare new x2 Setup Request */ - x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p); - //x2ap_eNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p); + if(instance_p->cell_type == CELL_MACRO_GNB) + x2ap_gNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p); + else + x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p); } static diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index e43db6aa8a..201ac0a03c 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -39,6 +39,7 @@ #include "x2ap_ids.h" #include "x2ap_eNB_itti_messaging.h" +#include "X2AP_SupportedSULFreqBandItem.h" #include "msc.h" #include "assertions.h" @@ -1230,17 +1231,17 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p return ret; } -/*setup request message from an eNB to a gNB*/ -int x2ap_eNB_generate_ENDC_x2_setup_request( +/*setup request message from a gNB to an eNB*/ +int x2ap_gNB_generate_ENDC_x2_setup_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) { - printf("In x2ap_eNB_generate_ENDC_x2_setup_request \n"); X2AP_X2AP_PDU_t pdu; X2AP_ENDCX2SetupRequest_t *out; X2AP_ENDCX2SetupRequest_IEs_t *ie; - X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC; + X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC; X2AP_PLMN_Identity_t *plmn; - ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember; + ServedNRcellsENDCX2ManagementList__Member *servedCellMember; + X2AP_SupportedSULFreqBandItem_t *SULFreqBandItem; uint8_t *buffer; uint32_t len; @@ -1262,24 +1263,166 @@ int x2ap_eNB_generate_ENDC_x2_setup_request( ie = (X2AP_ENDCX2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupRequest_IEs_t)); ie->id = X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup; ie->value.present = X2AP_ENDCX2SetupRequest_IEs__value_PR_InitiatingNodeType_EndcX2Setup; - ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_eNB; + ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_en_gNB; - ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t)); + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqIEs_t)); + ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_Globalen_gNB_ID; + ie_GNB_ENDC->criticality = X2AP_Criticality_reject; + ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_GlobalGNB_ID; + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.present = X2AP_GNB_ID_PR_gNB_ID; + INT32_TO_OCTET_STRING(instance_p->eNB_id, + &ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID); + +X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[0], + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[1], + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]); + +MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity); + + ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC); + + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqIEs_t)); + ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList; + ie_GNB_ENDC->criticality = X2AP_Criticality_reject; + ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqIEs__value_PR_ServedNRcellsENDCX2ManagementList; + + { + for (int i = 0; inum_cc; i++){ + servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member)); + { + servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i]; + + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id, + &servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier); + servedCellMember->servedNRCellInfo.fiveGS_TAC = calloc(1, sizeof(X2AP_FiveGS_TAC_t)); + if (servedCellMember->servedNRCellInfo.fiveGS_TAC == NULL) + exit(1); + NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC); + + X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac, + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); + + plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); + { + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn); + } + + if (instance_p->frame_type[i] == FDD) { // Panos: Remember to change that to TDD + X2AP_FreqBandNrItem_t *freq_band; + servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i]; + /* addition of Frequency Band List */ + freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t)); + if (freq_band == NULL) + exit(1); + freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */ + + SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t)); + SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */ + ASN_SEQUENCE_ADD(&freq_band->supportedSULBandList.list, SULFreqBandItem); + + ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band); + switch (instance_p->N_RB_DL[i]) { + case 50: + //This is not correct. Just to be able to test X2 only using an eNB instead of gNB + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51; + break; + case 93 : + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93; + break; + case 106: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106; + break; + case 121: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121; + break; + /*More cases to be added */ + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } + } + else { + AssertFatal(0,"ENDC_X2Setuprequest not supported for FDD!"); + } + /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */ + INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); + } + ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC); + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 setup request\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int x2ap_eNB_generate_ENDC_x2_setup_response( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_ENDCX2SetupResponse_t *out; + X2AP_ENDCX2SetupResponse_IEs_t *ie; + X2AP_ENB_ENDCX2SetupReqAckIEs_t *ie_ENB_ENDC; + X2AP_PLMN_Identity_t *plmn; + ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.ENDCX2SetupResponse; + + ie = (X2AP_ENDCX2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupResponse_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup; + ie->value.present = X2AP_ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup; + ie->value.choice.RespondingNodeType_EndcX2Setup.present = X2AP_RespondingNodeType_EndcX2Setup_PR_respond_eNB; + + ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqAckIEs_t)); ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID; ie_ENB_ENDC->criticality = X2AP_Criticality_reject; - ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_GlobalENB_ID; + ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqAckIEs__value_PR_GlobalENB_ID; ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present = X2AP_ENB_ID_PR_macro_eNB_ID; MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, &ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, &ie_ENB_ENDC->value.choice.GlobalENB_ID.pLMN_Identity); - ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC); + ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC); - ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t)); + ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqAckIEs_t)); ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList; ie_ENB_ENDC->criticality = X2AP_Criticality_reject; - ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList; + ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqAckIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList; { for (int i = 0; inum_cc; i++){ @@ -1299,11 +1442,11 @@ int x2ap_eNB_generate_ENDC_x2_setup_request( ASN_SEQUENCE_ADD(&servedCellMember->servedEUTRACellInfo.broadcastPLMNs.list, plmn); } - if (instance_p->frame_type[i] == FDD) { - servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD; + if (instance_p->frame_type[i] == FDD) { + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD; servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; - switch (instance_p->N_RB_DL[i]) { + switch (instance_p->N_RB_DL[i]) { case 6: servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; @@ -1334,177 +1477,13 @@ int x2ap_eNB_generate_ENDC_x2_setup_request( } } else { - AssertFatal(0,"X2Setuprequest not supported for TDD!"); + AssertFatal(0,"X2Setupresponse not supported for TDD!"); } } ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember); } } - ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC); - - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { - X2AP_ERROR("Failed to encode ENDC X2 setup request\n"); - return -1; - } - - MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); - - x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); - - return ret; -} - - -/*setup request message from an eNB to a gNB*/ -int x2ap_gNB_generate_ENDC_x2_setup_response( - x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) -{ - X2AP_INFO("In x2ap_gNB_generate_ENDC_x2_setup_response ()!\n"); - X2AP_X2AP_PDU_t pdu; - X2AP_ENDCX2SetupResponse_t *out; - X2AP_ENDCX2SetupResponse_IEs_t *ie; - X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *ie_GNB_ENDC; - X2AP_PLMN_Identity_t *plmn; - ServedNRcellsENDCX2ManagementList__Member *servedCellMember; - - uint8_t *buffer; - uint32_t len; - int ret = 0; - - DevAssert(instance_p != NULL); - DevAssert(x2ap_eNB_data_p != NULL); - - x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; - - /* Prepare the X2AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup; - pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse; - out = &pdu.choice.successfulOutcome.value.choice.ENDCX2SetupResponse; - - ie = (X2AP_ENDCX2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupResponse_IEs_t)); - ie->id = X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup; - ie->value.present = X2AP_ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup; - ie->value.choice.RespondingNodeType_EndcX2Setup.present = X2AP_RespondingNodeType_EndcX2Setup_PR_respond_en_gNB; - - ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t)); - ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_Globalen_gNB_ID; - ie_GNB_ENDC->criticality = X2AP_Criticality_reject; - ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_GlobalGNB_ID; - ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.present = X2AP_GNB_ID_PR_gNB_ID; - - INT32_TO_OCTET_STRING(instance_p->eNB_id, - &ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID); - - X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, - ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[0], - ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[1], - ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]); - - MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - &ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity); - - ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC); - - ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t)); - ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList; - ie_GNB_ENDC->criticality = X2AP_Criticality_reject; - ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_ServedNRcellsENDCX2ManagementList; - - { - for (int i = 0; inum_cc; i++){ - servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member)); - { - servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i]; - - MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, - &servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity); - NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id, - &servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier); - servedCellMember->servedNRCellInfo.fiveGS_TAC = calloc(1, sizeof(X2AP_FiveGS_TAC_t)); - if (servedCellMember->servedNRCellInfo.fiveGS_TAC == NULL) - exit(1); - NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC); - - X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac, - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); - - plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); - { - MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); - ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn); - } - - if (instance_p->frame_type[i] == TDD) { // Panos: Remember to change that to TDD - X2AP_FreqBandNrItem_t *freq_band; - servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i]; - - /* addition of Frequency Band List */ - freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t)); - if (freq_band == NULL) - exit(1); - freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */ - ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band); - - switch (instance_p->N_RB_DL[i]) { - case 50: - //This is not correct. Just to be able to test X2 only using an eNB instead of gNB - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51; - break; - case 93 : - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93; - break; - case 106: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106; - break; - case 121: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121; - break; - - /*More cases to be added */ - - default: - AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); - break; - } - - instance_p->nr_SCS[i] = 30; // Hardcoded for now. Normally this should originate from the gNB config file - switch (instance_p->nr_SCS[i]) { - case 15: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs15; - break; - case 30: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs30; - break; - case 60: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs60; - break; - case 120: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs120; - break; - default: - AssertFatal(0,"Failed: Check value for nr_SCS"); - break; - } - } - else { - AssertFatal(0,"nr_X2Setupresponse not supported for FDD!"); - } - /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */ - INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); - } - ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember); - } - } - ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC); + ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 6b0cd9c2da..4abda36e5a 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -66,8 +66,8 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2 int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack); -int x2ap_eNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); +int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); -int x2ap_gNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); +int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index bde7bd59d9..dabbe0e8a6 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -103,7 +103,7 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); -int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, +int x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu); @@ -153,7 +153,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, - { x2ap_gNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, + { x2ap_eNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } @@ -1324,7 +1324,7 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, } int -x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, +x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu) @@ -1332,12 +1332,12 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, X2AP_ENDCX2SetupRequest_t *x2_ENDC_SetupRequest; X2AP_ENDCX2SetupRequest_IEs_t *ie; - X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC; - ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember; + X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC; + ServedNRcellsENDCX2ManagementList__Member *servedCellMember; x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; - uint32_t eNB_id = 0; + uint32_t gNB_id = 0; x2ap_eNB_data = NULL; DevAssert (pdu != NULL); @@ -1372,156 +1372,11 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; } else { - if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count > 0) { - //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest - //message or the ie to which there are more nested information elements? - for (int i=0; ivalue.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count;i++) { + if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count > 0) { - ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i]; - if (ie_ENB_ENDC == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } + for (int i=0; ivalue.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) { - else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_GlobalENB_ID) { - if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) { - // Home eNB ID = 28 bits - uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf; - if (ie_ENB_ENDC->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); - X2AP_DEBUG("Home eNB id: %07x\n", eNB_id); - } else { - // Macro eNB = 20 bits - uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; - if (ie_ENB_ENDC->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); - X2AP_DEBUG("macro eNB id: %05x\n", eNB_id); - } - X2AP_DEBUG("Adding eNB to the list of associated eNBs\n"); - if ((x2ap_eNB_data = x2ap_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 ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { - /* - * ?? - */ - return -1; - } else { - x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; - x2ap_eNB_data->eNB_id = eNB_id; - } - } else { - x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; - - /* - * eNB has been found in list, consider the x2 setup request as a reset connection, - * * * * reseting any previous UE state if sctp association is != than the previous one - */ - if (x2ap_eNB_data->assoc_id != assoc_id) { - /* - * ??: Send an overload cause... - */ - X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id); - - // Panos: Here we should be calling an ENDC specific setup_failure function instead - x2ap_eNB_generate_x2_setup_failure (instance, - assoc_id, - X2AP_Cause_PR_protocol, - X2AP_CauseProtocol_unspecified, - -1); - return -1; - } - /* - * * TODO: call the reset procedure - */ - } - } - else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList){ - if (ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count > 0) { - x2ap_eNB_data->num_cc = ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count; - for (int i=0; ivalue.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;i++) { - servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.array[i]; - x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedEUTRACellInfo.pCI; - } - } - } - } - } - else { - X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__); - return -1; - } - } - - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - - // Panos: Here we should be calling an ENDC specific setup response function - return x2ap_gNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); - //return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); -} - -int -x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - X2AP_X2AP_PDU_t *pdu) -{ - - X2AP_ENDCX2SetupResponse_t *x2_ENDC_SetupResponse; - X2AP_ENDCX2SetupResponse_IEs_t *ie; - X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *ie_GNB_ENDC; - ServedNRcellsENDCX2ManagementList__Member *servedCellMember; - - x2ap_eNB_instance_t *instance_p; - x2ap_eNB_data_t *x2ap_eNB_data; - uint32_t gNB_id = 0; - - x2ap_eNB_data = NULL; - DevAssert (pdu != NULL); - x2_ENDC_SetupResponse = &pdu->choice.successfulOutcome.value.choice.ENDCX2SetupResponse; - - /* - * We received a new valid X2 Setup Request on a stream != 0. - * * * * This should not happen -> reject eNB x2 setup request. - */ - - if (stream != 0) { - X2AP_ERROR("Received new x2 setup request on stream != 0\n"); - /* - * Send a x2 setup failure with protocol cause unspecified - */ - // Panos: Here we should be calling an ENDC specific setup_failure function instead - return x2ap_eNB_generate_x2_setup_failure (instance, - assoc_id, - X2AP_Cause_PR_protocol, - X2AP_CauseProtocol_unspecified, - -1); - } - - X2AP_DEBUG("Received a new X2 setup request\n"); - - X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupResponse_IEs_t, ie, x2_ENDC_SetupResponse, - X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup, true); - - - - if (ie == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } else { - if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count > 0) { - //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest - //message or the ie to which there are more nested information elements? - for (int i=0; ivalue.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count;i++) { - - ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.array[i]; + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i]; if (ie_GNB_ENDC == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; @@ -1606,6 +1461,150 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, } } + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + // Panos: Here we should be calling an ENDC specific setup response function + return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); + //return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); +} + +int +x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_ENDCX2SetupResponse_t *x2_ENDC_SetupResponse; + X2AP_ENDCX2SetupResponse_IEs_t *ie; + X2AP_ENB_ENDCX2SetupReqAckIEs_t *ie_ENB_ENDC; + ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + uint32_t eNB_id = 0; + + x2ap_eNB_data = NULL; + DevAssert (pdu != NULL); + x2_ENDC_SetupResponse = &pdu->choice.successfulOutcome.value.choice.ENDCX2SetupResponse; + + /* + * We received a new valid X2 Setup Request on a stream != 0. + * * * * This should not happen -> reject eNB x2 setup request. + */ + + if (stream != 0) { + X2AP_ERROR("Received new x2 setup request on stream != 0\n"); + /* + * Send a x2 setup failure with protocol cause unspecified + */ + // Panos: Here we should be calling an ENDC specific setup_failure function instead + return x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + } + + X2AP_DEBUG("Received a new X2 setup request\n"); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupResponse_IEs_t, ie, x2_ENDC_SetupResponse, + X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup, true); + + + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } else { + if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count > 0) { + //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest + //message or the ie to which there are more nested information elements? + for (int i=0; ivalue.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count;i++) { + + ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.array[i]; + if (ie_ENB_ENDC == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_GlobalENB_ID) { + if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) { + // Home eNB ID = 28 bits + uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf; + if (ie_ENB_ENDC->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); + X2AP_DEBUG("Home eNB id: %07x\n", eNB_id); + } else { + // Macro eNB = 20 bits + uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; + if (ie_ENB_ENDC->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); + X2AP_DEBUG("macro eNB id: %05x\n", eNB_id); + } + X2AP_DEBUG("Adding eNB to the list of associated eNBs\n"); + if ((x2ap_eNB_data = x2ap_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 ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { + /* + * ?? + */ + return -1; + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + x2ap_eNB_data->eNB_id = eNB_id; + } + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + + /* + * eNB has been found in list, consider the x2 setup request as a reset connection, + * * * * reseting any previous UE state if sctp association is != than the previous one + */ + if (x2ap_eNB_data->assoc_id != assoc_id) { + /* + * ??: Send an overload cause... + */ + X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id); + + // Panos: Here we should be calling an ENDC specific setup_failure function instead + x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + return -1; + } + /* + * * TODO: call the reset procedure + */ + } + } + else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList){ + if (ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count > 0) { + x2ap_eNB_data->num_cc = ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count; + for (int i=0; ivalue.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;i++) { + servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.array[i]; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedEUTRACellInfo.pCI; + } + } + } + } + } + else { + X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__); + return -1; + } + } + /* Optionaly set the target eNB name */ /* The association is now ready as source and target eNBs know parameters of each other. @@ -1621,5 +1620,3 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, return 0; } - - From 7916e176666a6a31f0c4c4e8a2214ffcd7ebeaa5 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 8 Oct 2019 18:48:39 +0200 Subject: [PATCH 048/343] ENDC: Add X2AP initial configuration and X2AP task in nr-softmodem. Small issue with parsing NRCCPARAMS_DESC from RCconfig_NR_X2() needs to be resolved --- common/config/config_userapi.c | 1 - executables/nr-softmodem.c | 13 + openair2/ENB_APP/enb_config.c | 5 - openair2/GNB_APP/gnb_app.c | 30 +- openair2/GNB_APP/gnb_config.c | 432 +++++++++++++++++++++ openair2/GNB_APP/gnb_config.h | 1 + openair2/GNB_APP/gnb_paramdef.h | 8 +- openair2/X2AP/x2ap_eNB.c | 14 +- openair2/X2AP/x2ap_eNB_generate_messages.c | 2 +- 9 files changed, 493 insertions(+), 13 deletions(-) diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 13dd6730eb..bf0ae01cf7 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -213,7 +213,6 @@ int config_get(paramdef_t *params, int numparams, char *prefix) { } configmodule_interface_t *cfgif = config_get_if(); - if (cfgif != NULL) { ret = config_get_if()->get(params, numparams, prefix); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index d95d6a1d2e..2c76c929a0 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -84,6 +84,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "stats.h" #include "nr-softmodem.h" #include "NB_IoT_interface.h" +#include "x2ap_eNB.h" short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655}; @@ -460,6 +461,18 @@ int create_gNB_tasks(uint32_t gnb_nb) { LOG_E(GNB_APP, "Create task for gNB APP failed\n"); return -1; } + if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ + LOG_E(SCTP, "Create task for SCTP failed\n"); + return -1; + } + if (is_x2ap_enabled()) { + if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){ + LOG_E(X2AP, "Create task for X2AP failed\n"); + } + } + else { + LOG_I(X2AP, "X2AP is disabled.\n"); + } } /* diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2a66166762..3c925a0410 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2360,11 +2360,6 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { X2AP_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) { X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; - // Temporary option to be able to parse an eNB configuration file which is treated as gNB from - // the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to - // parse an actual gNB configuration file wrt. the X2AP parameters instead. - } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB; }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", diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 2a1267fa7c..df23de6797 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -46,7 +46,7 @@ # endif # include "PHY/INIT/phy_init.h" - +# include "x2ap_eNB.h" extern unsigned char NB_gNB_INST; #endif @@ -115,16 +115,38 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, } # endif */ + +/*------------------------------------------------------------------------------*/ +static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) { + uint32_t gnb_id; + MessageDef *msg_p; + uint32_t register_gnb_x2_pending = 0; + + for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { + { + msg_p = itti_alloc_new_message (TASK_GNB_APP, X2AP_REGISTER_ENB_REQ); + LOG_I(X2AP, "GNB_ID: %d \n", gnb_id); + RCconfig_NR_X2(msg_p, gnb_id); + itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); + register_gnb_x2_pending++; + } + } + + return register_gnb_x2_pending; +} + #endif /*------------------------------------------------------------------------------*/ void *gNB_app_task(void *args_p) { + #if defined(ENABLE_ITTI) uint32_t gnb_nb = RC.nb_nr_inst; uint32_t gnb_id_start = 0; uint32_t gnb_id_end = gnb_id_start + gnb_nb; + uint32_t x2_register_gnb_pending = 0; # if defined(ENABLE_USE_MME) //uint32_t register_gnb_pending; //uint32_t registered_gnb; @@ -166,6 +188,12 @@ void *gNB_app_task(void *args_p) configure_nr_rrc(gnb_id); } + if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type) + LOG_I(X2AP, "X2AP enabled \n"); + x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end); + + } + # if defined(ENABLE_USE_MME) /* Try to register each gNB */ //registered_gnb = 0; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 71bec1bc58..9ceda83f64 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -3010,3 +3010,435 @@ void NRRCConfig(void) { } + +int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { + int I, J, l; + char *address = NULL; + char *cidr = NULL; + + int num_gnbs = 0; + int num_component_carriers = 0; + int j,k = 0; + int32_t gnb_id = 0; + + int nb_cc = 0; + char* frame_type = NULL; + char* DL_prefix_type = NULL; + char* UL_prefix_type = NULL; + + int32_t nr_band = 0; + uint64_t downlink_frequency = 0; + int32_t uplink_frequency_offset = 0; + int32_t Nid_cell = 0; + int32_t N_RB_DL = 0; + int32_t nb_antenna_ports = 0; + + ///NR + //MIB + int32_t MIB_subCarrierSpacingCommon = 0; + int32_t MIB_ssb_SubcarrierOffset = 0; + int32_t MIB_dmrs_TypeA_Position = 0; + int32_t pdcch_ConfigSIB1 = 0; + + //SIB1 + char* SIB1_frequencyOffsetSSB = NULL; + int32_t SIB1_ssb_PeriodicityServingCell = 0; + int32_t SIB1_ss_PBCH_BlockPower = 0; + //DownlinkConfigCommon + //NR FrequencyInfoDL + int32_t absoluteFrequencySSB = 0; + int32_t DL_FreqBandIndicatorNR = 0; + int32_t DL_absoluteFrequencyPointA = 0; + + //NR DL SCS-SpecificCarrier + int32_t DL_offsetToCarrier = 0; + char* DL_SCS_SubcarrierSpacing = 0; + int32_t DL_carrierBandwidth = 0; + + // NR BWP-DownlinkCommon + int32_t DL_locationAndBandwidth = 0; + char* DL_BWP_SubcarrierSpacing = 0; + char* DL_BWP_prefix_type = NULL; + + //NR FrequencyInfoUL + int32_t UL_FreqBandIndicatorNR = 0; + int32_t UL_absoluteFrequencyPointA = 0; + int32_t UL_additionalSpectrumEmission = 0; + int32_t UL_p_Max = 0; + char* UL_frequencyShift7p5khz = 0; + + //NR UL SCS-SpecificCarrier + int32_t UL_offsetToCarrier = 0; + char* UL_SCS_SubcarrierSpacing = 0; + int32_t UL_carrierBandwidth = 0; + + // NR BWP-UplinkCommon + int32_t UL_locationAndBandwidth = 0; + char* UL_BWP_SubcarrierSpacing = 0; + char* UL_BWP_prefix_type = NULL; + char* UL_timeAlignmentTimerCommon = 0; + + char* ServingCellConfigCommon_n_TimingAdvanceOffset = 0; + uint64_t ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0; + int32_t ServingCellConfigCommon_ssb_periodicityServingCell = 0; + int32_t ServingCellConfigCommon_dmrs_TypeA_Position = 0; + char* NIA_SubcarrierSpacing = 0; + int32_t ServingCellConfigCommon_ss_PBCH_BlockPower = 0; + + //NR TDD-UL-DL-ConfigCommon + char* referenceSubcarrierSpacing = 0; + char* dl_UL_TransmissionPeriodicity = 0; + int32_t nrofDownlinkSlots = 0; + int32_t nrofDownlinkSymbols = 0; + int32_t nrofUplinkSlots = 0; + int32_t nrofUplinkSymbols = 0; + + //NR RACH-ConfigCommon + int32_t rach_totalNumberOfRA_Preambles = 0; + char* rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 0; + int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 0; + char* rach_groupBconfigured = NULL; + int32_t rach_ra_Msg3SizeGroupA = 0; + char* rach_messagePowerOffsetGroupB = NULL; + int32_t rach_numberOfRA_PreamblesGroupA = 0; + int32_t rach_ra_ContentionResolutionTimer = 0; + int32_t rsrp_ThresholdSSB = 0; + int32_t rsrp_ThresholdSSB_SUL = 0; + char* prach_RootSequenceIndex_choice = NULL; + int32_t prach_RootSequenceIndex_l839 = 0; + int32_t prach_RootSequenceIndex_l139 = 0; + char* prach_msg1_SubcarrierSpacing = NULL; + char* restrictedSetConfig = NULL; + char* msg3_transformPrecoding = NULL; + //ssb-perRACH-OccasionAndCB-PreamblesPerSSB not sure + + //NR RACH-ConfigGeneric + int32_t prach_ConfigurationIndex = 0; + char* prach_msg1_FDM = NULL; + int32_t prach_msg1_FrequencyStart = 0; + int32_t zeroCorrelationZoneConfig = 0; + int32_t preambleReceivedTargetPower = 0; + int32_t preambleTransMax = 0; + char* powerRampingStep = NULL; + int32_t ra_ResponseWindow = 0; + + //PUSCH-ConfigCommon + char* groupHoppingEnabledTransformPrecoding = NULL; + int32_t msg3_DeltaPreamble = 0; + int32_t p0_NominalWithGrant = 0; + + ///PUSCH-TimeDomainResourceAllocation + int32_t PUSCH_TimeDomainResourceAllocation_k2 = 0; + char* PUSCH_TimeDomainResourceAllocation_mappingType = NULL; + int32_t PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + + //PUCCH-ConfigCommon + int32_t pucch_ResourceCommon = 0; + char* pucch_GroupHopping = NULL; + int32_t hoppingId = 0; + int32_t p0_nominal = 0; + + //PDSCH-ConfigCOmmon + //PDSCH-TimeDomainResourceAllocation + int32_t PDSCH_TimeDomainResourceAllocation_k0 = 0; + char* PDSCH_TimeDomainResourceAllocation_mappingType = NULL; + int32_t PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + + //RateMatchPattern is used to configure one rate matching pattern for PDSCH + int32_t rateMatchPatternId = 0; + char* RateMatchPattern_patternType = NULL; + char* symbolsInResourceBlock = NULL; + int32_t periodicityAndPattern = 0; + int32_t RateMatchPattern_controlResourceSet = 0; + char* RateMatchPattern_subcarrierSpacing = NULL; + char* RateMatchPattern_mode = NULL; + + //PDCCH-ConfigCommon + int32_t controlResourceSetZero = 0; + int32_t searchSpaceZero = 0; + int32_t searchSpaceSIB1 = 0; + int32_t searchSpaceOtherSystemInformation = 0; + int32_t pagingSearchSpace = 0; + int32_t ra_SearchSpace = 0; + + //NR PDCCH-ConfigCommon commonControlResourcesSets + int32_t PDCCH_common_controlResourceSetId = 0; + int32_t PDCCH_common_ControlResourceSet_duration = 0; + char* PDCCH_cce_REG_MappingType = NULL; + int32_t PDCCH_reg_BundleSize = 0; + int32_t PDCCH_interleaverSize = 0; + int32_t PDCCH_shiftIndex = 0; + char* PDCCH_precoderGranularity = NULL; + int32_t PDCCH_TCI_StateId = 0; + char* tci_PresentInDCI = NULL; + int32_t PDCCH_DMRS_ScramblingID = 0; + + //NR PDCCH-ConfigCommon commonSearchSpaces + int32_t SearchSpaceId = 0; + int32_t commonSearchSpaces_controlResourceSetId = 0; + char* SearchSpace_monitoringSlotPeriodicityAndOffset_choice = NULL; + int32_t SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; + int32_t SearchSpace_duration = 0; + int32_t SearchSpace_nrofCandidates_aggregationLevel1 = 0; + int32_t SearchSpace_nrofCandidates_aggregationLevel2 = 0; + int32_t SearchSpace_nrofCandidates_aggregationLevel4 = 0; + int32_t SearchSpace_nrofCandidates_aggregationLevel8 = 0; + int32_t SearchSpace_nrofCandidates_aggregationLevel16 = 0; + char* SearchSpace_searchSpaceType = NULL; + int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 0; + int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 0; + int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 0; + int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 0; + int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 0; + int32_t Common_dci_Format2_3_monitoringPeriodicity = 0; + int32_t Common_dci_Format2_3_nrofPDCCH_Candidates = 0; + char* ue_Specific__dci_Formats = NULL; + //NR RateMatchPatternLTE-CRS + int32_t RateMatchPatternLTE_CRS_carrierFreqDL = 0; + int32_t RateMatchPatternLTE_CRS_carrierBandwidthDL = 0; + int32_t RateMatchPatternLTE_CRS_nrofCRS_Ports = 0; + int32_t RateMatchPatternLTE_CRS_v_Shift = 0; + int32_t RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 0; + int32_t RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; + char* RateMatchPatternLTE_CRS_subframeAllocation_choice = NULL; + + + + //temp out + ccparams_lte_t ccparams_lte; + memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t)); + + paramdef_t GNBSParams[] = GNBSPARAMS_DESC; + paramdef_t GNBParams[] = GNBPARAMS_DESC; + paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; + /* get global parameters, defined outside any section in the config file */ + config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; + + //temp out + //paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte); + + paramdef_t CCsParams[] = NRCCPARAMS_DESC; + + paramlist_def_t CCsParamList = {GNB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; + + /* 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 < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt, + "Failed to parse config file %s, %uth attribute %s \n", + RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS); + + if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) { + // Output a list of all gNBs. + config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); + + if (GNBParamList.numelt > 0) { + for (k = 0; k < GNBParamList.numelt; k++) { + if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { + // Calculate a default eNB ID + if (EPC_MODE_ENABLED) { + uint32_t hash; + hash = s1ap_generate_eNB_id (); + gnb_id = k + (hash & 0xFFFF8); + } else { + gnb_id = k; + } + } else { + gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr); + } + + // search if in active list + for (j = 0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { + if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { + paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {GNB_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 X2Params[] = X2PARAMS_DESC; + paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; + paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC; + paramdef_t NETParams[] = GNBNETPARAMS_DESC; + /* 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]",GNB_CONFIG_STRING_GNB_LIST,k); + /* Some default/random parameters */ + X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = gnb_id; + + if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB; + /*} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; + // Temporary option to be able to parse an eNB configuration file which is treated as gNB from + // the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to + // parse an actual gNB configuration file wrt. the X2AP parameters instead. + } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB;*/ + }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, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); + } + + X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); + X2AP_REGISTER_ENB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 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(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n"); + + X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 + || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + X2AP_REGISTER_ENB_REQ(msg_p).mnc); + /* CC params */ + config_getlist(&CCsParamList, NULL, 0, aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; + + if (CCsParamList.numelt > 0) { + for (J = 0; J < CCsParamList.numelt ; J++) { + + sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_COMPONENT_CARRIERS, J), + config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + + X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = nr_band; //78 + X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = downlink_frequency; //3600000000 + X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) uplink_frequency_offset; //0 + X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= Nid_cell; //0 + + /*if (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, Nid_cell); + }*/ + + X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= N_RB_DL; //106 + + /*if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (N_RB_DL!=100) && (N_RB_DL!=106)) { + 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, N_RB_DL); + }*/ + + //X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + + if (strcmp(frame_type, "FDD") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; + } else if (strcmp(frame_type, "TDD") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + //Don't know which are the corresponding NR parameters for the following two + //X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = tdd_config; + //X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s; + } 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, frame_type); + } + + //Temp out + /*X2AP_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); + X2AP_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]",GNB_CONFIG_STRING_GNB_LIST,k); + config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); + AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, + "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", + X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); + X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; + + for (l = 0; l < X2ParamList.numelt; l++) { + X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1; + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr)); + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr)); + + if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0; + } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; + } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_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(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n"); + exit(1); + } + + X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep; + X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall; + } + // SCTP SETTING + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; + + if (EPC_MODE_ENABLED) { + sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); + } + + sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + // NETWORK_INTERFACES + config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr); + + //temp out + if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { + LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n"); + exit(1); + } + + cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr); + address = strtok(cidr, "/"); + X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0; + X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1; + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address); + } + } + } + } + } + + return 0; +} + + diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index 8320c5ccdc..e2588d9e4d 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -103,6 +103,7 @@ extern void NRRCConfig(void); void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc); int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i); +int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); #endif /* GNB_CONFIG_H_ */ /** @} */ diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 1ca6f2d7ec..611f721213 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -997,6 +997,10 @@ typedef enum { #define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U "GNB_IPV4_ADDRESS_FOR_S1U" #define GNB_CONFIG_STRING_GNB_PORT_FOR_S1U "GNB_PORT_FOR_S1U" +/* X2 interface configuration parameters names */ +#define GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C "GNB_IPV4_ADDRESS_FOR_X2C" +#define GNB_CONFIG_STRING_ENB_PORT_FOR_X2C "GNB_PORT_FOR_X2C" + /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ /* S1 interface configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -1006,7 +1010,9 @@ typedef enum { {GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0} \ +{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \ +{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0} \ } diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index c8f35d6d13..6d945626ee 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -554,7 +554,6 @@ int is_x2ap_enabled(void) 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; @@ -567,13 +566,20 @@ int is_x2ap_enabled(void) /* TODO: do it per module - we check only first eNB */ config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]"); - if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0) - enabled = 1; + if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0){ + enabled = 1; + } + + /*Consider also the case of enabling X2AP for a gNB by parsing a gNB configuration file*/ + + config_get(p, sizeof(p)/sizeof(paramdef_t), "gNBs.[0]"); + if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0){ + enabled = 1; + } config_loaded = 1; if (pthread_mutex_unlock(&mutex)) goto mutex_error; - return enabled; mutex_error: diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 201ac0a03c..8d203b286a 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1314,7 +1314,7 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn); } - if (instance_p->frame_type[i] == FDD) { // Panos: Remember to change that to TDD + if (instance_p->frame_type[i] == TDD) { X2AP_FreqBandNrItem_t *freq_band; servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i]; From c107789e4ccda46c084efd8d967f2124b4854c5f Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 9 Oct 2019 07:30:10 -0700 Subject: [PATCH 049/343] [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 050/343] [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 cc8be29a8da823d420a9d5e186625c1416d91c91 Mon Sep 17 00:00:00 2001 From: matzakos Date: Mon, 21 Oct 2019 17:29:21 +0200 Subject: [PATCH 051/343] ENDC: Restore X2AP initial configuration after merge with NR_RRCConfiguration branch --- openair2/GNB_APP/gnb_config.c | 281 ++---------------- openair2/GNB_APP/gnb_paramdef.h | 25 ++ .../CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 18 +- 3 files changed, 58 insertions(+), 266 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index c9e633b31c..61da86bb3f 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -987,227 +987,22 @@ void NRRCConfig(void) { } int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { - int I, J, l; + int J, l; char *address = NULL; char *cidr = NULL; - int num_gnbs = 0; - int num_component_carriers = 0; + //int num_gnbs = 0; + //int num_component_carriers = 0; int j,k = 0; int32_t gnb_id = 0; - int nb_cc = 0; - char* frame_type = NULL; - char* DL_prefix_type = NULL; - char* UL_prefix_type = NULL; - - int32_t nr_band = 0; - uint64_t downlink_frequency = 0; - int32_t uplink_frequency_offset = 0; - int32_t Nid_cell = 0; - int32_t N_RB_DL = 0; - int32_t nb_antenna_ports = 0; - - ///NR - //MIB - int32_t MIB_subCarrierSpacingCommon = 0; - int32_t MIB_ssb_SubcarrierOffset = 0; - int32_t MIB_dmrs_TypeA_Position = 0; - int32_t pdcch_ConfigSIB1 = 0; - - //SIB1 - char* SIB1_frequencyOffsetSSB = NULL; - int32_t SIB1_ssb_PeriodicityServingCell = 0; - int32_t SIB1_ss_PBCH_BlockPower = 0; - //DownlinkConfigCommon - //NR FrequencyInfoDL - int32_t absoluteFrequencySSB = 0; - int32_t DL_FreqBandIndicatorNR = 0; - int32_t DL_absoluteFrequencyPointA = 0; - - //NR DL SCS-SpecificCarrier - int32_t DL_offsetToCarrier = 0; - char* DL_SCS_SubcarrierSpacing = 0; - int32_t DL_carrierBandwidth = 0; - - // NR BWP-DownlinkCommon - int32_t DL_locationAndBandwidth = 0; - char* DL_BWP_SubcarrierSpacing = 0; - char* DL_BWP_prefix_type = NULL; - - //NR FrequencyInfoUL - int32_t UL_FreqBandIndicatorNR = 0; - int32_t UL_absoluteFrequencyPointA = 0; - int32_t UL_additionalSpectrumEmission = 0; - int32_t UL_p_Max = 0; - char* UL_frequencyShift7p5khz = 0; - - //NR UL SCS-SpecificCarrier - int32_t UL_offsetToCarrier = 0; - char* UL_SCS_SubcarrierSpacing = 0; - int32_t UL_carrierBandwidth = 0; - - // NR BWP-UplinkCommon - int32_t UL_locationAndBandwidth = 0; - char* UL_BWP_SubcarrierSpacing = 0; - char* UL_BWP_prefix_type = NULL; - char* UL_timeAlignmentTimerCommon = 0; - - char* ServingCellConfigCommon_n_TimingAdvanceOffset = 0; - uint64_t ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0; - int32_t ServingCellConfigCommon_ssb_periodicityServingCell = 0; - int32_t ServingCellConfigCommon_dmrs_TypeA_Position = 0; - char* NIA_SubcarrierSpacing = 0; - int32_t ServingCellConfigCommon_ss_PBCH_BlockPower = 0; - - //NR TDD-UL-DL-ConfigCommon - char* referenceSubcarrierSpacing = 0; - char* dl_UL_TransmissionPeriodicity = 0; - int32_t nrofDownlinkSlots = 0; - int32_t nrofDownlinkSymbols = 0; - int32_t nrofUplinkSlots = 0; - int32_t nrofUplinkSymbols = 0; - - //NR RACH-ConfigCommon - int32_t rach_totalNumberOfRA_Preambles = 0; - char* rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 0; - int32_t rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 0; - char* rach_groupBconfigured = NULL; - int32_t rach_ra_Msg3SizeGroupA = 0; - char* rach_messagePowerOffsetGroupB = NULL; - int32_t rach_numberOfRA_PreamblesGroupA = 0; - int32_t rach_ra_ContentionResolutionTimer = 0; - int32_t rsrp_ThresholdSSB = 0; - int32_t rsrp_ThresholdSSB_SUL = 0; - char* prach_RootSequenceIndex_choice = NULL; - int32_t prach_RootSequenceIndex_l839 = 0; - int32_t prach_RootSequenceIndex_l139 = 0; - char* prach_msg1_SubcarrierSpacing = NULL; - char* restrictedSetConfig = NULL; - char* msg3_transformPrecoding = NULL; - //ssb-perRACH-OccasionAndCB-PreamblesPerSSB not sure - - //NR RACH-ConfigGeneric - int32_t prach_ConfigurationIndex = 0; - char* prach_msg1_FDM = NULL; - int32_t prach_msg1_FrequencyStart = 0; - int32_t zeroCorrelationZoneConfig = 0; - int32_t preambleReceivedTargetPower = 0; - int32_t preambleTransMax = 0; - char* powerRampingStep = NULL; - int32_t ra_ResponseWindow = 0; - - //PUSCH-ConfigCommon - char* groupHoppingEnabledTransformPrecoding = NULL; - int32_t msg3_DeltaPreamble = 0; - int32_t p0_NominalWithGrant = 0; - - ///PUSCH-TimeDomainResourceAllocation - int32_t PUSCH_TimeDomainResourceAllocation_k2 = 0; - char* PUSCH_TimeDomainResourceAllocation_mappingType = NULL; - int32_t PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; - - //PUCCH-ConfigCommon - int32_t pucch_ResourceCommon = 0; - char* pucch_GroupHopping = NULL; - int32_t hoppingId = 0; - int32_t p0_nominal = 0; - - //PDSCH-ConfigCOmmon - //PDSCH-TimeDomainResourceAllocation - int32_t PDSCH_TimeDomainResourceAllocation_k0 = 0; - char* PDSCH_TimeDomainResourceAllocation_mappingType = NULL; - int32_t PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; - - //RateMatchPattern is used to configure one rate matching pattern for PDSCH - int32_t rateMatchPatternId = 0; - char* RateMatchPattern_patternType = NULL; - char* symbolsInResourceBlock = NULL; - int32_t periodicityAndPattern = 0; - int32_t RateMatchPattern_controlResourceSet = 0; - char* RateMatchPattern_subcarrierSpacing = NULL; - char* RateMatchPattern_mode = NULL; - - //PDCCH-ConfigCommon - int32_t controlResourceSetZero = 0; - int32_t searchSpaceZero = 0; - int32_t searchSpaceSIB1 = 0; - int32_t searchSpaceOtherSystemInformation = 0; - int32_t pagingSearchSpace = 0; - int32_t ra_SearchSpace = 0; - - //NR PDCCH-ConfigCommon commonControlResourcesSets - int32_t PDCCH_common_controlResourceSetId = 0; - int32_t PDCCH_common_ControlResourceSet_duration = 0; - char* PDCCH_cce_REG_MappingType = NULL; - int32_t PDCCH_reg_BundleSize = 0; - int32_t PDCCH_interleaverSize = 0; - int32_t PDCCH_shiftIndex = 0; - char* PDCCH_precoderGranularity = NULL; - int32_t PDCCH_TCI_StateId = 0; - char* tci_PresentInDCI = NULL; - int32_t PDCCH_DMRS_ScramblingID = 0; - - //NR PDCCH-ConfigCommon commonSearchSpaces - int32_t SearchSpaceId = 0; - int32_t commonSearchSpaces_controlResourceSetId = 0; - char* SearchSpace_monitoringSlotPeriodicityAndOffset_choice = NULL; - int32_t SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; - int32_t SearchSpace_duration = 0; - int32_t SearchSpace_nrofCandidates_aggregationLevel1 = 0; - int32_t SearchSpace_nrofCandidates_aggregationLevel2 = 0; - int32_t SearchSpace_nrofCandidates_aggregationLevel4 = 0; - int32_t SearchSpace_nrofCandidates_aggregationLevel8 = 0; - int32_t SearchSpace_nrofCandidates_aggregationLevel16 = 0; - char* SearchSpace_searchSpaceType = NULL; - int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 0; - int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 0; - int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 0; - int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 0; - int32_t Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 0; - int32_t Common_dci_Format2_3_monitoringPeriodicity = 0; - int32_t Common_dci_Format2_3_nrofPDCCH_Candidates = 0; - char* ue_Specific__dci_Formats = NULL; - //NR RateMatchPatternLTE-CRS - int32_t RateMatchPatternLTE_CRS_carrierFreqDL = 0; - int32_t RateMatchPatternLTE_CRS_carrierBandwidthDL = 0; - int32_t RateMatchPatternLTE_CRS_nrofCRS_Ports = 0; - int32_t RateMatchPatternLTE_CRS_v_Shift = 0; - int32_t RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 0; - int32_t RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; - char* RateMatchPatternLTE_CRS_subframeAllocation_choice = NULL; - - - - //temp out - ccparams_lte_t ccparams_lte; - memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t)); - paramdef_t GNBSParams[] = GNBSPARAMS_DESC; paramdef_t GNBParams[] = GNBPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; /* get global parameters, defined outside any section in the config file */ config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); - checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; - //temp out - //paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte); - - paramdef_t CCsParams[] = NRCCPARAMS_DESC; - - paramlist_def_t CCsParamList = {GNB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; - - /* 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]); - } + //paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0}; AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt, "Failed to parse config file %s, %uth attribute %s \n", @@ -1256,13 +1051,6 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB; - /*} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; - // Temporary option to be able to parse an eNB configuration file which is treated as gNB from - // the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to - // parse an actual gNB configuration file wrt. the X2AP parameters instead. - } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB;*/ }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", @@ -1287,55 +1075,20 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", X2AP_REGISTER_ENB_REQ(msg_p).mnc); - /* CC params */ - config_getlist(&CCsParamList, NULL, 0, aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; - if (CCsParamList.numelt > 0) { - for (J = 0; J < CCsParamList.numelt ; J++) { + X2AP_REGISTER_ENB_REQ (msg_p).num_cc = 1; + J = 0; + X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = 78; //ccparams_nr_x2.nr_band; //78 + X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = 3600000000; //ccparams_nr_x2.downlink_frequency; //3600000000 + X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = 0; //(unsigned int) ccparams_nr_x2.uplink_frequency_offset; //0 + X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= 0; //ccparams_nr_x2.Nid_cell; //0 + X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= 106; //ccparams_nr_x2.N_RB_DL; //106 - sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_COMPONENT_CARRIERS, J), - config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; - X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = nr_band; //78 - X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = downlink_frequency; //3600000000 - X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) uplink_frequency_offset; //0 - X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= Nid_cell; //0 - - /*if (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, Nid_cell); - }*/ - - X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= N_RB_DL; //106 - - /*if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (N_RB_DL!=100) && (N_RB_DL!=106)) { - 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, N_RB_DL); - }*/ - - //X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; - - if (strcmp(frame_type, "FDD") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; - } else if (strcmp(frame_type, "TDD") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; - //Don't know which are the corresponding NR parameters for the following two - //X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = tdd_config; - //X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s; - } 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, frame_type); - } - - //Temp out - /*X2AP_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); - X2AP_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);*/ - } - } + //Temp out + /*X2AP_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); + X2AP_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]",GNB_CONFIG_STRING_GNB_LIST,k); config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); @@ -1394,10 +1147,10 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); // NETWORK_INTERFACES config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr); + X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[GNB_PORT_FOR_X2C_IDX].uptr); //temp out - if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { + if ((NETParams[GNB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n"); exit(1); } diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 2c531b71f9..20a87c9111 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -187,6 +187,29 @@ typedef enum { #define GNB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd" #define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" +typedef struct ccparams_nr_x2 { + char *frame_type; + int32_t tdd_config; + int32_t tdd_config_s; + int32_t nr_band; + long long int downlink_frequency; + int32_t uplink_frequency_offset; + int32_t Nid_cell; + int32_t N_RB_DL; + } ccparams_nr_x2_t; + + +#define CCPARAMS_NR_X2_DESC(ccparams) { \ + {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"TDD", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&ccparams.tdd_config, defintval:3, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:&ccparams.tdd_config_s, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:&ccparams.nr_band, defintval:78, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:3600000000, TYPE_UINT64, 0}, \ + {ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:0, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:&ccparams.Nid_cell, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:&ccparams.N_RB_DL, defintval:106, TYPE_UINT, 0} \ +} + /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -336,6 +359,8 @@ typedef enum { #define GNB_INTERFACE_NAME_FOR_S1U_IDX 2 #define GNB_IPV4_ADDR_FOR_S1U_IDX 3 #define GNB_PORT_FOR_S1U_IDX 4 +#define GNB_IPV4_ADDR_FOR_X2C_IDX 5 +#define GNB_PORT_FOR_X2C_IDX 6 /* S1 interface configuration parameters names */ #define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME "GNB_INTERFACE_NAME_FOR_S1_MME" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index e7fb9b8de8..067affa880 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -197,15 +197,29 @@ gNBs = preference = "ipv4"; } ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.12.108"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); NETWORK_INTERFACES : { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.188/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.188/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 + + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.188/23"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); From 4e64a34ada34e3e9bd44aae9720e8a4b8a9de7c9 Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 25 Oct 2019 14:13:49 +0200 Subject: [PATCH 052/343] ENDC: Basic implementation of x2ap_eNB_generate_ENDC_x2_SgNB_addition_request() --- openair2/COMMON/x2ap_messages_types.h | 31 ++++ openair2/X2AP/x2ap_eNB_generate_messages.c | 154 +++++++++++++++++++- openair2/X2AP/x2ap_eNB_generate_messages.h | 2 + openair2/X2AP/x2ap_eNB_handler.c | 160 ++++++++++++++++++++- openair3/UTILS/conversions.h | 10 +- 5 files changed, 343 insertions(+), 14 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index e502191d2b..2ccab19071 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -303,4 +303,35 @@ typedef struct x2ap_senb_addition_req_ack_s { } x2ap_senb_addition_req_ack_t; +typedef struct x2ap_ENDC_sgnb_addition_req_s { + /* used for RRC->X2AP in source eNB */ + int rnti; + + security_capabilities_t security_capabilities; + + uint8_t kgnb[32]; // keNB or keNB* + + /*next_hop_chaining_coun */ + long int kgnb_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]; + + x2ap_lastvisitedcell_info_t lastvisitedcell_info; + + uint8_t rrc_buffer[8192 /* arbitrary, big enough */]; + int rrc_buffer_size; + + int target_assoc_id; +} x2ap_ENDC_sgnb_addition_req__t; + + #endif /* X2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 8d203b286a..4f8122b93b 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1098,7 +1098,6 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2 return ret; } -//Panos: int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack) { @@ -1119,8 +1118,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p DevAssert(instance_p != NULL); DevAssert(x2ap_eNB_data_p != NULL); - //Panos: The fact that we have separate IDs here is because the ID for a specific UE might be different - //between the 2 eNBs? //ue_id = x2ap_addition_req_ack->x2_id_target; //Panos: change name to master_x2... //id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); //id_target = ue_id; @@ -1129,7 +1126,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p memset(&pdu, 0, sizeof(pdu)); pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation; - //Panos: What does the criticality indicate here? pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SeNBAdditionRequestAcknowledge; out = &pdu.choice.successfulOutcome.value.choice.SeNBAdditionRequestAcknowledge; @@ -1145,7 +1141,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p /* mandatory */ ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t)); ie->id = X2AP_ProtocolIE_ID_id_SeNB_UE_X2AP_ID; - //Panos: Why for the X2_HANDOVER_REQ_ACK here the criticality is ignore whereas in the specs it is reject? ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1; ie->value.choice.UE_X2AP_ID_1 = 0; @@ -1500,3 +1495,152 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( return ret; } +int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBAdditionRequest_t *out; + X2AP_SgNBAdditionRequest_IEs_t *ie; + X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *e_RABS_ToBeAdded_SgNBAddReq_ItemIEs; + X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item_t *e_RABS_ToBeAdded_SgNBAddReq_Item; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + // Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted + // with values coming from RRC. + uint16_t nRencryptionAlgorithms = 0; + uint16_t nRintegrityProtectionAlgorithms = 0; + uint8_t SgNBSecurityKey[32] = { 0 }; + + + int uEaggregateMaximumBitRateDownlink = 10^8; + int uEaggregateMaximumBitRateUplink = 10^8; + int e_rabs_tobeadded = 1; + int e_RAB_ID = 1; + int drb_ID = 2; + long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; + long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_present; + long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_present; + int qCI = 1; + X2AP_Pre_emptionCapability_t pre_emptionCapability = X2AP_Pre_emptionCapability_shall_not_trigger_pre_emption; + X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability = X2AP_Pre_emptionVulnerability_not_pre_emptable; + e_rab_setup_t e_MCG_rabs_tobeadded; + e_MCG_rabs_tobeadded.gtp_teid = 0; + e_MCG_rabs_tobeadded.eNB_addr.length = 24; + uint8_t buf[20] = { 0 }; + memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); + + OCTET_STRING_t CG_Config_Info; + char buf2[4096] = { 0 }; + memcpy(CG_Config_Info.buf, buf2, 4096); + CG_Config_Info.size = 4096; + + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBAdditionPreparation; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_InitiatingMessage__value_PR_SgNBAdditionRequest; + out = &pdu.choice.initiatingMessage.value.choice.SgNBAdditionRequest; + + ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; //Not sure about that + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_NRUESecurityCapabilities; + INT16_TO_BIT_STRING(nRencryptionAlgorithms, &ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms); + INT16_TO_BIT_STRING(nRintegrityProtectionAlgorithms, &ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNBSecurityKey; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_SgNBSecurityKey; + KENB_STAR_TO_BIT_STRING(SgNBSecurityKey, &ie->value.choice.SgNBSecurityKey); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UEAggregateMaximumBitRate; + INT32_TO_BUFFER(uEaggregateMaximumBitRateDownlink, &ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf); + ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.size = 4; + + INT32_TO_BUFFER(uEaggregateMaximumBitRateUplink, &ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf); + ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.size = 4; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + //Not sure if id should be X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List or X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList + ie->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_E_RABs_ToBeAdded_SgNBAddReqList; + + for (int i=0;iid = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item; + e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item; + e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item; + { + e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID; + e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID; + e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB; + e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; + e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; + if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI = qCI; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = pre_emptionCapability; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = pre_emptionVulnerability; + + //Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case + INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID); + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf = + calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); + + memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, + e_MCG_rabs_tobeadded.eNB_addr.buffer, + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); + } + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list, e_RABS_ToBeAdded_SgNBAddReq_ItemIEs); + } + + ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + memcpy(ie->value.choice.MeNBtoSgNBContainer.buf, CG_Config_Info.buf, CG_Config_Info.size); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 setup response\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; + +} + + diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 4abda36e5a..dffe164c6c 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -70,4 +70,6 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2a int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); +int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index dabbe0e8a6..b881418f46 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -114,8 +114,14 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); -/* Handlers matrix. Only eNB related procedure present here */ + +/* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */ { x2ap_eNB_handle_handover_cancel, 0, 0 }, /* handoverCancel */ @@ -144,6 +150,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* seNBinitiatedSeNBRelease */ { 0, 0, 0 }, /* seNBCounterCheck */ { 0, 0, 0 }, /* retrieveUEContext */ + { x2ap_gNB_handle_ENDC_sGNB_addition_request, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, @@ -152,8 +159,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, - { 0, 0, 0 }, - { x2ap_eNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, + { x2ap_eNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, /*X2AP_ProcedureCode_id_endcX2Setup*/ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } @@ -1499,7 +1505,7 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, /* * Send a x2 setup failure with protocol cause unspecified */ - // Panos: Here we should be calling an ENDC specific setup_failure function instead + // Here we should be calling an ENDC specific setup_failure function instead return x2ap_eNB_generate_x2_setup_failure (instance, assoc_id, X2AP_Cause_PR_protocol, @@ -1519,8 +1525,6 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, return -1; } else { if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count > 0) { - //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest - //message or the ie to which there are more nested information elements? for (int i=0; ivalue.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count;i++) { ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.array[i]; @@ -1575,7 +1579,7 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, */ X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id); - // Panos: Here we should be calling an ENDC specific setup_failure function instead + // Here we should be calling an ENDC specific setup_failure function instead x2ap_eNB_generate_x2_setup_failure (instance, assoc_id, X2AP_Cause_PR_protocol, @@ -1620,3 +1624,145 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, return 0; } + +static +int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + /* + X2AP_SgNBAdditionRequest_t *x2SgNBAdditionRequest; + X2AP_SgNBAdditionRequest_IEs_t *ie; + + X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *e_RABS_ToBeAdded_SgNBAddReq_ItemIEs; + X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item_t *e_RABS_ToBeAdded_SgNBAddReq_Item; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + + DevAssert (pdu != NULL); + x2SgNBAdditionRequest = &pdu->choice.initiatingMessage.value.choice.SgNBAdditionRequest; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); + // TODO: send a x2 failure response + return 0; + } + + X2AP_DEBUG ("Received a new X2 SgNB Addition request\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead + //msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + // allocate a new X2AP UE ID + ue_id = x2ap_allocate_new_id(&instance_p->id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP 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 + x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.SgNB_UE_X2AP_ID, ue_id); + x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET); + + X2AP_HANDOVER_REQ(msg).x2_id = ue_id; + + //X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. + //measResultListEUTRA.list.array[ncell_index]->physCellId; + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, + X2AP_ProtocolIE_ID_id_GUMMEI_ID, true); + + TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc, + X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); + OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code); + OCTET_STRING_TO_INT16(&ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, + X2AP_ProtocolIE_ID_id_UE_ContextInformation, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID; + + // TODO: properly store Target Cell ID + + X2AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; + + X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); + X2AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); + + //X2AP_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(X2AP_HANDOVER_REQ(msg).kenb, ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf, 32); + X2AP_HANDOVER_REQ(msg).kenb_ncc = ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount; + } else { + X2AP_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) { + + X2AP_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 = (X2AP_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; + + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_ToBeSetup_Item->e_RAB_ID ; + + memcpy(X2AP_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); + + X2AP_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, + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid); + + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; + X2AP_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; + X2AP_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 { + X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n"); + } + + X2AP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context; + + if (c->size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s + { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } + + memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); + X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);*/ + + return 0; +} diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index e39a841d96..d28c9acccb 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -116,8 +116,14 @@ do { \ #define INT16_TO_OCTET_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(2, sizeof(uint8_t)); \ - (aSN)->size = 2; \ - INT16_TO_BUFFER(x, (aSN)->buf); \ + INT16_TO_BUFFER(x, ((aSN)->buf)); \ + (aSN)->size = 2; \ +} while(0) + +#define INT16_TO_BIT_STRING(x, aSN) \ +do { \ + INT16_TO_OCTET_STRING(x, aSN); \ + (aSN)->bits_unused = 0; \ } while(0) #define INT8_TO_OCTET_STRING(x, aSN) \ From 587f9f63d031380aa58c5acf23ce3196b187c167 Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 25 Oct 2019 19:20:34 +0200 Subject: [PATCH 053/343] ENDC X2AP: Corrections on the generation of x2_sGNB_AdditionRequest message --- openair2/X2AP/x2ap_eNB_decoder.c | 7 +++-- openair2/X2AP/x2ap_eNB_encoder.c | 4 +-- openair2/X2AP/x2ap_eNB_generate_messages.c | 36 +++++++++++++--------- openair2/X2AP/x2ap_eNB_handler.c | 4 +-- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 7b178fb109..3fddefd28a 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -60,8 +60,11 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) break; case X2AP_ProcedureCode_id_endcX2Setup: - X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n"); - break; + X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n"); + break; + case X2AP_ProcedureCode_id_sgNBAdditionPreparation: + X2AP_INFO("X2AP_ProcedureCode_id_sgNBAdditionPreparation message!\n"); + break; default: X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", diff --git a/openair2/X2AP/x2ap_eNB_encoder.c b/openair2/X2AP/x2ap_eNB_encoder.c index 8b1c030d35..392206e4d7 100644 --- a/openair2/X2AP/x2ap_eNB_encoder.c +++ b/openair2/X2AP/x2ap_eNB_encoder.c @@ -44,9 +44,9 @@ int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) DevAssert(buffer != NULL); DevAssert(len != NULL); - if (asn1_xer_print) { + //if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)pdu); - } + //} encoded = aper_encode_to_new_buffer(&asn_DEF_X2AP_X2AP_PDU, 0, pdu, (void **)buffer); diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 4f8122b93b..fa52c2a408 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1513,17 +1513,15 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( uint16_t nRencryptionAlgorithms = 0; uint16_t nRintegrityProtectionAlgorithms = 0; uint8_t SgNBSecurityKey[32] = { 0 }; - - - int uEaggregateMaximumBitRateDownlink = 10^8; - int uEaggregateMaximumBitRateUplink = 10^8; + int uEaggregateMaximumBitRateDownlink = 100000000; + int uEaggregateMaximumBitRateUplink = 100000000; int e_rabs_tobeadded = 1; int e_RAB_ID = 1; int drb_ID = 2; long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; - long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_present; - long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_present; - int qCI = 1; + long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; + long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present; + long qCI = 1; X2AP_Pre_emptionCapability_t pre_emptionCapability = X2AP_Pre_emptionCapability_shall_not_trigger_pre_emption; X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability = X2AP_Pre_emptionVulnerability_not_pre_emptable; e_rab_setup_t e_MCG_rabs_tobeadded; @@ -1531,11 +1529,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_MCG_rabs_tobeadded.eNB_addr.length = 24; uint8_t buf[20] = { 0 }; memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); - OCTET_STRING_t CG_Config_Info; - char buf2[4096] = { 0 }; - memcpy(CG_Config_Info.buf, buf2, 4096); CG_Config_Info.size = 4096; + CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t)); DevAssert(instance_p != NULL); @@ -1579,10 +1575,12 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( ie->id = X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UEAggregateMaximumBitRate; - INT32_TO_BUFFER(uEaggregateMaximumBitRateDownlink, &ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf); + ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf = (uint8_t *)calloc(4, sizeof(uint8_t)); + INT32_TO_BUFFER(uEaggregateMaximumBitRateDownlink, ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf); ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.size = 4; - INT32_TO_BUFFER(uEaggregateMaximumBitRateUplink, &ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf); + ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf = (uint8_t *)calloc(4, sizeof(uint8_t)); + INT32_TO_BUFFER(uEaggregateMaximumBitRateUplink, ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf); ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.size = 4; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); @@ -1595,9 +1593,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( for (int i=0;iid = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item; + e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReq_Item; e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore; - e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item; + e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item; e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item; { e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID; @@ -1606,6 +1604,8 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item__resource_configuration_PR_sgNBPDCPpresent; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI = qCI; e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = pre_emptionCapability; e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = pre_emptionVulnerability; @@ -1625,13 +1625,19 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( } ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list, e_RABS_ToBeAdded_SgNBAddReq_ItemIEs); } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_MeNBtoSgNBContainer; + ie->value.choice.MeNBtoSgNBContainer.buf = (uint8_t *)calloc(4096, sizeof(uint8_t)); memcpy(ie->value.choice.MeNBtoSgNBContainer.buf, CG_Config_Info.buf, CG_Config_Info.size); + ie->value.choice.MeNBtoSgNBContainer.size = 4096; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { - X2AP_ERROR("Failed to encode ENDC X2 setup response\n"); + X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n"); return -1; } diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index b881418f46..ae6dd6c5da 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1470,9 +1470,9 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - // Panos: Here we should be calling an ENDC specific setup response function return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); - //return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); + //return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); + } int 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 054/343] [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 055/343] [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 056/343] [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 057/343] [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 058/343] [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 059/343] [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 060/343] [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 266926307d518945aecbd87978327b530afa151e Mon Sep 17 00:00:00 2001 From: matzakos Date: Thu, 7 Nov 2019 17:00:03 +0100 Subject: [PATCH 061/343] ENDC X2AP: Implementation of handler function for SgNB addition request message --- openair2/COMMON/s1ap_messages_types.h | 16 +++ openair2/COMMON/x2ap_messages_def.h | 3 + openair2/COMMON/x2ap_messages_types.h | 22 +++- openair2/X2AP/x2ap_eNB_generate_messages.c | 28 ++++- openair2/X2AP/x2ap_eNB_handler.c | 122 +++++++++++---------- 5 files changed, 124 insertions(+), 67 deletions(-) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index bfceddb936..aa718dbcf8 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -273,6 +273,22 @@ typedef struct e_rab_setup_s { uint32_t gtp_teid; } e_rab_setup_t; +typedef struct e_rab_tobe_added_s { + /* Unique e_rab_id for the UE. */ + uint8_t e_rab_id; + + /* Unique drb_ID for the UE. */ + uint8_t drb_ID; + + /* The transport layer address for the IP packets */ + transport_layer_addr_t eNB_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} e_rab_tobe_added_t; + + + typedef struct e_rab_tobeswitched_s { /* Unique e_rab_id for the UE. */ uint8_t e_rab_id; diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index 6c2d56a942..ed33abfbfd 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -50,3 +50,6 @@ MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_ /*Senb bearer addition messages X2AP <-> RRC */ MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_senb_addition_req_t , x2ap_senb_addition_req) + +/*SGnb bearer addition messages X2AP <-> RRC */ +MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 2ccab19071..3c429e930d 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -38,6 +38,7 @@ #define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release #define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel #define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req +#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 @@ -286,7 +287,7 @@ typedef struct x2ap_senb_addition_req_ack_s { int MeNB_UE_X2_id; - int SeNB_UE_X2_id; + int SgNB_UE_X2_id; uint8_t nb_sCG_e_rabs_tobeadded; @@ -304,12 +305,15 @@ typedef struct x2ap_senb_addition_req_ack_s { } x2ap_senb_addition_req_ack_t; typedef struct x2ap_ENDC_sgnb_addition_req_s { + int ue_x2_id; + /* used for RRC->X2AP in source eNB */ int rnti; security_capabilities_t security_capabilities; - uint8_t kgnb[32]; // keNB or keNB* + /* SgNB Security Key */ + uint8_t kgnb[32]; /*next_hop_chaining_coun */ long int kgnb_ncc; @@ -317,10 +321,10 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { /* UE aggregate maximum bitrate */ ambr_t ue_ambr; - uint8_t nb_e_rabs_tobesetup; + uint8_t nb_e_rabs_tobeadded; - /* 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 added by RRC layers */ + e_rab_tobe_added_t e_rabs_tobeadded[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; @@ -331,7 +335,13 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { int rrc_buffer_size; int target_assoc_id; -} x2ap_ENDC_sgnb_addition_req__t; + + /*long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; + long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; + long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;*/ + + +} x2ap_ENDC_sgnb_addition_req_t; #endif /* X2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index fa52c2a408..1d67b6e9be 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1524,14 +1524,29 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( long qCI = 1; X2AP_Pre_emptionCapability_t pre_emptionCapability = X2AP_Pre_emptionCapability_shall_not_trigger_pre_emption; X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability = X2AP_Pre_emptionVulnerability_not_pre_emptable; + priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY; e_rab_setup_t e_MCG_rabs_tobeadded; e_MCG_rabs_tobeadded.gtp_teid = 0; e_MCG_rabs_tobeadded.eNB_addr.length = 24; uint8_t buf[20] = { 0 }; memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); - OCTET_STRING_t CG_Config_Info; + + FILE *fd; + fd = fopen("uecap.raw","r"); + if (fd != NULL) { + OCTET_STRING_t CG_Config_Info; + CG_Config_Info.size = 4096; + CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t)); + int msg_len=fread(CG_Config_Info.buf,1,CG_Config_Info.size,fd); + + /*char buffer[4096]; + int msg_len=fread(buffer,1,4096,fd);*/ + LOG_I(RRC,"Read in %d bytes for uecap\n",msg_len); + + + /*OCTET_STRING_t CG_Config_Info; CG_Config_Info.size = 4096; - CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t)); + CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t));*/ DevAssert(instance_p != NULL); @@ -1608,7 +1623,8 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI = qCI; e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = pre_emptionCapability; - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = pre_emptionVulnerability; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority. pre_emptionVulnerability = pre_emptionVulnerability; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level; //Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID); @@ -1644,6 +1660,12 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + fclose(fd); + } + else { + LOG_I(RRC, "uecap.raw file could not be opened... \n"); + return -1; + } return ret; diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index ae6dd6c5da..a39bb29737 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1470,8 +1470,8 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); - //return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); + //return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); + return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); } @@ -1632,7 +1632,7 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_X2AP_PDU_t *pdu) { - /* + X2AP_SgNBAdditionRequest_t *x2SgNBAdditionRequest; X2AP_SgNBAdditionRequest_IEs_t *ie; @@ -1662,8 +1662,9 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, DevAssert(instance_p != NULL); //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead - //msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ); + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ); + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); if (ie == NULL ) { @@ -1671,6 +1672,7 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, return -1; } + // allocate a new X2AP UE ID ue_id = x2ap_allocate_new_id(&instance_p->id_manager); if (ue_id == -1) { @@ -1679,74 +1681,73 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, exit(1); } // rnti is unknown yet, must not be set to -1, 0 is fine - x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.SgNB_UE_X2AP_ID, ue_id); + x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id); x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET); - X2AP_HANDOVER_REQ(msg).x2_id = ue_id; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_x2_id = ue_id; - //X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. - //measResultListEUTRA.list.array[ncell_index]->physCellId; - X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, - X2AP_ProtocolIE_ID_id_GUMMEI_ID, true); - TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc, - X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); - OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code); - OCTET_STRING_TO_INT16(&ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id); + /* X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, + X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities, true); - X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, - X2AP_ProtocolIE_ID_id_UE_ContextInformation, true); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms); - if (ie == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms); - X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID; + /* X2AP_ProtocolIE_ID_id_SgNBSecurityKey */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, + X2AP_ProtocolIE_ID_id_SgNBSecurityKey, true); - // TODO: properly store Target Cell ID + if ((ie->value.choice.SgNBSecurityKey.buf) && + (ie->value.choice.SgNBSecurityKey.size == 32)) { + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ie->value.choice.SgNBSecurityKey.buf, 32); + } else { + X2AP_WARN ("Size of eNB key star does not match the expected value\n"); + } - X2AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; - X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); - X2AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); + /* X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, + X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate, true); - //X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr; + //X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_ambr.br_dl =ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink; + //X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_ambr.br_ul = ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink; - 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(X2AP_HANDOVER_REQ(msg).kenb, ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf, 32); - X2AP_HANDOVER_REQ(msg).kenb_ncc = ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount; - } else { - X2AP_WARN ("Size of eNB key star does not match the expected value\n"); - } + /* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, + X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList, true); - if (ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count > 0) { - X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count; + if (ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count > 0) { - for (int i=0;ivalue.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count;i++) { - e_RABS_ToBeSetup_ItemIEs = (X2AP_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; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count; - X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_ToBeSetup_Item->e_RAB_ID ; + for (int i=0;ivalue.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count;i++) { + e_RABS_ToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *) ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.array[i]; + e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item; - memcpy(X2AP_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); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].e_rab_id = e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID ; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].drb_ID = e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID; + if(e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.qci = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; - X2AP_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; + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer, + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); - OCTET_STRING_TO_INT32(&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID, - X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length = + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; + + OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID, + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid); + } - X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI; - X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; - X2AP_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; - X2AP_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; } } @@ -1754,15 +1755,20 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n"); } - X2AP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context; + /* X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, + X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true); - if (c->size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s - { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } + X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer; - memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); - X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; + if (ie->value.choice.MeNBtoSgNBContainer.size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s + { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } - itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);*/ + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size; + + + //itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; } From cd14e5d3dcb2e59bbb3c37887cc52b00ee992e00 Mon Sep 17 00:00:00 2001 From: LAD Date: Wed, 13 Nov 2019 00:53:34 -0800 Subject: [PATCH 062/343] 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 063/343] 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 50509dfc32b9eb8b4ba378913b037a73785221e1 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 19 Nov 2019 14:05:14 +0100 Subject: [PATCH 064/343] ENDC: Enable transfer and handling of SgNB Addition request elements from X2AP to RRC of gNB. --- openair2/COMMON/x2ap_messages_types.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 62 ++++++++++++++++++++++++++- openair2/X2AP/x2ap_eNB_decoder.c | 4 +- openair2/X2AP/x2ap_eNB_handler.c | 6 +-- 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 3c429e930d..6bbfc6efd7 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -331,7 +331,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { x2ap_lastvisitedcell_info_t lastvisitedcell_info; - uint8_t rrc_buffer[8192 /* arbitrary, big enough */]; + uint8_t rrc_buffer[4096 /* arbitrary, big enough */]; int rrc_buffer_size; int target_assoc_id; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5bd775ff77..5c23a13910 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -203,7 +203,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { ); - if (phy_test > 0) { + /*if (phy_test > 0) { // This is for phytest only, emulate first X2 message if uecap.raw file is present FILE *fd; @@ -252,7 +252,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); rrc_add_nsa_user(rrc,ue_context_p); } - } + }*/ } @@ -298,6 +298,59 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu }//END openair_rrc_gNB_configuration +void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) { + +FILE *fd; +fd = fopen("uecap.raw","r"); +if (fd != NULL) { + char buffer[4096]; + int msg_len=fread(buffer,1,4096,fd); + fclose(fd); +} + /*LOG_I(RRC,"Read in %d bytes for uecap\n",msg_len);*/ + + + + LTE_UL_DCCH_Message_t *LTE_UL_DCCH_Message; + + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_LTE_UL_DCCH_Message, + (void **)<E_UL_DCCH_Message, + (uint8_t *)m->rrc_buffer, + (int) m->rrc_buffer_size);//m->rrc_buffer_size); + gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_LTE_UL_DCCH_Message, LTE_UL_DCCH_Message, 1 ); + return; + } + xer_fprint(stdout,&asn_DEF_LTE_UL_DCCH_Message, LTE_UL_DCCH_Message); + // recreate enough of X2 EN-DC Container + AssertFatal(LTE_UL_DCCH_Message->message.choice.c1.present == LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation, + "ueCapabilityInformation not present\n"); + NR_CG_ConfigInfo_t *CG_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo)); + CG_ConfigInfo->criticalExtensions.present = NR_CG_ConfigInfo__criticalExtensions_PR_c1; + CG_ConfigInfo->criticalExtensions.choice.c1 = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1)); + CG_ConfigInfo->criticalExtensions.choice.c1->present = NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo; + CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo)); + NR_CG_ConfigInfo_IEs_t *cg_ConfigInfo = CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo; + cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof(*cg_ConfigInfo->ue_CapabilityInfo)); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,NULL,(void*)<E_UL_DCCH_Message->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList,m->rrc_buffer,m->rrc_buffer_size); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, + (const char *)m->rrc_buffer, + (enc_rval.encoded+7)>>3); + parse_CG_ConfigInfo(rrc,CG_ConfigInfo); + +} + + + + + ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -393,6 +446,11 @@ void *rrc_gnb_task(void *args_p) { LOG_I(NR_RRC, "[gNB %d] Received %s : %p\n", instance, msg_name_p,&NRRRC_CONFIGURATION_REQ(msg_p)); openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p)); break; + + case X2AP_ENDC_SGNB_ADDITION_REQ: + LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n"); + rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); + break; default: LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p); diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 3fddefd28a..6535ce0a78 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -137,9 +137,9 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3 length, 0, 0); - if (asn1_xer_print) { + //if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu); - } + //} if (dec_ret.code != RC_OK) { X2AP_ERROR("Failed to decode pdu\n"); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index a39bb29737..feeaeaaeda 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1647,11 +1647,11 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, DevAssert (pdu != NULL); x2SgNBAdditionRequest = &pdu->choice.initiatingMessage.value.choice.SgNBAdditionRequest; - if (stream == 0) { + /*if (stream == 0) { X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); // TODO: send a x2 failure response return 0; - } + }*/ X2AP_DEBUG ("Received a new X2 SgNB Addition request\n"); @@ -1768,7 +1768,7 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size; - //itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); return 0; } From 7e1607bcca4059c064f01d86544823cb23b57715 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 19 Nov 2019 14:22:54 +0100 Subject: [PATCH 065/343] ENDC X2AP: Small modification at generation of SgNB Addition Request. --- openair2/RRC/NR/rrc_gNB.c | 11 +++++++---- openair2/X2AP/x2ap_eNB_generate_messages.c | 5 +++-- openair2/X2AP/x2ap_eNB_handler.c | 1 - 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5c23a13910..5222eecf36 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -347,10 +347,6 @@ if (fd != NULL) { } - - - - ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -452,6 +448,13 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); break; + /* Messages from X2AP */ + case X2AP_ENDC_SGNB_ADDITION_REQ: + LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n"); + rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); + break; + + default: LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p); break; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 1d67b6e9be..e709de5f41 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1538,6 +1538,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( CG_Config_Info.size = 4096; CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t)); int msg_len=fread(CG_Config_Info.buf,1,CG_Config_Info.size,fd); + CG_Config_Info.size = msg_len; /*char buffer[4096]; int msg_len=fread(buffer,1,4096,fd);*/ @@ -1647,9 +1648,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_MeNBtoSgNBContainer; - ie->value.choice.MeNBtoSgNBContainer.buf = (uint8_t *)calloc(4096, sizeof(uint8_t)); + ie->value.choice.MeNBtoSgNBContainer.buf = (uint8_t *)calloc(CG_Config_Info.size, sizeof(uint8_t)); memcpy(ie->value.choice.MeNBtoSgNBContainer.buf, CG_Config_Info.buf, CG_Config_Info.size); - ie->value.choice.MeNBtoSgNBContainer.size = 4096; + ie->value.choice.MeNBtoSgNBContainer.size = CG_Config_Info.size; //4096; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index feeaeaaeda..f107450c02 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1767,7 +1767,6 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size; - itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); return 0; From 96006201b9205b97ce89ca04766af3964f2c656b Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 19 Nov 2019 15:15:25 +0100 Subject: [PATCH 066/343] ENDC: Minor correction --- openair2/RRC/NR/rrc_gNB.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5222eecf36..3747d38c28 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -442,11 +442,6 @@ void *rrc_gnb_task(void *args_p) { LOG_I(NR_RRC, "[gNB %d] Received %s : %p\n", instance, msg_name_p,&NRRRC_CONFIGURATION_REQ(msg_p)); openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p)); break; - - case X2AP_ENDC_SGNB_ADDITION_REQ: - LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n"); - rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); - break; /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: From bc580bd6beb5aa7ca1bf3b57305db900fc846379 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 19 Nov 2019 16:45:04 +0100 Subject: [PATCH 067/343] ENDC: Correction at processing Addition request information --- openair2/RRC/NR/rrc_gNB.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3747d38c28..1dbcaaef7c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -300,24 +300,21 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_addition_req_t *m) { -FILE *fd; -fd = fopen("uecap.raw","r"); -if (fd != NULL) { - char buffer[4096]; - int msg_len=fread(buffer,1,4096,fd); - fclose(fd); -} - /*LOG_I(RRC,"Read in %d bytes for uecap\n",msg_len);*/ - - - LTE_UL_DCCH_Message_t *LTE_UL_DCCH_Message; + LTE_UL_DCCH_Message_t *LTE_UL_DCCH_Message = NULL; asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_LTE_UL_DCCH_Message, (void **)<E_UL_DCCH_Message, (uint8_t *)m->rrc_buffer, (int) m->rrc_buffer_size);//m->rrc_buffer_size); + +/* asn_dec_rval_t dec_rval = uper_decode( NULL, + &asn_DEF_LTE_UL_DCCH_Message, + (void **)<E_UL_DCCH_Message, + (uint8_t *)m->rrc_buffer, + (int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size); +*/ gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { From 5bda11024d2b98b65b70873b91b4b3a90e492ee1 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 4 Dec 2019 15:30:17 +0100 Subject: [PATCH 068/343] Enabling ITTI interactions between RRC and X2AP for the generation of sgb addition request ACK message at the gNB side --- openair2/COMMON/x2ap_messages_def.h | 1 + openair2/COMMON/x2ap_messages_types.h | 62 +++- openair2/RRC/NR/rrc_gNB_nsa.c | 13 + openair2/X2AP/x2ap_eNB.c | 48 +++ openair2/X2AP/x2ap_eNB_generate_messages.c | 9 + openair2/X2AP/x2ap_eNB_generate_messages.h | 2 + openair2/X2AP/x2ap_eNB_handler.c | 4 +- .../CONF/gnb.band78.slave.conf | 284 ++++++++++++++++++ 8 files changed, 411 insertions(+), 12 deletions(-) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index ed33abfbfd..ddc2b255a5 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -53,3 +53,4 @@ MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_sen /*SGnb bearer addition messages X2AP <-> RRC */ MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req) +MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t , x2ap_ENDC_sgnb_addition_req_ACK) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 6bbfc6efd7..8bcdfe9ea6 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -28,17 +28,18 @@ //-------------------------------------------------------------------------------------------// // Defines to access message fields. -#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req -#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req -#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp -#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req -#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack -#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf -#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind -#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release -#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel -#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req -#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req +#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req +#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req +#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp +#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req +#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack +#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf +#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind +#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release +#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel +#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req +#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req +#define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 @@ -343,5 +344,44 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { } x2ap_ENDC_sgnb_addition_req_t; +typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { + int ue_x2_id; + + /* used for RRC->X2AP in source eNB */ + int rnti; + + security_capabilities_t security_capabilities; + + /* SgNB Security Key */ + uint8_t kgnb[32]; + + /*next_hop_chaining_coun */ + long int kgnb_ncc; + + /* UE aggregate maximum bitrate */ + ambr_t ue_ambr; + + uint8_t nb_e_rabs_tobeadded; + + /* list of e_rab to be added by RRC layers */ + e_rab_tobe_added_t e_rabs_tobeadded[S1AP_MAX_E_RAB]; + + /* list of e_rab to be setup by RRC layers */ + e_rab_t e_rab_param[S1AP_MAX_E_RAB]; + + x2ap_lastvisitedcell_info_t lastvisitedcell_info; + + uint8_t rrc_buffer[4096 /* arbitrary, big enough */]; + int rrc_buffer_size; + + int target_assoc_id; + + /*long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; + long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; + long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;*/ + + +} x2ap_ENDC_sgnb_addition_req_ACK_t; + #endif /* X2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index e4c77a8f00..69080cdd20 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -104,6 +104,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ rrc_gNB_carrier_data_t *carrier=&rrc->carrier; + MessageDef *msg; + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = 2048; //Need to verify correct value for the buffer_size + // NR RRCReconfiguration AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n"); @@ -130,7 +134,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void*)CG_Config,0,sizeof(*CG_Config)); generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + // Send to X2 entity to transport to MeNB + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, + NULL, + (void *)CG_Config, + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size); + + + itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding rrc->Nb_ue++; // configure MAC and RLC diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 6d945626ee..2586d1aa63 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -446,6 +446,47 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack); } +static +void x2ap_eNB_handle_sgNB_add_req_ack(instance_t instance, + x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_ENDC_sgnb_addition_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 X2AP to identify eNodeBs + * RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in + * the configuration file) + * as far as I understand.. CROUX + */ + + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + /*int source_assoc_id = x2ap_ENDC_sgnb_addition_req_ACK->source_assoc_id; + int ue_id; + int id_source; + int id_target;*/ + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + /*target = x2ap_get_eNB(NULL, source_assoc_id, 0); + DevAssert(target != NULL);*/ + + // rnti is a new information, save it + + /*ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);*/ + + + //target = x2ap_get_eNB(NULL, 17, 0); + target = x2ap_is_eNB_id_in_list (3585); //Currently hardcoded. Need to extract it differently + DevAssert(target != NULL); + x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target, x2ap_ENDC_sgnb_addition_req_ACK, 0); +} + + static void x2ap_eNB_ue_context_release(instance_t instance, x2ap_ue_context_release_t *x2ap_ue_context_release) @@ -511,6 +552,13 @@ void *x2ap_task(void *arg) { &X2AP_UE_CONTEXT_RELEASE(received_msg)); break; + case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: + x2ap_eNB_handle_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(received_msg)); + LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n"); + + break; + case SCTP_INIT_MSG_MULTI_CNF: x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index e709de5f41..156bb1fc45 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1673,3 +1673,12 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( } +int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id) +{ + + return 0; + +} + + diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index dffe164c6c..9afcda6749 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -72,4 +72,6 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); +int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index f107450c02..75d5bac702 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1470,7 +1470,7 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - //return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); + x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); } @@ -1658,6 +1658,8 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + X2AP_INFO("X2AP Association id: %d \n",assoc_id); + instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf new file mode 100644 index 0000000000..b7ebb6ed8c --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -0,0 +1,284 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // 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: + + ssb_SubcarrierOffset = 0; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 642016; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 217; + #initialDownlinkBWP + #genericParameters + # this is RBstart=84,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13559; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=2,L=3 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 217; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13559; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#0 = 839, 1 = 139 + prach_RootSequenceIndex_PR = 1; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 255; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2 +; +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 2; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 0; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- 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.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.12.188"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.107/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.107/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.107/23"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +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_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "addr=192.168.20.2,mgmt_addr=192.168.20.2"; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #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"; + }; + From f0b7debefcb93b9f45a8c2bc099dcf8122b6ea82 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 13 Jun 2019 19:29:43 +0200 Subject: [PATCH 069/343] Extraction of common NR MAC data structures from NR_MAC_UE/mac.h and definition of MAC CE struct --- openair2/LAYER2/NR_MAC/nr_mac.h | 111 +++++++++++++++++++ openair2/LAYER2/NR_MAC_UE/mac.h | 67 +---------- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 1 + openair2/RRC/NR_UE/rrc_defs.h | 1 + 4 files changed, 114 insertions(+), 66 deletions(-) create mode 100644 openair2/LAYER2/NR_MAC/nr_mac.h diff --git a/openair2/LAYER2/NR_MAC/nr_mac.h b/openair2/LAYER2/NR_MAC/nr_mac.h new file mode 100644 index 0000000000..ce15d88c0c --- /dev/null +++ b/openair2/LAYER2/NR_MAC/nr_mac.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 nr_mac.h + * \brief common MAC data structures, constant, and function prototype + * \author R. Knopp, K.H. HSU, G. Casati + * \date 2019 + * \version 0.1 + * \company Eurecom / NTUST / Fraunhofer IIS + * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr, guido.casati@iis.fraunhofer.de + * \note + * \warning + */ + +#ifndef __LAYER2_NR_MAC_H__ +#define __LAYER2_NR_MAC_H__ + +#include +#include +#include + +#define NR_BCCH_DL_SCH 3 // SI + +#define NR_BCCH_BCH 5 // MIB + +typedef struct { + uint8_t LCID:6; // octet 1 [5:0] + uint8_t F:1; // octet 1 [6] + uint8_t R:1; // octet 1 [7] + uint8_t L:8; // octet 2 [7:0] +} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT; + +typedef struct { + uint8_t LCID:6; // octet 1 [5:0] + uint8_t F:1; // octet 1 [6] + uint8_t R:1; // octet 1 [7] + uint8_t L1:8; // octet 2 [7:0] + uint8_t L2:8; // octet 3 [7:0] +} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG; + +typedef struct { + uint8_t LCID:6; // octet 1 [5:0] + uint8_t R:2; // octet 1 [7:6] +} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED; + +// 38.321 ch. 6.1.3.4 +typedef struct { + uint8_t TA_COMMAND:6; // octet 1 [5:0] + uint8_t TAGID:2; // octet 1 [7:6] +} __attribute__ ((__packed__)) NR_MAC_CE_TA; + +// 38.321 ch6.2.1, 38.331 +#define DL_SCH_LCID_CCCH 0x00 +#define DL_SCH_LCID_SRB1 0x01 +#define DL_SCH_LCID_SRB2 0x02 +#define DL_SCH_LCID_SRB3 0x03 +#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F +#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30 +#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31 +#define DL_SCH_LCID_SP_SRS_ACTIVATION 0x32 +#define DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT 0x33 +#define DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH 0x34 +#define DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH 0x35 +#define DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL 0x36 +#define DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT 0X37 +#define DL_SCH_LCID_DUPLICATION_ACT 0X38 +#define DL_SCH_LCID_SCell_ACT_4_OCT 0X39 +#define DL_SCH_LCID_SCell_ACT_1_OCT 0X3A +#define DL_SCH_LCID_L_DRX 0x3B +#define DL_SCH_LCID_DRX 0x3C +#define DL_SCH_LCID_TA_COMMAND 0x3D +#define DL_SCH_LCID_CON_RES_ID 0x3E +#define DL_SCH_LCID_PADDING 0x3F + +#define UL_SCH_LCID_CCCH 0x00 +#define UL_SCH_LCID_SRB1 0x01 +#define UL_SCH_LCID_SRB2 0x02 +#define UL_SCH_LCID_SRB3 0x03 +#define UL_SCH_LCID_CCCH_MSG3 0x21 +#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 +#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 +#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 +#define UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT 0x38 +#define UL_SCH_LCID_SINGLE_ENTRY_PHR 0x39 +#define UL_SCH_LCID_C_RNTI 0x3A +#define UL_SCH_LCID_S_TRUNCATED_BSR 0x3B +#define UL_SCH_LCID_L_TRUNCATED_BSR 0x3C +#define UL_SCH_LCID_S_BSR 0x3D +#define UL_SCH_LCID_L_BSR 0x3E +#define UL_SCH_LCID_PADDING 0x3F + + +#endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac.h b/openair2/LAYER2/NR_MAC_UE/mac.h index fe8e91500a..9418511adf 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac.h +++ b/openair2/LAYER2/NR_MAC_UE/mac.h @@ -37,10 +37,6 @@ #include #include -#define NR_BCCH_DL_SCH 3 // SI - -#define NR_BCCH_BCH 5 // MIB - /*!\brief UE layer 2 status */ typedef enum { UE_CONNECTION_OK = 0, @@ -49,65 +45,4 @@ typedef enum { UE_PHY_HO_PRACH } NR_UE_L2_STATE_t; -typedef struct { - uint8_t LCID:6; // octet 1 [5:0] - uint8_t F:1; // octet 1 [6] - uint8_t R:1; // octet 1 [7] - uint8_t L:8; // octet 2 [7:0] -} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT; - -typedef struct { - uint8_t LCID:6; // octet 1 [5:0] - uint8_t F:1; // octet 1 [6] - uint8_t R:1; // octet 1 [7] - uint8_t L1:8; // octet 2 [7:0] - uint8_t L2:8; // octet 3 [7:0] -} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG; - -typedef struct { - uint8_t LCID:6; // octet 1 [5:0] - uint8_t R:2; // octet 1 [7:6] -} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED; - -// 38.321 ch6.2.1, 38.331 -#define DL_SCH_LCID_CCCH 0x00 -#define DL_SCH_LCID_SRB1 0x01 -#define DL_SCH_LCID_SRB2 0x02 -#define DL_SCH_LCID_SRB3 0x03 -#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F -#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30 -#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31 -#define DL_SCH_LCID_SP_SRS_ACTIVATION 0x32 -#define DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT 0x33 -#define DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH 0x34 -#define DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH 0x35 -#define DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL 0x36 -#define DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT 0X37 -#define DL_SCH_LCID_DUPLICATION_ACT 0X38 -#define DL_SCH_LCID_SCell_ACT_4_OCT 0X39 -#define DL_SCH_LCID_SCell_ACT_1_OCT 0X3A -#define DL_SCH_LCID_L_DRX 0x3B -#define DL_SCH_LCID_DRX 0x3C -#define DL_SCH_LCID_TA_COMMAND 0x3D -#define DL_SCH_LCID_CON_RES_ID 0x3E -#define DL_SCH_LCID_PADDING 0x3F - -#define UL_SCH_LCID_CCCH 0x00 -#define UL_SCH_LCID_SRB1 0x01 -#define UL_SCH_LCID_SRB2 0x02 -#define UL_SCH_LCID_SRB3 0x03 -#define UL_SCH_LCID_CCCH_MSG3 0x21 -#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 -#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 -#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 -#define UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT 0x38 -#define UL_SCH_LCID_SINGLE_ENTRY_PHR 0x39 -#define UL_SCH_LCID_C_RNTI 0x3A -#define UL_SCH_LCID_S_TRUNCATED_BSR 0x3B -#define UL_SCH_LCID_L_TRUNCATED_BSR 0x3C -#define UL_SCH_LCID_S_BSR 0x3D -#define UL_SCH_LCID_L_BSR 0x3E -#define UL_SCH_LCID_PADDING 0x3F - - -#endif /*__LAYER2_MAC_DEFS_H__ */ +#endif /*__LAYER2_NR_UE_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 6b9e79d510..5d7a2dca29 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -31,6 +31,7 @@ */ #include "mac_proto.h" +#include "LAYER2/NR_MAC/nr_mac.h" #include "mac_extern.h" #include "RRC/NR_UE/rrc_proto.h" #include "assertions.h" diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index af8971e5ed..ff4145ece3 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -40,6 +40,7 @@ #include "platform_types.h" #include "LAYER2/NR_MAC_UE/mac.h" +#include "LAYER2/NR_MAC/nr_mac.h" #include "rrc_list.h" #include "NR_asn_constant.h" #include "NR_MeasConfig.h" From 310efee7f26b950112218e04cae428798739d4f0 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 13 Jun 2019 17:46:29 +0200 Subject: [PATCH 070/343] Implementation of TA procedures at MAC layer for gNB and UE - Initial gNB DLSCH and UE spec scheduling implentation - MAC PDU generation (including header as per TS 38.321) - MAC PDU processing at UE side with extracion of TA updates - General code cleanup - Introduced NR MAC COMMON folder, moved common files here --- cmake_targets/CMakeLists.txt | 3 +- executables/nr-gnb.c | 2 +- executables/nr-ru.c | 2 +- openair1/SCHED_NR/nr_ru_procedures.c | 2 +- openair1/SCHED_NR_UE/defs.h | 8 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 119 +++++-- openair2/LAYER2/MAC/mac_extern.h | 6 - .../LAYER2/{NR_MAC => NR_MAC_COMMON}/nr_mac.h | 25 ++ .../nr_mac_common.c | 0 openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h | 73 ++++ openair2/LAYER2/NR_MAC_UE/mac_extern.h | 4 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 18 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 235 ++++++++++++- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 12 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 2 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 330 ++++++++++++++++++ .../NR_MAC_gNB/gNB_scheduler_primitives.c | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 14 + openair2/LAYER2/NR_MAC_gNB/main.c | 5 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 8 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 2 +- openair2/RRC/NR/nr_rrc_common.c | 2 +- openair2/RRC/NR_UE/rrc_defs.h | 2 +- 23 files changed, 812 insertions(+), 64 deletions(-) rename openair2/LAYER2/{NR_MAC => NR_MAC_COMMON}/nr_mac.h (78%) rename openair2/LAYER2/{NR_MAC_gNB => NR_MAC_COMMON}/nr_mac_common.c (100%) create mode 100644 openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h create mode 100644 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 273aad0c20..de3a08f2e0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1641,6 +1641,7 @@ set (MAC_NR_SRC ${NR_MAC_DIR}/config.c ${NR_MAC_DIR}/gNB_scheduler.c ${NR_MAC_DIR}/gNB_scheduler_bch.c + ${NR_MAC_DIR}/gNB_scheduler_dlsch.c ${NR_MAC_DIR}/gNB_scheduler_primitives.c ${NR_MAC_DIR}/gNB_scheduler_phytest.c ) @@ -1713,7 +1714,7 @@ add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) -add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ) +add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ) include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE") include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE") diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index b4bf5efe81..8cf64318cb 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -63,7 +63,7 @@ #include "LAYER2/MAC/mac.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/MAC/mac_proto.h" #include "RRC/LTE/rrc_extern.h" #include "PHY_INTERFACE/phy_interface.h" diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 1abcd3b7a1..a9565abd17 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -72,7 +72,7 @@ #include "SCHED_NR/sched_nr.h" #include "LAYER2/MAC/mac.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/MAC/mac_proto.h" #include "RRC/LTE/rrc_extern.h" #include "PHY_INTERFACE/phy_interface.h" diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index e726bdc711..7f8dc9853b 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -38,7 +38,7 @@ #include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/MAC/mac.h" #include "common/utils/LOG/log.h" #include "common/utils/system.h" diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 8e42149add..cbcb936be3 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -289,7 +289,13 @@ uint16_t nr_get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1); 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); +/*! \brief Compute the timing adjustment at UE side from the old TA offset and the new received TA command + @param Mod_id Local UE index on which to act + @param CC_id Component Carrier Index + @param timing_advance TA command + @param mu numerology index (0,1,2..) +*/ +void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t timing_advance, uint8_t mu); 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); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 60378d81fc..2ad57beba9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -21,11 +21,11 @@ /*! \file phy_procedures_nr_ue.c * \brief Implementation of UE procedures from 36.213 LTE specifications - * \author R. Knopp, F. Kaltenberger, N. Nikaein, A. Mico Pereperez + * \author R. Knopp, F. Kaltenberger, N. Nikaein, A. Mico Pereperez, G. Casati * \date 2018 * \version 0.1 * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de * \note * \warning */ @@ -421,22 +421,6 @@ void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,ui LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance); #endif -} - -void nr_process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance) -{ - - // uint32_t frame = PHY_vars_UE_g[Mod_id]->frame; - - // timing advance has Q1.5 format - timing_advance = timing_advance - 31; - - PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!! - - - LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); - - } uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id) @@ -1560,6 +1544,19 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR #endif + +void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing_advance, uint8_t mu){ + + // 3GPP TS 38.213 p4.2 + + int factor_mu = 1 << mu; + + PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * 1024 / factor_mu ; + + + LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value is %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); +} + void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, @@ -3361,7 +3358,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol; uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols; - LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); + LOG_I(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); for (m = s0; m < (s1 + s0); m++) { @@ -3528,7 +3525,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; int ret=0, ret1=0; - //int CC_id = ue->CC_id; + uint8_t CC_id = ue->CC_id; NR_UE_PDSCH *pdsch_vars; uint8_t is_cw0_active = 0; uint8_t is_cw1_active = 0; @@ -3800,11 +3797,89 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication); } - } + // TODO CRC check for CW0 + // Check CRC for CW 0 + /*if (ret == (1+dlsch0->max_turbo_iterations)) { + *dlsch_errors=*dlsch_errors+1; + if(dlsch0->rnti != 0xffff){ + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + } + } else { + if(dlsch0->rnti != 0xffff){ + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + } + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ + int j; + LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid); + for (j=0; jharq_processes[dlsch0->current_harq_pid]->TBS>>3; j++) + LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]); + LOG_T(PHY,"\n"); + }*/ + if (ue->mac_enabled == 1) { + switch (pdsch) { + case PDSCH: + printf("PDSCH procedures\n"); + nr_ue_send_sdu(ue->Mod_id, + CC_id, + frame_rx, + nr_tti_rx, + dlsch0->harq_processes[harq_pid]->b, + dlsch0->harq_processes[harq_pid]->TBS>>3, + eNB_id); + break; + case SI_PDSCH: + /*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);*/ + break; + case P_PDSCH: + /*ue_decode_p(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);*/ + break; + case RA_PDSCH: + /*process_rar(ue,proc,eNB_id,mode,abstraction_flag);*/ + break; + case PDSCH1: + /*LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n"); + AssertFatal(1==0,"exiting");*/ + break; + case PMCH: + /*LOG_E(PHY,"Shouldn't have PMCH here\n"); + AssertFatal(1==0,"exiting");*/ + break; + } + } + + /*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; + ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; + }*/ + + // TODO CRC check for CW1 + + } } @@ -4132,6 +4207,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, uint8_t do_pdcch_flag, runmode_t mode) { + int l,l2; + int pilot1; int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; int slot_pbch; diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index 3510e7e7ae..dbf5b57b6b 100644 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -34,7 +34,6 @@ //#include "PHY/defs_common.h" #include "mac.h" - #include "RRC/LTE/rrc_defs.h" extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; @@ -51,13 +50,9 @@ extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; extern UE_RRC_INST *UE_rrc_inst; extern UE_MAC_INST *UE_mac_inst; - extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 - - - extern unsigned char NB_INST; extern unsigned char NB_eNB_INST; extern uint16_t NB_UE_INST; @@ -65,7 +60,6 @@ extern uint16_t NB_THREAD_INST; extern unsigned char NB_RN_INST; extern unsigned short NODE_ID[1]; - extern int cqi_to_mcs[16]; extern uint32_t RRC_CONNECTION_FLAG; diff --git a/openair2/LAYER2/NR_MAC/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h similarity index 78% rename from openair2/LAYER2/NR_MAC/nr_mac.h rename to openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index ce15d88c0c..acb63ea4dc 100644 --- a/openair2/LAYER2/NR_MAC/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -41,6 +41,31 @@ #define NR_BCCH_BCH 5 // MIB +// For both DL/UL-SCH +// Except: +// - UL/DL-SCH: fixed-size MAC CE(known by LCID) +// - UL/DL-SCH: padding +// - UL-SCH: MSG3 48-bits +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// | L | + +// For both DL/UL-SCH +// For: +// - UL/DL-SCH: fixed-size MAC CE(known by LCID) +// - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) +// - UL-SCH: MSG3 48-bits +// |0|1|2|3|4|5|6|7| bit-wise +// |R|R| LCID | +// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; +// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; +// F: lenght of L is 0:8 or 1:16 bits wide +// R: Reserved bit, set to zero. + typedef struct { uint8_t LCID:6; // octet 1 [5:0] uint8_t F:1; // octet 1 [6] diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c similarity index 100% rename from openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c rename to openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h new file mode 100644 index 0000000000..10df4567c4 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -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 + */ + +/*! \file extern.h +* \brief NR mac externs +* \author G. Casati +* \date 2019 +* \version 1.0 +* \email guido.casati@iis.fraunhofer.de +* @ingroup _mac + +*/ + +#ifndef __NR_MAC_EXTERN_H__ +#define __NR_MAC_EXTERN_H__ + +//#include "PHY/defs_common.h" +#include "nr_mac.h" +#include "RRC/LTE/rrc_defs.h" +#include "common/ran_context.h" + +/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; +extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE]; +extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; +extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; +extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; +extern UE_RRC_INST *UE_rrc_inst; +extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 +extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 +extern int cqi_to_mcs[16]; +extern uint32_t RRC_CONNECTION_FLAG; +extern uint8_t rb_table[34]; +extern mac_rlc_am_muilist_t rlc_am_mui; +extern SCHEDULER_MODES global_scheduler_mode; +extern unsigned char NB_UE_INST;*/ + +extern unsigned char NB_INST; +extern unsigned char NB_eNB_INST; +extern unsigned char NB_RN_INST; +extern unsigned short NODE_ID[1]; + +/* Scheduler */ +extern RAN_CONTEXT_t RC; +extern int phy_test; +extern uint8_t nfapi_mode; + +/*#if defined(PRE_SCD_THREAD) +extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +extern uint8_t dlsch_ue_select_tbl_in_use; +extern uint8_t new_dlsch_ue_select_tbl_in_use; +extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; +extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +#endif*/ + +#endif //DEF_H diff --git a/openair2/LAYER2/NR_MAC_UE/mac_extern.h b/openair2/LAYER2/NR_MAC_UE/mac_extern.h index 960b47e44a..26e0ea2667 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_extern.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_extern.h @@ -30,6 +30,10 @@ * \warning */ +#include "mac_defs.h" + +//extern NR_UE_MAC_INST_t *UE_mac_inst; + // Type0-PDCCH search space extern const int32_t table_38213_13_1_c2[16]; extern const int32_t table_38213_13_1_c3[16]; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 98389ddcfd..6cbe7b32c4 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -125,16 +125,28 @@ uint32_t get_ssb_slot(uint32_t ssb_index); uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe); + +/* \brief Get payload (MAC PDU) from UE PHY +@param module_idP Instance id of UE in machine +@param CC_id Component Carrier index +@param frameP Current Rx frame +@param ttiP Current Rx tti subframe +@param pdu Pointer to the MAC PDU +@param pdu_len Length of the MAC PDU +@param eNB_id Index of eNB that UE is attached to +@returns void +*/ +void nr_ue_send_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP, uint8_t ttiP, + uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index); + void nr_ue_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, uint8_t *pduP, - uint16_t mac_pdu_len, + uint16_t mac_pdu_len, uint8_t eNB_index); int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len); -void nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP, uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index); - #endif /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5d7a2dca29..57b418f945 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -21,23 +21,41 @@ /* \file ue_procedures.c * \brief procedures related to UE - * \author R. Knopp, K.H. HSU + * \author R. Knopp, K.H. HSU, G. Casati * \date 2018 * \version 0.1 * \company Eurecom / NTUST - * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr + * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr, guido.casati@iis.fraunhofer.de * \note * \warning */ +/* MAC related headers */ #include "mac_proto.h" -#include "LAYER2/NR_MAC/nr_mac.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac.h" #include "mac_extern.h" +//#include "LAYER2/MAC/mac_vars.h" // TODO Note that mac_vars.h is not NR specific and this should be updated + // also, the use of the same should be updated in nr-softmodem and nr-uesoftmodem + +/* PHY UE related headers*/ +#include "SCHED_NR_UE/defs.h" + #include "RRC/NR_UE/rrc_proto.h" #include "assertions.h" #include "PHY/defs_nr_UE.h" + +/*Openair Packet Tracer */ +#include "UTIL/OPT/opt.h" +#include "OCG.h" + +/* log utils */ #include "common/utils/LOG/log.h" -#include "openair2/LAYER2/MAC/mac.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +/* TODO remove this for debugging purpose +#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include "LAYER2/MAC/mac.h" +*/ #include #include @@ -2025,21 +2043,88 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e return 0; } +void nr_ue_send_sdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t ttiP, + uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index){ + + printf("nr_ue_send_sdu frame %d\n", frameP); + + // Changes wrt LTE: replaced subframeP with ttiP + // TODO double check this and eventually create a type for TTI (tti_t) + // Note: pdu_len was previously named sdu and sdu_len + + uint8_t * pduP = pdu; + NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); + + /* + #if UE_TIMING_TRACE + start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); + #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]); + + if (opt_enabled) { + trace_pdu(DIRECTION_DOWNLINK, pduP, pdu_len, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP + 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].cs_RNTI, pdu_len); + } + + /* + #ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n", + module_idP, frameP, eNB_index, num_ce, num_sdu); + #endif + */ + + /* + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + for (i = 0; i < 32; i++) { + LOG_T(MAC, "%x.", sdu[i]); + } + LOG_T(MAC, "\n"); + #endif + */ + + // Processing MAC PDU + // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs + nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); + + /* + #if UE_TIMING_TRACE + stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); + #endif + */ +} void nr_ue_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, uint8_t *pduP, - uint16_t mac_pdu_len, + uint16_t mac_pdu_len, uint8_t eNB_index){ + // This function is adapting code from the old + // parse_header(...) and ue_send_sdu(...) functions of OAI LTE + uint8_t *pdu_ptr = pduP; - uint16_t pdu_len = mac_pdu_len; + int pdu_len = mac_pdu_len; uint16_t mac_ce_len; uint16_t mac_subheader_len; uint16_t mac_sdu_len; + NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); + uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; + // For both DL/UL-SCH // Except: // - UL/DL-SCH: fixed-size MAC CE(known by LCID) @@ -2067,12 +2152,16 @@ void nr_ue_process_mac_pdu( uint8_t done = 0; - while (!done || pdu_len <= 0){ - mac_ce_len = 0x0000; - mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct - mac_sdu_len = 0x0000; + while (!done && pdu_len > 0){ + mac_ce_len = 0; + mac_subheader_len = 1; // default to fixed-length subheader = 1-oct + mac_sdu_len = 0; switch(((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID){ // MAC CE + + /*#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); + #endif*/ case DL_SCH_LCID_CCCH: // MSG4 RRC Connection Setup 38.331 // varialbe length @@ -2082,8 +2171,29 @@ void nr_ue_process_mac_pdu( mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; mac_subheader_len = 3; } + + /*LOG_D(MAC, "[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n", + module_idP, UE_mac_inst[module_idP].crnti, frameP, eNB_index, rx_lengths[i]);*/ + + /*#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + int j; + for (j = 0; j < rx_lengths[i]; j++) { + LOG_T(MAC, "%x.", (uint8_t) payload_ptr[j]); + } + LOG_T(MAC, "\n"); + #endif*/ + + /*mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP, subframeP, + UE_mac_inst[module_idP].crnti, + CCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], eNB_index, 0);*/ break; + case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH: + // 38.321 Ch6.1.3.14 // varialbe length mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; @@ -2169,10 +2279,70 @@ void nr_ue_process_mac_pdu( case DL_SCH_LCID_TA_COMMAND: // 38.321 Ch6.1.3.4 mac_ce_len = 1; + + uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND; + + uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID; + + /* + #ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pdu_ptr[1]); + #endif + */ + + LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ta_command, tag_id, CC_id); + + //if (nfapi_mode!=3){ // TODO check nfapi_mode + nr_process_timing_advance(module_idP, CC_id, ta_command, scs); + //} + break; case DL_SCH_LCID_CON_RES_ID: // 38.321 Ch6.1.3.3 mac_ce_len = 6; + + // TODO index should be shifted by 1 + // LOG_I(MAC,"[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5]); + + // TODO RACH is missing + + /*if (UE_mac_inst[module_idP].RA_active == 1) { + LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", + module_idP, frameP); + UE_mac_inst[module_idP].RA_active = 0; + // check if RA procedure has finished completely (no contention) + tx_sdu = &UE_mac_inst[module_idP].CCCH_pdu.payload[3]; + + //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits) + // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or SCH_SUBHEADER_SHORT) + for (i = 0; i < 6; i++) + if (tx_sdu[i] != payload_ptr[i]) { + LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP); + if(nfapi_mode == 3) { // phy_stub mode + // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to + // PRACH state. + LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n"); + UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH; + //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + } + else{ + ra_failed(module_idP, CC_id, eNB_index); + } + UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); + return; + } + LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n", module_idP, frameP); + UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + if(nfapi_mode == 3){ + // phy_stub mode + // Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH + UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH; + } else { // Full stack mode + ra_succeeded(module_idP,CC_id,eNB_index); + } + }*/ + break; case DL_SCH_LCID_PADDING: done = 1; @@ -2180,25 +2350,62 @@ void nr_ue_process_mac_pdu( break; // MAC SDU + /* TODO double check SRBs 1-3 & DRB 1-3 */ + case DL_SCH_LCID_SRB1: - // check if LCID is valid at current time. + // check if LCID is valid at current time. + + /*if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) { + + LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", + module_idP, frameP, rx_lcids[i], eNB_index, rx_lengths[i]); + + mac_rlc_data_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, ENB_FLAG_NO, + MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); + } else if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1)) { + LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", + module_idP, frameP, rx_lcids[i], eNB_index, rx_lengths[i]); + + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + int j; + for (j = 0; j < rx_lengths[i]; j++) + LOG_T(MAC, "%x.", (unsigned char) payload_ptr[j]); + LOG_T(MAC, "\n"); + #endif + + mac_rlc_data_ind(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + rx_lcids[i], + (char *) payload_ptr, rx_lengths[i], 1, NULL); + }*/ + case UL_SCH_LCID_SRB2: // check if LCID is valid at current time. case UL_SCH_LCID_SRB3: // check if LCID is valid at current time. default: // check if LCID is valid at current time. - mac_sdu_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; mac_subheader_len = 3; + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); + + } else { + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; } + // DRB LCID by RRC break; } pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n"); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index e43f2633b1..fb5f9eccf1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -33,9 +33,10 @@ #include "assertions.h" #include "LAYER2/MAC/mac.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/MAC/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" + #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" @@ -64,10 +65,6 @@ #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 -extern RAN_CONTEXT_t RC; -extern int phy_test; -extern uint8_t nfapi_mode; - uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; void clear_nr_nfapi_information(gNB_MAC_INST * gNB, @@ -375,11 +372,12 @@ 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_ue_spec(module_idP, frame_txP, slot_txP); nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 8dbdbc93fa..df3e04dccf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -33,7 +33,7 @@ #include "assertions.h" #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c new file mode 100644 index 0000000000..a53f09939b --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -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 + */ + +/*! \file gNB_scheduler_dlsch.c + * \brief procedures related to gNB for the DLSCH transport channel + * \author Guido Casati + * \date 2019 + * \email: guido.casati@iis.fraunhofe.de + * \version 1.0 + * @ingroup _mac + + */ + +/*PHY*/ +#include "PHY/CODING/coding_defs.h" +#include "PHY/defs_nr_common.h" +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" +/*MAC*/ +#include "LAYER2/NR_MAC_COMMON/nr_mac.h" +#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" +#include "LAYER2/MAC/mac.h" + +/*NFAPI*/ +#include "nfapi_nr_interface.h" +/*TAG*/ +#include "NR_TAG-Id.h" + + +int nr_generate_dlsch_pdu(unsigned char *sdus_payload, + unsigned char *mac_pdu, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + NR_TAG_Id_t tag_id, + unsigned char *ue_cont_res_id, + unsigned short post_padding){ + + NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; + unsigned char * dlsch_buffer_ptr = sdus_payload; + uint8_t last_size = 0; + int offset = 0, mac_ce_size, i; + + // MAC CEs + uint8_t mac_header_control_elements[16], *ce_ptr; + ce_ptr = &mac_header_control_elements[0]; + + // 1) Compute MAC CE and related subheaders + + // DRX command subheader (MAC CE size 0) + if (drx_cmd != 255) { + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = DL_SCH_LCID_DRX; + //last_size = 1; + mac_pdu_ptr++; + } + + // Timing Advance subheader + if (timing_advance_cmd != 31) { + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND; + //last_size = 1; + mac_pdu_ptr++; + + // TA MAC CE (1 octet) + AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; + + LOG_D(MAC, "NR MAC CE timing advance command =%d (%d) TAG ID =%d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id); + mac_ce_size = sizeof(NR_MAC_CE_TA); + + // Copying bytes for MAC CEs to the mac pdu pointer + memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); + ce_ptr += mac_ce_size; + mac_pdu_ptr += (unsigned char) mac_ce_size; + } + + // Contention resolution fixed subheader and MAC CE + if (ue_cont_res_id) { + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = DL_SCH_LCID_CON_RES_ID; + mac_pdu_ptr++; + //last_size = 1; + + // contention resolution identity MAC ce has a fixed 48 bit size + // this contains the UL CCCH SDU. If UL CCCH SDU is longer than 48 bits, + // it contains the first 48 bits of the UL CCCH SDU + LOG_T(MAC, "[gNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], + ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); + + // Copying bytes (6 octects) to CEs pointer + mac_ce_size = 6; + memcpy(ce_ptr, ue_cont_res_id, mac_ce_size); + + // Copying bytes for MAC CEs to mac pdu pointer + memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); + ce_ptr += mac_ce_size; + mac_pdu_ptr += (unsigned char) mac_ce_size; + } + + + // 2) Generation of DLSCH MAC SDU subheaders + for (i = 0; i < num_sdus; i++) { + LOG_D(MAC, "[gNB] Generate DLSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]); + + if (sdu_lengths[i] < 128) { + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; + last_size = 2; + } else { + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; + last_size = 3; + } + + mac_pdu_ptr += last_size; + + // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in + memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]); + dlsch_buffer_ptr+= sdu_lengths[i]; + mac_pdu_ptr += sdu_lengths[i]; + } + + // 4) Compute final offset for padding + if (post_padding > 0) { + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING; + mac_pdu_ptr++; + + // compute final offset + offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); + + } else { + // no MAC subPDU with padding + } + + //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu)); + + return offset; +} + +/*TODO expand the scheduling functionalities +this function is just generating a dummy MAC PDU and is used to transmit the TA +The structure of the algorithm is taken from the schedule_ue_spec function in LTE +and is preserved for future reference.*/ +void +nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ + + + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + UE_list_t *UE_list = &gNB->UE_list; + nfapi_nr_dl_config_request_body_t *dl_req; + + // TODO size corretly the arrays + // at present, preserved the array length from lte code + // however not sure why NR_MAX_NB_RB was used here + unsigned char sdu_lcids[NR_MAX_NB_RB] = {0}; + uint16_t sdu_lengths[NR_MAX_NB_RB] = {0}; + + int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; + int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0; + + // hardcoded parameters + // for DMRS configuration type 1 + // sdus should come from RLC + static unsigned char dlsch_buffer[MAX_NR_DLSCH_PAYLOAD_BYTES]; + uint8_t Qm = 2; + uint16_t R = 697; + uint16_t nb_rb = 50 ; + uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs + int ta_update = 17; + NR_TAG_Id_t tag_id = 0; + int UE_id = 0; // UE_list->head is -1 ! + + UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP] + 1; CC_id++) { + LOG_D(MAC, "doing nr_schedule_ue_spec for CC_id %d\n", CC_id); + dl_req = &gNB->DL_req[CC_id].dl_config_request_body; + + //for (UE_id = UE_list->head; UE_id >= -1; UE_id = UE_list->next[UE_id]) { + + /* + //process retransmission + if (round != 8) { + + } else { // This is a potentially new SDU opportunity */ + + if (gNB->tag->timeAlignmentTimer != NULL) { + if (gNB->tag->timeAlignmentTimer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) + ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } + } + + ta_len = (ta_update != 31) ? 2 : 0; + + // retrieve TAG ID + if(gNB->tag->tag_Id != NULL ){ + tag_id = gNB->tag->tag_Id; + } + + // fill dlsch_buffer with random data + for (i = 0; i < MAX_NR_DLSCH_PAYLOAD_BYTES; i++){ + dlsch_buffer[i] = (unsigned char) rand(); + } + + /* + //Sending SDUs with size 1 + //Initialize elements of sdu_lcids and sdu_lengths + //TODO this will be eventually be removed + for (j = 0; j < NB_RB_MAX; j++){ + sdu_lcids[j] = 0x05; // DRB + } + + for (k = 0; k < NB_RB_MAX; k++){ + sdu_lengths[k] = 1; + header_length_total += 2; + sdu_length_total += 1; + }*/ + + //Sending SDUs with size 1 + //Initialize elements of sdu_lcids and sdu_lengths + //TODO this will be eventually be removed + while (TBS - header_length_total - sdu_length_total - ta_len >= 3){ + if (k < NR_MAX_NB_RB && j < NR_MAX_NB_RB){ + sdu_lcids[j] = 0x05; // DRB + sdu_lengths[k] = 1; + header_length_total += 2; + sdu_length_total += 1; + num_sdus +=1; + k++, j++; + } + else { + break; + } + } + + /* + // RLC data on DCCH + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + } + + // RLC data on DCCH1 + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + } + + // looping over lcid + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // here sdu_lcids[num_sdus] is populated + }*/ + + // there is at least one SDU or TA command + // if (num_sdus > 0 ){ + if (ta_len + sdu_length_total + header_length_total > 0) { + + // Check if there is data from RLC or CE + if (TBS - header_length_total - sdu_length_total - ta_len >= 2) { + // we have to consider padding + // padding param currently not in use + padding = TBS - header_length_total - sdu_length_total - ta_len - 1; + post_padding = 1; + } else { + post_padding = 0; + } + + + offset = nr_generate_dlsch_pdu((unsigned char *) dlsch_buffer, + (unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + num_sdus, //num_sdus + sdu_lengths, + sdu_lcids, + 255, // no drx + ta_update, // timing advance + tag_id, + NULL, // contention res id + post_padding); + // Padding: fill remainder of DLSCH with 0 + if (post_padding > 0){ + for (int j = 0; j < (TBS - offset); j++) + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + j] = 0; + } + + // Printing bit by bit for debugging purpose + /*for (int k = 0; k < TBS; k++){ + printf("MAC PDU %u\n",((( UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][k/8]) & (1 << (k & 7))) >> (k & 7))); + if ((k+1)%8 == 0) + printf("\n"); + }*/ + + } + else { // There is no data from RLC or MAC header, so don't schedule + } + //} + //} // UE_id loop + } // CC_id loop +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d746756d65..92ba958519 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -34,7 +34,7 @@ #include "LAYER2/MAC/mac.h" #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/utils/LOG/log.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d56d5d28c1..451bac8042 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -33,6 +33,7 @@ #include "nr_mac_gNB.h" #include "PHY/defs_gNB.h" +#include "NR_TAG-Id.h" void set_cset_offset(uint16_t); @@ -70,6 +71,19 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_txP, sub_frame_t slot_txP, frame_t frame_rxP, sub_frame_t slot_rxP); +int nr_generate_dlsch_pdu(unsigned char *sdus_payload, + unsigned char *mac_pdu, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + NR_TAG_Id_t tag_id, + unsigned char *ue_cont_res_id, + unsigned short post_padding); + +void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); + void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); void nr_schedule_css_dlsch_phytest(module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 88f6c38758..1482f9bf35 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -31,7 +31,7 @@ */ #include "mac_proto.h" -#include "LAYER2/MAC/mac_extern.h" //temporary +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "assertions.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" @@ -106,6 +106,9 @@ void mac_top_init_gNB(void) RC.nrmac[i]->Mod_id = i; + RC.nrmac[i]->tag = (NR_TAG_t*)malloc(sizeof(NR_TAG_t)); + memset((void*)RC.nrmac[i]->tag,0,sizeof(NR_TAG_t)); + for (j = 0; j < MAX_NUM_CCs; j++) { RC.nrmac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j]; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7633279579..170fb5d440 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -55,12 +55,14 @@ #include "common/ran_context.h" #include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac_proto.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "PHY/defs_gNB.h" #include "PHY/TOOLS/time_meas.h" #include "targets/ARCH/COMMON/common_lib.h" +#include "NR_TAG.h" + /*! \brief gNB common channels */ typedef struct { int physCellId; @@ -107,7 +109,9 @@ typedef struct gNB_MAC_INST_s { /// frame counter frame_t frame; /// slot counter - int slot; + int slot; + /// timing advance group + NR_TAG_t *tag; /// Pointer to IF module instance for PHY NR_IF_Module_t *if_inst; /// Common cell resources diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 4c9804bdc0..e446ab3a95 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -34,7 +34,7 @@ #include "openair1/PHY/phy_extern.h" #include "openair1/SCHED_NR/fapi_nr_l1.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/MAC/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/ran_context.h" diff --git a/openair2/RRC/NR/nr_rrc_common.c b/openair2/RRC/NR/nr_rrc_common.c index f5ab3f2366..daa9663ca8 100644 --- a/openair2/RRC/NR/nr_rrc_common.c +++ b/openair2/RRC/NR/nr_rrc_common.c @@ -29,7 +29,7 @@ */ #include "nr_rrc_extern.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "COMMON/openair_defs.h" #include "COMMON/platform_types.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index ff4145ece3..e2b22ef243 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -40,7 +40,7 @@ #include "platform_types.h" #include "LAYER2/NR_MAC_UE/mac.h" -#include "LAYER2/NR_MAC/nr_mac.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac.h" #include "rrc_list.h" #include "NR_asn_constant.h" #include "NR_MeasConfig.h" From 6ec89bec1f02274b3bef108a95639271a357d310 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 26 Aug 2019 17:37:49 +0200 Subject: [PATCH 071/343] Bugfix: header from NR included in LTE UE PHY procedures --- openair1/SCHED_UE/phy_procedures_lte_ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index e67735de71..2973473c5a 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -37,7 +37,7 @@ e@ieee.org #include "assertions.h" #include "PHY/defs_UE.h" #include "PHY/phy_extern_ue.h" -#include "executables/nr-uesoftmodem.h" +//#include "executables/nr-uesoftmodem.h" #include "targets/RT/USER/lte-softmodem.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" From 825ae3c06db4ad9a70ae4fc4bf9684e6329faf3a Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 29 Aug 2019 16:42:29 +0200 Subject: [PATCH 072/343] Integration PHY and MAC procedures for Timing Advance updates. Compilation and run is OK. TA updates need further fixes as not working as expected. - "nr_process_timing_advance": TA to be applied is commented out, need to be uncommented - with introduced delay of 50 in rx_rf, TA update should be 34 in MAC CE but this does not occur when ta is applied at UE side according to standard - introduced ULSCH scheduler and NR RX SDU functions - fixes to logic in UL fill RX indication - added crc indication in UL RX - temporary hardcoded UE_id to 0, rnti not considered in the logic --- cmake_targets/CMakeLists.txt | 1 + openair1/SCHED_NR/fapi_nr_l1.h | 2 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 35 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 7 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 18 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 1933 +++++++++++++++++ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 22 + openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 44 +- 9 files changed, 2032 insertions(+), 34 deletions(-) create mode 100644 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index de3a08f2e0..bf90a996b5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1642,6 +1642,7 @@ set (MAC_NR_SRC ${NR_MAC_DIR}/gNB_scheduler.c ${NR_MAC_DIR}/gNB_scheduler_bch.c ${NR_MAC_DIR}/gNB_scheduler_dlsch.c + ${NR_MAC_DIR}/gNB_scheduler_ulsch.c ${NR_MAC_DIR}/gNB_scheduler_primitives.c ${NR_MAC_DIR}/gNB_scheduler_phytest.c ) diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index 51169660bf..57ecdc86bb 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -46,3 +46,5 @@ void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, uint8_t *sdu); void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid); + +void nr_fill_crc_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t crc_flag); \ No newline at end of file diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index caf7652841..e353a51143 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -267,7 +267,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // [hna] TO BE CLEANED // -------------------- - // nfapi_rx_indication_pdu_t *pdu; + nfapi_rx_indication_pdu_t *pdu; int timing_advance_update; int sync_pos; @@ -277,7 +277,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; // gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; - // pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; + pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; // pdu->rx_ue_information.handle = gNB->ulsch[UE_id+1][0]->handle; // pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; @@ -285,11 +285,10 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; // pdu->rx_indication_rel8.length = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->TBS>>3; // pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - // pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; + pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; // estimate timing advance for MAC sync_pos = nr_est_timing_advance_pusch(gNB, UE_id); timing_advance_update = sync_pos; // - gNB->frame_parms.nb_prefix_samples/4; //to check - // printf("\x1B[33m" "timing_advance_update = %d\n" "\x1B[0m", timing_advance_update); switch (gNB->frame_parms.N_RB_DL) { // case 6: /* nothing to do */ break; @@ -309,7 +308,9 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, if (timing_advance_update < 0) timing_advance_update = 0; if (timing_advance_update > 63) timing_advance_update = 63; - // pdu->rx_indication_rel8.timing_advance = timing_advance_update; + printf("\x1B[33m" "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n" "\x1B[0m", sync_pos,timing_advance_update); + + pdu->rx_indication_rel8.timing_advance = timing_advance_update; // estimate UL_CQI for MAC (from antenna port 0 only) // int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]); @@ -322,12 +323,28 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // harq_pid,frame,slot_rx,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, // timing_advance_update); - // gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; + gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | slot_rx; // pthread_mutex_unlock(&gNB->UL_INFO_mutex); } +void nr_fill_crc_indication (PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t crc_flag){ + // pthread_mutex_lock(&gNB->UL_INFO_mutex); + nfapi_crc_indication_pdu_t *pdu = &gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; + // gNB->UL_INFO.crc_ind.sfn_sf = frame<<4 | subframe; + // gNB->UL_INFO.crc_ind.header.message_id = NFAPI_CRC_INDICATION; + // gNB->UL_INFO.crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; + // pdu->instance_length = 0; // don't know what to do with this + // // pdu->rx_ue_information.handle = handle; + // pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + // pdu->rx_ue_information.rnti = gNB->ulsch[UE_id]->rnti; + // pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; + // pdu->crc_indication_rel8.crc_flag = crc_flag; + gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs++; + //LOG_D(PHY, "%s() rnti:%04x crcs:%d crc_flag:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, crc_flag); + // pthread_mutex_unlock(&gNB->UL_INFO_mutex); +} void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { @@ -355,9 +372,10 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) int num_pusch_pdu = UL_tti_req->n_pdus; LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pusch_pdu %d\n",frame_rx,slot_rx,num_pusch_pdu); - - for (int i = 0; i < num_pusch_pdu; i++) { + gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; + + for (int i = 0; i < num_pusch_pdu; i++) { switch (UL_tti_req->pdus_list[i].pdu_type) { case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: { @@ -378,6 +396,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[UE_id]->rxdataF_ext[0],6900,1,1); nr_ulsch_procedures(gNB, frame_rx, slot_rx, UE_id, harq_pid); nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); // indicate SDU to MAC + nr_fill_crc_indication(gNB, frame_rx, slot_rx, UE_id, 0); } } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2ad57beba9..bccc3a61b9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1551,10 +1551,10 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing int factor_mu = 1 << mu; - PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * 1024 / factor_mu ; + //PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * 1024 / factor_mu ; - LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value is %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); + LOG_D(PHY,"[UE %d] Got timing advance %u from MAC, new value is %u\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); } void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index a53f09939b..7f309a8a3a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -185,7 +185,7 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ uint16_t sdu_lengths[NR_MAX_NB_RB] = {0}; int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0; + int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0, ta_update; // hardcoded parameters // for DMRS configuration type 1 @@ -195,11 +195,11 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ uint16_t R = 697; uint16_t nb_rb = 50 ; uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs - int ta_update = 17; NR_TAG_Id_t tag_id = 0; int UE_id = 0; // UE_list->head is -1 ! UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ta_update = ue_sched_ctl->ta_update; for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP] + 1; CC_id++) { LOG_D(MAC, "doing nr_schedule_ue_spec for CC_id %d\n", CC_id); @@ -214,13 +214,14 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ } else { // This is a potentially new SDU opportunity */ if (gNB->tag->timeAlignmentTimer != NULL) { + printf(" SHOULD NOT ENTER HERE \n"); if (gNB->tag->timeAlignmentTimer == 0) { ta_update = ue_sched_ctl->ta_update; /* if we send TA then set timer to not send it for a while */ if (ta_update != 31) ue_sched_ctl->ta_timer = 20; /* reset ta_update */ - ue_sched_ctl->ta_update = 31; + ue_sched_ctl->ta_update = 31; } else { ta_update = 31; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 92ba958519..f3a1b3e7fd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -464,3 +464,21 @@ int get_symbolsperslot(nfapi_nr_config_request_t *cfg) { } +int find_nrUE_id(module_id_t mod_idP, rnti_t rntiP) { + + int UE_id; + UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list; + + for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) { + if (UE_list->active[UE_id] == TRUE) { + if (UE_list->UE_template[nrUE_PCCID(mod_idP, UE_id)][UE_id].rnti == rntiP) { + return UE_id; + } + } + } + return -1; +} + +int nrUE_PCCID(module_id_t mod_idP, int ue_idP) { + return (RC.nrmac[mod_idP]->UE_list.pCC_id[ue_idP]); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c new file mode 100644 index 0000000000..cc3f0c5001 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -0,0 +1,1933 @@ +/* + * 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 gNB_scheduler_ulsch.c + * \brief gNB procedures for the ULSCH transport channel + * \author Navid Nikaein and Raymond Knopp, Guido Casati + * \date 2019 + * \email: guido.casati@iis.fraunhofer.de + * \version 1.0 + * @ingroup _mac + */ + +/* indented with: indent -kr eNB_scheduler_RA.c */ + +#include "LAYER2/NR_MAC_gNB/mac_proto.h" + +/* +#include "LAYER2/MAC/mac.h" +#include "LAYER2/MAC/mac_extern.h" +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "nfapi/oai_integration/vendor_ext.h" +#include "UTIL/OPT/opt.h" +#include "OCG.h" +#include "OCG_extern.h" +#include "PHY/LTE_TRANSPORT/transport_common_proto.h" + +#include "RRC/LTE/rrc_extern.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" + +#include "assertions.h" +#include "pdcp.h" + +#if defined(ENABLE_ITTI) + #include "intertask_interface.h" +#endif + +#include "ENB_APP/flexran_agent_defs.h" +#include "flexran_agent_ran_api.h" +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "flexran_agent_mac.h" +#include + +#include "T.h" + +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + +#define ENABLE_MAC_PAYLOAD_DEBUG +#define DEBUG_eNB_SCHEDULER 1 + +extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); +extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); +extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset); +extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req);*/ + +/* +// This table holds the allowable PRB sizes for ULSCH transmissions +uint8_t rb_table[34] = { + 1, 2, 3, 4, 5, // 0-4 + 6, 8, 9, 10, 12, // 5-9 + 15, 16, 18, 20, 24, // 10-14 + 25, 27, 30, 32, 36, // 15-19 + 40, 45, 48, 50, 54, // 20-24 + 60, 64, 72, 75, 80, // 25-29 + 81, 90, 96, 100 // 30-33 +};*/ + +/*extern mui_t rrc_eNB_mui;*/ + +//----------------------------------------------------------------------------- +/* +* When data are received on PHY and transmitted to MAC +*/ +void +nr_rx_sdu(const module_id_t gnb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP, + uint8_t *sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, + const uint8_t ul_cqi) +//----------------------------------------------------------------------------- +{ + int current_rnti = 0, UE_id = -1, harq_pid = 0; + // int RA_id = 0; + // int old_rnti = -1; + // int old_UE_id = -1; + // int crnti_rx = 0; + // int first_rb = 0; + // unsigned char num_ce = 0; + // unsigned char num_sdu = 0; + // unsigned char *payload_ptr = NULL; + // unsigned char rx_ces[MAX_NUM_CE]; + // unsigned char rx_lcids[NB_RB_MAX]; + // unsigned short rx_lengths[NB_RB_MAX]; + // uint8_t lcgid = 0; + // int lcgid_updated[4] = {0, 0, 0, 0}; + // rrc_eNB_ue_context_t *ue_contextP = NULL; + gNB_MAC_INST *gNB = NULL; + UE_list_t *UE_list = NULL; + UE_sched_ctrl_t *UE_scheduling_control = NULL; + // UE_TEMPLATE *UE_template_ptr = NULL; + + /* Init */ + current_rnti = rntiP; + UE_id = find_nrUE_id(gnb_mod_idP, current_rnti); + gNB = RC.nrmac[gnb_mod_idP]; + UE_list = &gNB->UE_list; + + // harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + // memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char)); + // memset(rx_lcids, 0, NB_RB_MAX * sizeof(unsigned char)); + // 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); + + // 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", + // gnb_mod_idP, + // frameP, + // current_rnti, + // sdu_lenP); + // } + + /* Hardcoded UE_id */ + UE_id = 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", + gnb_mod_idP, + harq_pid, + CC_idP, + frameP, + subframeP, + UE_scheduling_control->round_UL[CC_idP][harq_pid], + current_rnti, + UE_id, + ul_cqi); + + // AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + + if (sduP != NULL) { + // UE_scheduling_control->ul_inactivity_timer = 0; + // UE_scheduling_control->ul_failure_timer = 0; + // UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); + /* LTE: Update with smoothing: 3/4 of old value and 1/4 of new. + * This is the logic that was done in the function + * lte_est_timing_advance_pusch, maybe it's not necessary? + * maybe it's even not correct at all? + * NR: smoothing removed + */ + //UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; + UE_scheduling_control->ta_update = timing_advance; + printf("UE_scheduling_control->ta_update %u\n", UE_scheduling_control->ta_update); + // 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) { + // UE_scheduling_control->ul_out_of_sync = 0; + // mac_eNB_rrc_ul_in_sync(gnb_mod_idP, CC_idP, frameP, subframeP, current_rnti); + // } + + /* Update bytes to schedule */ + // UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; + + // if (UE_template_ptr->scheduled_ul_bytes < 0) { + // UE_template_ptr->scheduled_ul_bytes = 0; + // } + } else { // sduP == NULL => error + // LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n", + // gnb_mod_idP, + // harq_pid, + // CC_idP, + // frameP, + // subframeP, + // UE_scheduling_control->round_UL[CC_idP][harq_pid], + // ul_cqi, + // UE_id, + // current_rnti); + + // if (ul_cqi > 200) { // too high energy pattern + // UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; + // LOG_W(MAC, "[MAC] Too high energy pattern\n"); + // } + + // if (UE_scheduling_control->round_UL[CC_idP][harq_pid] == 3) { + // UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); + // UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; + + // if (UE_scheduling_control->ul_consecutive_errors++ == 10) { + // UE_scheduling_control->ul_failure_timer = 1; + // } + + // /* Update scheduled bytes */ + // UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; + + // if (UE_template_ptr->scheduled_ul_bytes < 0) { + // UE_template_ptr->scheduled_ul_bytes = 0; + // } + + // if (find_RA_id(gnb_mod_idP, CC_idP, current_rnti) != -1) { + // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); + // } + // } else { + // UE_scheduling_control->round_UL[CC_idP][harq_pid]++; + // } + + // /* CDRX UL HARQ timers */ + // 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. + // * Start corresponding CDRX ULRetransmission timer. + // */ + // } + + // 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]; + // 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]; + // memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + // hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + // hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + // hi_dci0_req_body->number_of_hi++; + // hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 0); + // hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + // hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); + // hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + // return; + } + + // if UE_id == -1 + } // else if ((RA_id = find_RA_id(gnb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti + // RA_t *ra = (RA_t *) &(mac->common_channels[CC_idP].ra[RA_id]); + // #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + + // if (ra->rach_resource_type > 0) { + // harq_pid = 0; + // } + + // #endif + // AssertFatal(mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 1, + // "maxHARQ %d should be greater than 1\n", + // (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); + // LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + // gnb_mod_idP, + // harq_pid, + // CC_idP, + // ra->msg3_round, + // current_rnti, + // RA_id, + // ul_cqi); + // first_rb = ra->msg3_first_rb; + + // if (sduP == NULL) { // we've got an error on Msg3 + // LOG_D(MAC, "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", + // gnb_mod_idP, + // CC_idP, + // RA_id, + // ra->msg3_round, + // (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); + + // if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { + // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); + // } 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(gnb_mod_idP, CC_idP, ra, frameP, subframeP); + // } + // /* TODO: program NACK for PHICH? */ + // return; + // } + //} else { + // LOG_W(MAC, "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti); + // return; + //} + + //payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); + + //if (payload_ptr == NULL) { + // LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", + // gnb_mod_idP, + // harq_pid, + // CC_idP, + // current_rnti, + // UE_id); + // return; + //} + + //T(T_ENB_MAC_UE_UL_PDU, + // T_INT(gnb_mod_idP), + // T_INT(CC_idP), + // T_INT(current_rnti), + // T_INT(frameP), + // T_INT(subframeP), + // T_INT(harq_pid), + // T_INT(sdu_lenP), + // T_INT(num_ce), + // T_INT(num_sdu)); + //T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, + // T_INT(gnb_mod_idP), + // T_INT(CC_idP), + // T_INT(current_rnti), + // T_INT(frameP), + // T_INT(subframeP), + // T_INT(harq_pid), + // T_INT(sdu_lenP), + // T_INT(num_ce), + // T_INT(num_sdu), + // T_BUFFER(sduP, sdu_lenP)); + //mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; + //mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; + //mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; + + //if (UE_id != -1) { + // UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; + //} + + ///* Control element */ + //for (int i = 0; i < num_ce; i++) { + // T(T_ENB_MAC_UE_UL_CE, + // T_INT(gnb_mod_idP), + // T_INT(CC_idP), + // T_INT(current_rnti), + // T_INT(frameP), + // T_INT(subframeP), + // T_INT(rx_ces[i])); + + // switch (rx_ces[i]) { // implement and process PHR + CRNTI + BSR + // case POWER_HEADROOM: + // if (UE_id != -1) { + // UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100); + + // if (UE_template_ptr->phr_info > 40) { + // UE_template_ptr->phr_info = 40; + // } + + // LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", + // gnb_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; + // } + + // payload_ptr += sizeof(POWER_HEADROOM_CMD); + // break; + + // case CRNTI: + // old_rnti = (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; + // old_UE_id = find_UE_id(gnb_mod_idP, old_rnti); + // LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", + // gnb_mod_idP, + // frameP, + // subframeP, + // CC_idP, + // rx_ces[i], + // i, + // num_ce, + // old_rnti, + // old_UE_id); + + // /* Receiving CRNTI means that the current rnti has to go away */ + // if (old_UE_id != -1) { + // if (mac_eNB_get_rrc_status(gnb_mod_idP,old_rnti) == RRC_HO_EXECUTION) { + // LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n", + // gnb_mod_idP, + // frameP, + // subframeP, + // 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; + + // if (UE_scheduling_control->ul_out_of_sync > 0) { + // UE_scheduling_control->ul_out_of_sync = 0; + // mac_eNB_rrc_ul_in_sync(gnb_mod_idP, + // CC_idP, + // frameP, + // subframeP, + // old_rnti); + // } + // UE_template_ptr->ul_SR = 1; + // UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; + // UE_list->UE_template[UE_PCCID(gnb_mod_idP, UE_id)][UE_id].configured = 1; + // cancel_ra_proc(gnb_mod_idP, + // CC_idP, + // frameP, + // current_rnti); + // } else { + // /* TODO: if the UE did random access (followed by a MAC uplink with + // * CRNTI) because none of its scheduling request was granted, then + // * according to 36.321 5.4.4 the UE's MAC will notify RRC to release + // * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply + // * default configuration for CQI reporting and scheduling requests, + // * which basically means that the CQI requests won't work anymore and + // * that the UE won't do any scheduling request anymore as long as the + // * eNB doesn't reconfigure the UE. + // * We have to take care of this. As the code is, nothing is done and + // * the UE state in the eNB is wrong. + // */ + // RA_id = find_RA_id(gnb_mod_idP, CC_idP, current_rnti); + + // if (RA_id != -1) { + // RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); + // int8_t ret = mac_rrc_data_ind(gnb_mod_idP, + // 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 + // #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", + // gnb_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; + + // if (UE_scheduling_control->ul_out_of_sync > 0) { + // UE_scheduling_control->ul_out_of_sync = 0; + // mac_eNB_rrc_ul_in_sync(gnb_mod_idP, CC_idP, frameP, subframeP, old_rnti); + // } + // UE_template_ptr->ul_SR = 1; + // UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; + // } else { + // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); + // } + // // break; + // } + // } + // } else { + // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); + // LOG_W(MAC, "[MAC] Can't find old UE_id\n"); + // } + + // crnti_rx = 1; + // payload_ptr += 2; // sizeof(CRNTI) + // break; + + // case TRUNCATED_BSR: + // case SHORT_BSR: + // lcgid = (payload_ptr[0] >> 6); + // LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + // gnb_mod_idP, + // CC_idP, + // rx_ces[i], + // lcgid, + // payload_ptr[0] & 0x3f); + + // if (UE_id != -1) { + // int bsr = 0; + // bsr = payload_ptr[0] & 0x3f; + // lcgid_updated[lcgid] = 1; + // /* Update buffer info */ + // UE_template_ptr->ul_buffer_info[lcgid] = BSR_TABLE[bsr]; + // 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]; + + // RC.eNB[gnb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); + + // if (UE_id == UE_list->head) { + // VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, (payload_ptr[0] & 0x3f)); + // } + + // if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { + // UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; + // } + + // if (mac_eNB_get_rrc_status(gnb_mod_idP,UE_RNTI(gnb_mod_idP, UE_id)) < RRC_CONNECTED) { + // LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", + // gnb_mod_idP, + // CC_idP, + // rx_ces[i], + // UE_template_ptr->estimated_ul_buffer, + // UE_template_ptr->ul_buffer_info[lcgid]); + // } + // } else { + // /* Need error message */ + // } + + // payload_ptr += 1; // sizeof(SHORT_BSR) + // break; + + // case LONG_BSR: + // if (UE_id != -1) { + // int bsr0 = (payload_ptr[0] & 0xFC) >> 2; + // int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + // int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + // int bsr3 = payload_ptr[2] & 0x3F; + // lcgid_updated[LCGID0] = 1; + // lcgid_updated[LCGID1] = 1; + // lcgid_updated[LCGID2] = 1; + // lcgid_updated[LCGID3] = 1; + // /* Update buffer info */ + // UE_template_ptr->ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; + // 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", + // gnb_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", + // gnb_mod_idP, + // CC_idP, + // rx_ces[i]); + // } + + // for(int lcgid = 0; lcgid <= LCGID3; lcgid++) { + // if (UE_template_ptr->ul_buffer_info[lcgid] == 0) { + // UE_template_ptr->ul_buffer_creation_time[lcgid] = 0; + // } else if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { + // UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; + // } + // } + // } + + // payload_ptr += 3; // sizeof(LONG_BSR) + // break; + + // default: + // LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + // gnb_mod_idP, + // CC_idP, + // rx_ces[i]); + // break; + //} // end switch on control element + //} // end for loop on control element + + // for (int i = 0; i < num_sdu; i++) { + // LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", + // i, + // rx_lcids[i], + // rx_lengths[i]); + // T(T_ENB_MAC_UE_UL_SDU, + // T_INT(gnb_mod_idP), + // T_INT(CC_idP), + // T_INT(current_rnti), + // T_INT(frameP), + // T_INT(subframeP), + // T_INT(rx_lcids[i]), + // T_INT(rx_lengths[i])); + // T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, + // T_INT(gnb_mod_idP), + // T_INT(CC_idP), + // T_INT(current_rnti), + // T_INT(frameP), + // T_INT(subframeP), + // T_INT(rx_lcids[i]), + // T_INT(rx_lengths[i]), + // T_BUFFER(payload_ptr, rx_lengths[i])); + + // switch (rx_lcids[i]) { + // case CCCH: + // if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + // LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + // gnb_mod_idP, + // CC_idP, + // frameP, + // rx_lengths[i], + // CCCH_PAYLOAD_SIZE_MAX, + // sdu_lenP); + // break; + // } + + // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + // gnb_mod_idP, + // CC_idP, + // frameP, + // payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5], + // current_rnti); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); + // RA_id = find_RA_id(gnb_mod_idP, CC_idP, current_rnti); + + // if (RA_id != -1) { + // RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); + // LOG_D(MAC, "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + // gnb_mod_idP, + // CC_idP, + // RA_id, + // ra->rnti, + // current_rnti, + // ra->state); + + // if (UE_id < 0) { + // memcpy(&(ra->cont_res_id[0]), payload_ptr, 6); + // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", + // gnb_mod_idP, + // CC_idP, + // frameP, + // rx_lengths[i], + // payload_ptr - sduP); + + // if ((UE_id = add_new_ue(gnb_mod_idP, CC_idP, ra->rnti, harq_pid + // #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + // , ra->rach_resource_type + // #endif + // )) == -1) { + // LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); + // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); // send Connection Reject ??? + // break; + // // kill RA proc + // } else { + // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", + // gnb_mod_idP, + // CC_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]); + // } + // } else { + // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", + // gnb_mod_idP, + // CC_idP, + // frameP, + // UE_id, + // rx_lengths[i], + // payload_ptr - sduP); + // // kill RA proc + // } + + // mac_rrc_data_ind(gnb_mod_idP, + // CC_idP, + // frameP, subframeP, + // UE_id, + // current_rnti, + // CCCH, + // (uint8_t *) payload_ptr, + // rx_lengths[i], + // 0 + // #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + // ,ra->rach_resource_type > 0 + // #endif + // ); + + // if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest + // // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + // } + + // // prepare transmission of Msg4 + // ra->state = MSG4; + + // if(mac->common_channels[CC_idP].tdd_Config != NULL) { + // switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) { + // case 1: + // ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); + // ra->Msg4_subframe = (subframeP + 7) % 10; + // break; + + // default: + // printf("%s:%d: TODO\n", __FILE__, __LINE__); + // abort(); + // // TODO need to be complete for other tdd configs. + // } + // } else { + // /* Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, + // * Check if this is ok for BL/CE, or if the rule is different + // */ + // ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); + // ra->Msg4_subframe = (subframeP + 4) % 10; + // } + + // UE_scheduling_control->crnti_reconfigurationcomplete_flag = 0; + // } // if RA process is active + + // break; + + // case DCCH: + // case DCCH1: + //#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + // LOG_T(MAC, "offset: %d\n", (unsigned char) ((unsigned char *) payload_ptr - sduP)); + // + // for (int j = 0; j < 32; j++) { + // LOG_T(MAC, "%x ", payload_ptr[j]); + // } + // + // LOG_T(MAC, "\n"); + //#endif + // + // if (UE_id != -1) { + // if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { + // /* Adjust buffer occupancy of the correponding logical channel group */ + // if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + // else + // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; + // + // UE_template_ptr->estimated_ul_buffer = + // UE_template_ptr->ul_buffer_info[0] + + // UE_template_ptr->ul_buffer_info[1] + + // UE_template_ptr->ul_buffer_info[2] + + // UE_template_ptr->ul_buffer_info[3]; + // //UE_template_ptr->estimated_ul_buffer += UE_template_ptr->estimated_ul_buffer / 4; + // } + // + // LOG_D(MAC, + // "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", + // gnb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + // rx_lcids[i]); + // mac_rlc_data_ind(gnb_mod_idP, current_rnti, gnb_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(gnb_mod_idP, current_rnti) < RRC_RECONFIGURED) { + // UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + // } + // } + // + // break; + // + // // all the DRBS + // case DTCH: + // default: + //#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + // LOG_T(MAC, "offset: %d\n", + // (unsigned char) ((unsigned char *) payload_ptr - sduP)); + // + // for (int j = 0; j < 32; j++) { + // LOG_T(MAC, "%x ", payload_ptr[j]); + // } + // + // LOG_T(MAC, "\n"); + //#endif + // + // if (rx_lcids[i] < NB_RB_MAX) { + // LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + // gnb_mod_idP, + // CC_idP, + // frameP, + // rx_lengths[i], + // UE_id, + // rx_lcids[i]); + // + // if (UE_id != -1) { + // /* Adjust buffer occupancy of the correponding logical channel group */ + // LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", + // gnb_mod_idP, + // CC_idP, + // frameP, + // rx_lengths[i], + // UE_id, + // rx_lcids[i], + // UE_template_ptr->lcgidmap[rx_lcids[i]], + // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]]); + // + // if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { + // if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { + // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + // } else { + // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; + // } + // + // UE_template_ptr->estimated_ul_buffer = + // UE_template_ptr->ul_buffer_info[0] + + // UE_template_ptr->ul_buffer_info[1] + + // UE_template_ptr->ul_buffer_info[2] + + // UE_template_ptr->ul_buffer_info[3]; + // } + // + // if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + // mac_rlc_data_ind(gnb_mod_idP, current_rnti, gnb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); + // 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]; + // /* 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[gnb_mod_idP], current_rnti); + // + // if (ue_contextP != NULL) { + // ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + // } else { + // LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", + // gnb_mod_idP, + // CC_idP, + // current_rnti); + // } + // } else { /* rx_length[i] Max size */ + // UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + // LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + // gnb_mod_idP, + // CC_idP, + // frameP, + // rx_lcids[i], + // UE_id); + // } + // } else { // end if (UE_id != -1) + // LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + // gnb_mod_idP, + // CC_idP, + // frameP, + // rx_lcids[i], + // UE_id); + // } + // } + // + // break; + // } + // + // payload_ptr += rx_lengths[i]; + // } + // + // /* CDRX UL HARQ timers */ + // if (UE_id != -1) { + // 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 + // * Stop corresponding CDRX ULRetransmission timer + // */ + // } + // } + // + // /* Program ACK for PHICH */ + // LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", + // 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]; + // memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + // hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + // hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; + // hi_dci0_req_body->number_of_hi++; + // hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + // hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + // hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); + // hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + // + // /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ + // if ((num_sdu == 0) && (num_ce == 0)) { + // if (UE_id != -1) + // UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; + // } else { + // if (UE_id != -1) { + // UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; + // UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP; + // UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; + // } + // } + // + // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); + // stop_meas(&mac->rx_ulsch_sdu); +} + +//----------------------------------------------------------------------------- +// +// Return the BSR table index corresponding to the number of bytes in input +// +/*uint32_t +bytes_to_bsr_index(int32_t nbytes) +//----------------------------------------------------------------------------- +{ + uint32_t i = 0; + + if (nbytes < 0) { + return (0); + } + + while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { + i++; + } + + return (i - 1); +}*/ + +//----------------------------------------------------------------------------- +// Add ue info in eNB_ulsch_info[module_idP][CC_id][UE_id] struct +/* +void +add_ue_ulsch_info(module_id_t module_idP, + int CC_id, + int UE_id, + sub_frame_t subframeP, + UE_ULSCH_STATUS status) +//----------------------------------------------------------------------------- +{ + eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); + eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; + eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; +}*/ + +/*----------------------------------------------------------------------------- +// +// Parse MAC header from ULSCH +/// +unsigned char * +parse_ulsch_header(unsigned char *mac_header, + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) +//----------------------------------------------------------------------------- +{ + unsigned char not_done = 1; + unsigned char num_ces = 0; + unsigned char num_sdus = 0; + unsigned char lcid = 0; + unsigned char num_sdu_cnt = 0; + unsigned char *mac_header_ptr = NULL; + unsigned short length, ce_len = 0; + // Init + mac_header_ptr = mac_header; + + while (not_done == 1) { + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + not_done = 0; + } + + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; + + if (lcid < EXTENDED_POWER_HEADROOM) { + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length - (mac_header_ptr - mac_header) - ce_len; + + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } + } else { + if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); + } else { // F = 1 + length = ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & 0x7f) << 8) | + (((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB & 0xff); + mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); + } + } + + LOG_D(MAC, "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", + num_sdus, + lcid, + tb_length, + length, + mac_header_ptr - mac_header); + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + if (lcid == SHORT_PADDING) { + mac_header_ptr++; + } else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + + if (lcid == LONG_BSR) { + ce_len += 3; + } else if (lcid == CRNTI) { + ce_len += 2; + } else if ((lcid == POWER_HEADROOM) || (lcid == TRUNCATED_BSR) || (lcid == SHORT_BSR)) { + ce_len++; + } else { + LOG_E(MAC, "unknown CE %d \n", lcid); + return NULL; + } + } + } + } + + *num_ce = num_ces; + *num_sdu = num_sdus; + return (mac_header_ptr); +}*/ + +//----------------------------------------------------------------------------- +// This function is called by PHY layer when it schedules some +// uplink for a random access message 3. +// The MAC scheduler has to skip the RBs used by this message 3 +// (done below in schedule_ulsch). +// This function seems to be unused, the Msg3_subframe is set somewhere else... +// In NFAPI?? +/// +/*void +set_msg3_subframe(module_id_t mod_id, + int CC_id, + int frame, // Not used, remove? + int subframe, // Not used, remove? + int rnti, + int Msg3_frame, // Not used, remove? + int Msg3_subframe) +//----------------------------------------------------------------------------- +{ + int RA_id = 0; + // Init + RA_id = find_RA_id(mod_id, CC_id, rnti); // state == WAITMSG3 instead of state != IDLE (?) + + if (RA_id != -1) { + RC.mac[mod_id]->common_channels[CC_id].ra[RA_id].Msg3_subframe = Msg3_subframe; + } else { + LOG_E(MAC, "[MAC] Unknown RAPROC associated to RNTI %x\n", rnti); + } + + return; +}*/ + +/* +//----------------------------------------------------------------------------- +// +//Main function called for uplink scheduling (DCI0). +// +void +schedule_ulsch(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- +{ + uint16_t first_rb[NFAPI_CC_MAX]; + eNB_MAC_INST *mac = NULL; + slice_info_t *sli = NULL; + 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; + + // For TDD: check subframes where we have to act and return if nothing should be done now + if (cc->tdd_Config) { // Done only for CC_id = 0, assume tdd_Config for all CC_id + int tdd_sfa = cc->tdd_Config->subframeAssignment; + + switch (subframeP) { + case 0: + if ((tdd_sfa == 0) || (tdd_sfa == 3)) + sched_subframe = 4; + else if (tdd_sfa == 6) + sched_subframe = 7; + else + return; + + break; + + case 1: + if ((tdd_sfa == 0) || (tdd_sfa == 1)) + sched_subframe = 7; + else if (tdd_sfa == 6) + sched_subframe = 8; + else + return; + + break; + + case 2: // Don't schedule UL in subframe 2 for TDD + return; + + case 3: + if (tdd_sfa == 2) + sched_subframe = 7; + else + return; + + break; + + case 4: + if (tdd_sfa == 1) + sched_subframe = 8; + else + return; + + break; + + case 5: + if (tdd_sfa == 0) + sched_subframe = 9; + else if (tdd_sfa == 6) + sched_subframe = 2; + else + return; + + break; + + case 6: + if (tdd_sfa == 0 || tdd_sfa == 1) + sched_subframe = 2; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; + + break; + + case 7: + return; + + case 8: + if ((tdd_sfa >= 2) && (tdd_sfa <= 5)) + sched_subframe = 2; + else + return; + + break; + + case 9: + if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) + sched_subframe = 3; + else if (tdd_sfa == 6) + sched_subframe = 4; + else + return; + + break; + + default: + return; + } + } + + if (sched_subframe < subframeP) { + sched_frame++; + sched_frame %= 1024; + } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + int emtc_active[5]; + memset(emtc_active, 0, 5 * sizeof(int)); + schedule_ulsch_rnti_emtc(module_idP, frameP, subframeP, sched_subframe, emtc_active); +#endif + + // Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX + for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) { +#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); + } +#endif + RA_t *ra_ptr = cc->ra; + + // From Louis-Adrien to François: + // The comment bloc below is to configure with a command line. + // I took it from the equivalent part in the fairRR scheduler (around line 2578 in eNB_scheduler_fairRR.c). + // As said in the meeting, it seems to work only for small TBS. + // The cause of false RA still present with this fix is to investigate. + // + // Note: in the get_prach_prb_offset() function below, the last argument is frameP in eNB_scheduler_fairRR.c + // I think it should be sched_frame instead. This parameter has only impacts in case TDD and preamble format 4. + // To confirm. + // + // + // int start_rb = 0; + // int nb_rb = 6; + // LTE_DL_FRAME_PARMS *frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms); + // + // if (is_prach_subframe(frame_parms, sched_frame, sched_subframe) == 1) { + // start_rb = get_prach_prb_offset(frame_parms, + // frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + // frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, + // 0, // tdd_mapindex + // sched_frame); // Nf + // + // first_rb[CC_id] = start_rb + nb_rb; + // } + + // + // Check if RA (Msg3) is active in this subframeP, if so skip the PRB used for Msg3 + // Msg3 is using 1 PRB so we need to increase first_rb accordingly + // Not sure about the break (can there be more than 1 active RA procedure per CC_id and per subframe?) + // + for (int ra_index = 0; ra_index < NB_RA_PROC_MAX; ra_index++, ra_ptr++) { + if ((ra_ptr->state == WAITMSG3) && (ra_ptr->Msg3_subframe == sched_subframe)) { + if (first_rb[CC_id] < ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb) { + first_rb[CC_id] = ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb; + } + + // Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling + // on the same time resources. Also the performance improvement of breaking is low, + // since we will loop until the end, most of the time. + // I'm letting the break as a reminder, in case of misunderstanding the spec. + // + // break; + } + } + } + + // Run each enabled slice-specific schedulers one by one + for (int i = 0; i < sli->n_ul; i++) { + // By default the scheduler is schedule_ulsch_rnti (see below) + sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); + } + + stop_meas(&mac->schedule_ulsch); +}*/ + +/* +//----------------------------------------------------------------------------- +// Schedule the DCI0 for ULSCH +void +nr_schedule_ulsch_rnti(module_id_t module_idP, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframeP, + uint16_t *first_rb) +//----------------------------------------------------------------------------- +{ + rnti_t rnti = -1; + uint8_t aggregation = 2; + uint8_t round_index = 0; + uint8_t harq_pid = 0; + uint8_t status = 0; + uint8_t rb_table_index = -1; + uint8_t dlsch_flag = 0; + uint16_t ul_req_index = 0; + uint32_t cqi_req = 0; + uint32_t cshift = 0; + uint32_t ndi = 0; + uint32_t tpc = 0; + int32_t snr = 0; + int32_t target_snr = 0; + int32_t framex10psubframe = 0; + static int32_t tpc_accumulated = 0; + int sched_frame = 0; + int CC_id = 0; + eNB_MAC_INST *mac = NULL; + COMMON_channels_t *cc = NULL; + UE_list_t *UE_list = NULL; + slice_info_t *sli = NULL; + UE_TEMPLATE *UE_template_ptr = NULL; + UE_sched_ctrl_t *UE_sched_ctrl_ptr = NULL; + int rvidx_tab[4] = {0, 2, 3, 1}; + int first_rb_slice[NFAPI_CC_MAX]; + int n_rb_ul_tab[NFAPI_CC_MAX]; + // Init + mac = RC.mac[module_idP]; + cc = mac->common_channels; + UE_list = &(mac->UE_list); + sli = &(mac->slice_info); + memset(first_rb_slice, 0, NFAPI_CC_MAX * sizeof(int)); + memset(n_rb_ul_tab, 0, NFAPI_CC_MAX * sizeof(int)); + sched_frame = frameP; + + if (sched_subframeP < subframeP) { + sched_frame++; + sched_frame %= 1024; + } + + // NFAPI struct init + nfapi_hi_dci0_request_t *hi_dci0_req = &(mac->HI_DCI0_req[CC_id][subframeP]); + 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; + nfapi_ul_config_request_t *ul_req_tmp = &(mac->UL_req_tmp[CC_id][sched_subframeP]); + nfapi_ul_config_request_body_t *ul_req_tmp_body = &(ul_req_tmp->ul_config_request_body); + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; + hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; + + // 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) + // - for 50: 2 RBs + // - for 100: 3 RBs + // This is totally arbitrary and might even be wrong. + // We suppose 'first_rb[]' has been correctly populated by the caller, + // 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); + } + 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 + // pre_allocated_rb_table_index_ul + /// + ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_frame, sched_subframeP, first_rb); + + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { + first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx]; + } + + // loop over all active UEs until end of function + for (int UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + 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 + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured == FALSE) { + LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, + frameP, + subframeP, + UE_id); + continue; + } + + rnti = UE_RNTI(module_idP, UE_id); + + if (rnti == NOT_A_RNTI) { + LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n", + module_idP, + frameP, + subframeP, + UE_id); + continue; + } + + // loop over all active UL CC_ids for this UE until end of function + 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); + round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid]; + AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n", + round_index, + UE_id, + rnti); + LOG_D(MAC, "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", + module_idP, + frameP, + subframeP, + sched_frame, + sched_subframeP, + harq_pid, + UE_id, + rnti, + CC_id, + aggregation, + n_rb_ul_tab[CC_id]); + // Seems unused, only for debug // + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template_ptr->estimated_ul_buffer; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer); + + // + //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 + // + if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) { + LOG_D(MAC, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %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_index, + UE_template_ptr->ul_SR, + 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); + + // New transmission + if (round_index == 0) { + // 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); + + continue; + } + + // Should format_flag be 2 in CCE_allocation_infeasible??? + // 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); + + 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) { + case 1: + if(subframeP == 1 || subframeP == 6) { + cqi_req=0; + } + break; + + case 3: + if(subframeP == 1) { + cqi_req=0; + } + break; + + default: + LOG_E(MAC," TDD config not supported\n"); + break; + } + } + + if(cqi_req == 1) { + UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP; + } + } + } else { + LOG_D(MAC,"Clearing CQI request timer\n"); + UE_sched_ctrl_ptr->cqi_req_flag = 0; + UE_sched_ctrl_ptr->cqi_received = 0; + UE_sched_ctrl_ptr->cqi_req_timer = 0; + } + } + + //Power control + // + //Compute the expected ULSCH RX snr (for the stats) + //This is the normalized RX snr and this should be constant (regardless of mcs) + //Is not in dBm, unit from nfapi, converting to dBm + // + 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 + // + framex10psubframe = (UE_template_ptr->pusch_tpc_tx_frame * 10) + UE_template_ptr->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_ptr->pusch_tpc_tx_frame = frameP; + UE_template_ptr->pusch_tpc_tx_subframe = subframeP; + + if (snr > target_snr + 4) { + tpc = 0; // -1 + tpc_accumulated--; + } else if (snr < target_snr - 4) { + tpc = 2; // +1 + tpc_accumulated++; + } 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, + tpc_accumulated, + snr, + target_snr); + } + + ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator + UE_template_ptr->oldNDI_UL[harq_pid] = ndi; + 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_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid]; + + // CDRX + 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 + } + + if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) { + rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul; + } else { + UE_template_ptr->mcs_UL[harq_pid] = 10; + rb_table_index = 5; // for PHR + } + + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template_ptr->mcs_UL[harq_pid]; + + while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) || + (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) { + rb_table_index--; + } + + UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->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_ptr->mcs_UL[harq_pid]), + T_INT(first_rb_slice[CC_id]), + T_INT(rb_table[rb_table_index]), + T_INT(UE_template_ptr->TBS_UL[harq_pid]), + T_INT(ndi)); + // Store information for possible retransmission + UE_template_ptr->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template_ptr->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; + UE_template_ptr->cqi_req[harq_pid] = cqi_req; + UE_sched_ctrl_ptr->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_ptr->ul_scheduled); + } + + // Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update + LOG_D(MAC, "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", + module_idP, + CC_id, + UE_id, + rnti, + UE_template_ptr->scheduled_ul_bytes, + UE_template_ptr->TBS_UL[harq_pid]); + UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid]; + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", + UE_template_ptr->scheduled_ul_bytes); + // Cyclic shift for DM-RS + 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_ptr->cshift[harq_pid] = cshift; + // Setting DCI0 NFAPI struct + 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]; + memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template_ptr->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template_ptr->DAI_ul[sched_subframeP]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; + hi_dci0_req_body->number_of_dci++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = frameP << 4 | subframeP; + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP); + ul_req_index = 0; + dlsch_flag = 0; + + for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { + if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { + dlsch_flag = 1; + LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n", + frameP, + subframeP, + rnti, + ul_req_index); + break; + } + } + + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], + cqi_req, + cc, + UE_template_ptr->physicalConfigDedicated, + get_tmode(module_idP, CC_id, UE_id), + mac->ul_handle, + rnti, + first_rb_slice[CC_id], // resource_block_start + rb_table[rb_table_index], // number_of_resource_blocks + UE_template_ptr->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index])); +#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], + UE_template_ptr->rach_resource_type > 2 ? 2 : 1, + 1, // total_number_of_repetitions + 1, // repetition_number + (frameP * 10) + subframeP); + } +#endif + + if (dlsch_flag == 1) { + if (cqi_req == 1) { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + rb_table[rb_table_index]; + } else { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; + } + + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + } else { + ul_req_tmp_body->number_of_pdus++; + } + + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + mac->ul_handle++; + ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP; + 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); + LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", + harq_pid, + frameP, + subframeP, + sched_frame, + sched_subframeP, + cqi_req, + UE_id, + rnti); + // Increment first rb for next UE allocation + first_rb_slice[CC_id] += rb_table[rb_table_index]; + } else { // round_index > 0 => retransmission + 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_ptr->mcs_UL[harq_pid]), + T_INT(UE_template_ptr->first_rb_ul[harq_pid]), + T_INT(UE_template_ptr->nb_rb_ul[harq_pid]), + T_INT(round_index)); + // Add UL_config PDUs + LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP); + ul_req_index = 0; + dlsch_flag = 0; + cqi_req = UE_template_ptr->cqi_req[harq_pid]; + + for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { + if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { + dlsch_flag = 1; + LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n", + frameP, + subframeP, + rnti, + ul_req_index); + break; + } + } + + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], + cqi_req, + cc, + UE_template_ptr->physicalConfigDedicated, + get_tmode(module_idP, CC_id, UE_id), + mac->ul_handle, + rnti, + UE_template_ptr->first_rb_ul[harq_pid], // resource_block_start + UE_template_ptr->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template_ptr->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template_ptr->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round_index & 3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 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], + UE_template_ptr->rach_resource_type > 2 ? 2 : 1, + 1, // total_number_of_repetitions + 1, // repetition_number + (frameP * 10) + subframeP); + } +#endif + + if(dlsch_flag == 1) { + if(cqi_req == 1) { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + UE_template_ptr->nb_rb_ul[harq_pid]; + } else { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + UE_template_ptr->nb_rb_ul[harq_pid]; + } + + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information, subframeP); + } else { + ul_req_tmp_body->number_of_pdus++; + } + + mac->ul_handle++; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + 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); + + // HACK: RBs used by retransmission have to be reserved. + // The current mechanism uses the notion of 'first_rb', so + // we skip all RBs below the ones retransmitted. This is + // not correct. Imagine only RB 23 is retransmitted, then all + // RBs < 23 will be marked unusable for new transmissions (case where round == 0). + // Note also that this code works only if the preprocessor orders + // UEs with retransmission with higher priority than UEs with new + // transmission. + // All this should be cleaned up properly. + // + 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 + } // UE_is_to_be_scheduled + } // loop over all active CC_ids + } // loop over UE_ids +}*/ \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 451bac8042..185c866661 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -149,6 +149,10 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint32_t bw); int32_t get_nr_uldl_offset(int nr_bandP); +int find_nrUE_id(module_id_t mod_idP, rnti_t rntiP); + +int nrUE_PCCID(module_id_t mod_idP, int ue_idP); + void config_nr_mib(int Mod_idP, int CC_idP, int p_gNBP, @@ -159,4 +163,22 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); +/* \brief Function to indicate a received SDU on ULSCH. +@param Mod_id Instance ID of gNB +@param CC_id Component carrier index +@param rnti RNTI of UE transmitting the SDU +@param sdu Pointer to received SDU +@param sdu_len Length of SDU +@param timing_advance timing advance adjustment after this pdu +@param ul_cqi Uplink CQI estimate after this pdu (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps) +*/ +void nr_rx_sdu(const module_id_t gnb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP, + uint8_t * sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, const uint8_t ul_cqi); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index e446ab3a95..86a24bd8d6 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -169,6 +169,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } } else { + printf("UL_info->rx_ind.rx_indication_body.number_of_pdus %d UL_info->crc_ind.crc_indication_body.number_of_crcs %d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->crc_ind.crc_indication_body.number_of_crcs); if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) { for (int i=0; irx_ind.rx_indication_body.number_of_pdus; i++) { for (int j=0; jcrc_ind.crc_indication_body.number_of_crcs; j++) { @@ -182,28 +183,29 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot); - rx_sdu(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, - NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - (uint8_t *)NULL, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); - } else { - LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); - rx_sdu(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, - NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + nr_rx_sdu(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + (uint8_t *)NULL, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } - + else { + LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); + nr_rx_sdu(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + } + printf("rx_indication_rel8.timing_advance %d\n", UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance); break; } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == From 0492f7eb7e50ad0191d2ba79edfb2baf9c1cb38e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 30 Aug 2019 17:14:34 +0200 Subject: [PATCH 073/343] Fix TBS condition in to schedule ue spec procedures --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7f309a8a3a..d2f6d805de 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -256,7 +256,7 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ //Sending SDUs with size 1 //Initialize elements of sdu_lcids and sdu_lengths //TODO this will be eventually be removed - while (TBS - header_length_total - sdu_length_total - ta_len >= 3){ + while (TBS >= 3 + header_length_total + sdu_length_total + ta_len){ if (k < NR_MAX_NB_RB && j < NR_MAX_NB_RB){ sdu_lcids[j] = 0x05; // DRB sdu_lengths[k] = 1; @@ -289,7 +289,7 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ if (ta_len + sdu_length_total + header_length_total > 0) { // Check if there is data from RLC or CE - if (TBS - header_length_total - sdu_length_total - ta_len >= 2) { + if (TBS >= 2 + header_length_total + sdu_length_total + ta_len) { // we have to consider padding // padding param currently not in use padding = TBS - header_length_total - sdu_length_total - ta_len - 1; From 5ac8b6f34d1459fe8080639fcdb2bf100c7587b5 Mon Sep 17 00:00:00 2001 From: Ahmed Hussein Date: Mon, 9 Sep 2019 16:49:15 +0200 Subject: [PATCH 074/343] TA implementation complete and tested in rfsimulator --- openair1/PHY/impl_defs_nr.h | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 19 ++++++++----------- openair1/SCHED_NR_UE/defs.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 15 ++++++++++++--- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 4 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 ++-- 7 files changed, 27 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 05e14f5e8d..cff2f02444 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 (0x05) #define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */ diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e353a51143..dd10ada2d6 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -268,10 +268,10 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // -------------------- nfapi_rx_indication_pdu_t *pdu; - int timing_advance_update; int sync_pos; + uint16_t mu = gNB->gNB_config.subframe_config.numerology_index_mu.value; // pthread_mutex_lock(&gNB->UL_INFO_mutex); // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; @@ -285,19 +285,16 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; // pdu->rx_indication_rel8.length = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->TBS>>3; // pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; - // estimate timing advance for MAC - sync_pos = nr_est_timing_advance_pusch(gNB, UE_id); - timing_advance_update = sync_pos; // - gNB->frame_parms.nb_prefix_samples/4; //to check + pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; + sync_pos = nr_est_timing_advance_pusch(gNB, UE_id); // estimate timing advance for MAC + timing_advance_update = sync_pos * (1 << mu); // scale by the used scs numerology + + // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size switch (gNB->frame_parms.N_RB_DL) { - // case 6: /* nothing to do */ break; - // case 15: timing_advance_update /= 2; break; - // case 25: timing_advance_update /= 4; break; - // case 50: timing_advance_update /= 8; break; - // case 75: timing_advance_update /= 12; break; case 106: timing_advance_update /= 16; break; case 217: timing_advance_update /= 32; break; + case 245: timing_advance_update /= 32; break; case 273: timing_advance_update /= 32; break; default: abort(); } @@ -308,7 +305,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, if (timing_advance_update < 0) timing_advance_update = 0; if (timing_advance_update > 63) timing_advance_update = 63; - printf("\x1B[33m" "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n" "\x1B[0m", sync_pos,timing_advance_update); + LOG_D(PHY, "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update); pdu->rx_indication_rel8.timing_advance = timing_advance_update; diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index cbcb936be3..66398c393e 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -295,7 +295,7 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); @param timing_advance TA command @param mu numerology index (0,1,2..) */ -void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t timing_advance, uint8_t mu); +void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t timing_advance, uint8_t mu, uint16_t bwp_ul_NB_RB); 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); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index bccc3a61b9..138f40790f 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1545,14 +1545,23 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR #endif -void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing_advance, uint8_t mu){ +void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing_advance, uint8_t mu, uint16_t bwp_ul_NB_RB){ // 3GPP TS 38.213 p4.2 - + // scale by the scs numerology int factor_mu = 1 << mu; + uint16_t bw_scaling; - //PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * 1024 / factor_mu ; + // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size + switch (bwp_ul_NB_RB) { + case 106: bw_scaling = 16; break; + case 217: bw_scaling = 32; break; + case 245: bw_scaling = 32; break; + case 273: bw_scaling = 32; break; + default: abort(); + } + PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * bw_scaling / factor_mu; LOG_D(PHY,"[UE %d] Got timing advance %u from MAC, new value is %u\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 57b418f945..f63620b1d0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2124,7 +2124,7 @@ void nr_ue_process_mac_pdu( NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; - + uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB; // For both DL/UL-SCH // Except: // - UL/DL-SCH: fixed-size MAC CE(known by LCID) @@ -2293,7 +2293,7 @@ void nr_ue_process_mac_pdu( LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ta_command, tag_id, CC_id); //if (nfapi_mode!=3){ // TODO check nfapi_mode - nr_process_timing_advance(module_idP, CC_id, ta_command, scs); + nr_process_timing_advance(module_idP, CC_id, ta_command, scs, bwp_ul_NB_RB); //} break; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index cc3f0c5001..4443dfdb20 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -177,7 +177,7 @@ nr_rx_sdu(const module_id_t gnb_mod_idP, */ //UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; UE_scheduling_control->ta_update = timing_advance; - printf("UE_scheduling_control->ta_update %u\n", UE_scheduling_control->ta_update); + // printf("UE_scheduling_control->ta_update %u\n", UE_scheduling_control->ta_update); // UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; // UE_scheduling_control->ul_consecutive_errors = 0; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 86a24bd8d6..ac072841f3 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -169,7 +169,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } } else { - printf("UL_info->rx_ind.rx_indication_body.number_of_pdus %d UL_info->crc_ind.crc_indication_body.number_of_crcs %d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->crc_ind.crc_indication_body.number_of_crcs); + // printf("UL_info->rx_ind.rx_indication_body.number_of_pdus %d UL_info->crc_ind.crc_indication_body.number_of_crcs %d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->crc_ind.crc_indication_body.number_of_crcs); if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) { for (int i=0; irx_ind.rx_indication_body.number_of_pdus; i++) { for (int j=0; jcrc_ind.crc_indication_body.number_of_crcs; j++) { @@ -205,7 +205,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } - printf("rx_indication_rel8.timing_advance %d\n", UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance); + //printf("rx_indication_rel8.timing_advance %d\n", UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance); break; } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == From c6855cb8d28525a9b66b2136303449ee11bac79c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 13 Sep 2019 18:15:11 +0200 Subject: [PATCH 075/343] Maintenance of Uplink Time Alignment. Introduced control on TA transmission and TA update application. - ta_timer at gNB side to control the transmission of TA to the UE. This is now happening every 20 slots. - when the timer resets gNB is now transmitting the TA whether it is zero or not. - introduced struct NR_UL_TIME_ALIGNMENT_t to handle configuration of time alignment related parameters. - UE PHY RX: is now triggered through a flag when to store the TA command, the frame and slot when the application should occur. - UE PHY TX: when the tx frame and slot match the time alignment configuration, it process the TA command and applies the TA update --- executables/nr-ue.c | 26 ++++++++- openair1/PHY/defs_nr_UE.h | 21 ++++++- openair1/SCHED_NR_UE/defs.h | 4 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 28 ++++++++-- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 5 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 26 +++++---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 55 +++++++++++-------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 8 files changed, 118 insertions(+), 48 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index fcbd659bbe..a781c5fdcd 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -461,6 +461,15 @@ void UE_processing(void *arg) { UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; processSlotRX(UE, proc); + uint8_t gNB_id = 0; + + // params for UL time alignment procedure + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id]; + uint8_t numerology = UE->frame_parms.numerology_index; + uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL; + int slot_tx = proc->nr_tti_tx; + int frame_tx = proc->frame_tx; + //printf(">>> mac ended\n"); // Prepare the future Tx data /* @@ -473,6 +482,21 @@ void UE_processing(void *arg) { #endif */ + /* UL time alignment + // If the current tx frame and slot match the TA configuration in ul_time_alignment + // then timing advance is processed and set to be applied in the next UL transmission */ + if (UE->mac_enabled == 1) { + + if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot){ + LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx); + + //if (nfapi_mode!=3){ + nr_process_timing_advance(UE->Mod_id, UE->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB); + ul_time_alignment->ta_frame = -1; + ul_time_alignment->ta_slot = -1; + //} + } + } if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD){ @@ -480,7 +504,7 @@ void UE_processing(void *arg) { if (UE->mode != loop_through_memory) - phy_procedures_nrUE_TX(UE,proc,0,thread_id); + phy_procedures_nrUE_TX(UE,proc,gNB_id,thread_id); } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 19f4365a29..663e005d65 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -871,6 +871,16 @@ typedef struct UE_NR_SCAN_INFO_s { int32_t freq_offset_Hz[3][10]; } UE_NR_SCAN_INFO_t; +typedef struct { + /// flag used by MAC to inform PHY about a TA to be applied + unsigned char apply_ta; + /// frame and slot when to apply the TA as stated in TS 38.213 setion 4.2 + int16_t ta_frame; + char ta_slot; + /// TA command and TAGID received from the gNB + uint8_t ta_command; + uint8_t tag_id; +} NR_UL_TIME_ALIGNMENT_t; #include "NR_IF_Module.h" @@ -1066,9 +1076,14 @@ typedef struct { int rx_offset; /// Timing offset int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP int time_sync_cell; - int timing_advance; ///timing advance signalled from eNB - int hw_timing_advance; - int N_TA_offset; ///timing offset used in TDD + + /// Timing Advance updates variables + /// Timing advance update computed from the TA command signalled from gNB + int timing_advance; + int hw_timing_advance; + int N_TA_offset; ///timing offset used in TDD + NR_UL_TIME_ALIGNMENT_t ul_time_alignment[NUMBER_OF_CONNECTED_gNB_MAX]; + /// Flag to tell if UE is secondary user (cognitive mode) unsigned char is_secondary_ue; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 66398c393e..4b4800398e 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -292,10 +292,10 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); /*! \brief Compute the timing adjustment at UE side from the old TA offset and the new received TA command @param Mod_id Local UE index on which to act @param CC_id Component Carrier Index - @param timing_advance TA command + @param ta_command TA command received from the network @param mu numerology index (0,1,2..) */ -void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t timing_advance, uint8_t mu, uint16_t bwp_ul_NB_RB); +void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB); 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); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 138f40790f..c4df96c56a 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1545,7 +1545,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR #endif -void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing_advance, uint8_t mu, uint16_t bwp_ul_NB_RB){ +void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){ // 3GPP TS 38.213 p4.2 // scale by the scs numerology @@ -1561,9 +1561,9 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing default: abort(); } - PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * bw_scaling / factor_mu; + PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu; - LOG_D(PHY,"[UE %d] Got timing advance %u from MAC, new value is %u\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); + LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %u\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); } void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, @@ -3545,6 +3545,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, uint16_t nb_symb_sch = 9; nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind; + // params for UL time alignment procedure + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id]; + unsigned char *apply_ta = &ul_time_alignment->apply_ta; + uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; + int ul_tx_timing_adjustment = 6; // temporary hardcoded if (dlsch0==NULL) AssertFatal(0,"dlsch0 should be defined at this level \n"); @@ -3850,7 +3855,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, nr_tti_rx, dlsch0->harq_processes[harq_pid]->b, dlsch0->harq_processes[harq_pid]->TBS>>3, - eNB_id); + eNB_id, + ul_time_alignment); break; case SI_PDSCH: /*ue_decode_si(ue->Mod_id, @@ -3880,6 +3886,20 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, AssertFatal(1==0,"exiting");*/ break; } + + /* Time alignment procedure set the TA to be applied 6 slots + // after the reception of the command */ + if (ul_time_alignment->apply_ta == 1){ + ul_time_alignment->ta_slot = (nr_tti_rx + ul_tx_timing_adjustment) % slots_per_frame; + if (nr_tti_rx + ul_tx_timing_adjustment > slots_per_frame){ + ul_time_alignment->ta_frame = (frame_rx + 1) % 1024; + } else { + ul_time_alignment->ta_frame = frame_rx; + } + // reset TA flag + ul_time_alignment->apply_ta = 0; + LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_tti_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); + } } /*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6cbe7b32c4..6e369ac274 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -137,14 +137,15 @@ uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t @returns void */ void nr_ue_send_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP, uint8_t ttiP, - uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index); + uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); void nr_ue_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, uint8_t *pduP, uint16_t mac_pdu_len, - uint8_t eNB_index); + uint8_t eNB_index, + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f63620b1d0..758d165cea 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2047,7 +2047,7 @@ void nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint8_t ttiP, - uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index){ + uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ printf("nr_ue_send_sdu frame %d\n", frameP); @@ -2094,7 +2094,7 @@ void nr_ue_send_sdu(module_id_t module_idP, // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index); + nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index, ul_time_alignment); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); @@ -2110,7 +2110,8 @@ void nr_ue_process_mac_pdu( uint8_t CC_id, uint8_t *pduP, uint16_t mac_pdu_len, - uint8_t eNB_index){ + uint8_t eNB_index, + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ // This function is adapting code from the old // parse_header(...) and ue_send_sdu(...) functions of OAI LTE @@ -2123,8 +2124,9 @@ void nr_ue_process_mac_pdu( uint16_t mac_sdu_len; NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); - uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; - uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB; + //uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; + //uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB; + // For both DL/UL-SCH // Except: // - UL/DL-SCH: fixed-size MAC CE(known by LCID) @@ -2280,9 +2282,12 @@ void nr_ue_process_mac_pdu( // 38.321 Ch6.1.3.4 mac_ce_len = 1; - uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND; + /*uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND; + uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID;*/ - uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID; + ul_time_alignment->apply_ta = 1; + ul_time_alignment->ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND; + ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID; /* #ifdef DEBUG_HEADER_PARSING @@ -2290,11 +2295,8 @@ void nr_ue_process_mac_pdu( #endif */ - LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ta_command, tag_id, CC_id); - - //if (nfapi_mode!=3){ // TODO check nfapi_mode - nr_process_timing_advance(module_idP, CC_id, ta_command, scs, bwp_ul_NB_RB); - //} + LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", + ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); break; case DL_SCH_LCID_CON_RES_ID: diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index d2f6d805de..3c654ac66c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -53,6 +53,7 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload, unsigned char drx_cmd, unsigned short timing_advance_cmd, NR_TAG_Id_t tag_id, + int ta_length, unsigned char *ue_cont_res_id, unsigned short post_padding){ @@ -76,25 +77,30 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload, } // Timing Advance subheader - if (timing_advance_cmd != 31) { + /* This was done only when timing_advance_cmd != 31 + // now TA is always send when ta_timer resets regardless of its value + // this is done to avoid issues with the timeAlignmentTimer which is + // supposed to monitor if the UE received TA or not */ + if (ta_length){ mac_pdu_ptr->R = 0; mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND; //last_size = 1; mac_pdu_ptr++; - // TA MAC CE (1 octet) + // TA MAC CE (1 octet) AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n", timing_advance_cmd); ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; LOG_D(MAC, "NR MAC CE timing advance command =%d (%d) TAG ID =%d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id); mac_ce_size = sizeof(NR_MAC_CE_TA); - + // Copying bytes for MAC CEs to the mac pdu pointer memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); ce_ptr += mac_ce_size; - mac_pdu_ptr += (unsigned char) mac_ce_size; - } + mac_pdu_ptr += (unsigned char) mac_ce_size; + } + // Contention resolution fixed subheader and MAC CE if (ue_cont_res_id) { @@ -199,35 +205,35 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ int UE_id = 0; // UE_list->head is -1 ! UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ta_update = ue_sched_ctl->ta_update; + //ta_update = ue_sched_ctl->ta_update; - for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP] + 1; CC_id++) { - LOG_D(MAC, "doing nr_schedule_ue_spec for CC_id %d\n", CC_id); + for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) { + LOG_D(MAC, "doing nr_schedule_ue_spec for UE_id %d CC_id %d frame %d slot %d\n", + UE_id, CC_id, frameP, slotP); dl_req = &gNB->DL_req[CC_id].dl_config_request_body; //for (UE_id = UE_list->head; UE_id >= -1; UE_id = UE_list->next[UE_id]) { - /* + // this was taken from the preprocessor + if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; + + /* //process retransmission if (round != 8) { - + } else { // This is a potentially new SDU opportunity */ - if (gNB->tag->timeAlignmentTimer != NULL) { - printf(" SHOULD NOT ENTER HERE \n"); - if (gNB->tag->timeAlignmentTimer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) - ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - } else { - ta_update = 31; - } - } + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if time is up, then set the timer to not send it for 20 NR_DOWNLINK_SLOT (20 frames) + // regardless of the TA value */ + ue_sched_ctl->ta_timer = 2; //set to 20 when transmission will be in every slot + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + ta_len = 2; + } // else ta_update = 31; - ta_len = (ta_update != 31) ? 2 : 0; + //ta_len = (ta_update != 31) ? 2 : 0; // retrieve TAG ID if(gNB->tag->tag_Id != NULL ){ @@ -307,6 +313,7 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ 255, // no drx ta_update, // timing advance tag_id, + ta_len, NULL, // contention res id post_padding); // Padding: fill remainder of DLSCH with 0 diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 185c866661..530911f359 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -79,6 +79,7 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload, unsigned char drx_cmd, unsigned short timing_advance_cmd, NR_TAG_Id_t tag_id, + int ta_length, unsigned char *ue_cont_res_id, unsigned short post_padding); From 0b873bb6207eee81c7407633ddaa403e878d0377 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 17 Sep 2019 17:35:48 +0200 Subject: [PATCH 076/343] Time Alignment procedure with time adjustment as per TS 38.213 section 4.2 - UE processing capability 1 - Setting the TA update to be applied after the reception of the TA command - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are computed according to sections 5.3 and 6.4 of TS 38.214 - Introduced tables 5.3-1, 5.3-2, 6.4-1, 6.4-2 from TS 38.214 --- openair1/PHY/INIT/nr_init_ue.c | 10 ++ openair1/PHY/impl_defs_nr.h | 10 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 80 ++++++++++++- .../SCHED_NR_UE/phy_sch_processing_time.h | 109 ++++++++++++++++++ 4 files changed, 203 insertions(+), 6 deletions(-) create mode 100644 openair1/SCHED_NR_UE/phy_sch_processing_time.h diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 0c7ce1cdd6..2658fbeeaa 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -703,11 +703,21 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeA; } + for (i=0;iPDSCH_Config.pdsch_TimeDomainResourceAllocation[i] = (NR_PDSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(NR_PDSCH_TimeDomainResourceAllocation_t)); + ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = typeA; + } + //------------- 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_maxLength = pusch_len1; //-------------------------------------------------// + ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1; + ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0; + ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1; + //-------------------------------------------------// + ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); pusch_dmrs = ue->nr_gold_pusch_dmrs; n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index cff2f02444..099ecd122a 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -36,6 +36,7 @@ #include #include "types.h" +#include "NR_PDSCH-TimeDomainResourceAllocation.h" #ifdef DEFINE_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H #define EXTERN @@ -377,8 +378,10 @@ typedef enum { ////////////////////////////////////////////////////////////////////////////////################################ -#define MAX_NR_RATE_MATCH_PATTERNS 4 -#define MAX_NR_ZP_CSI_RS_RESOURCES 32 +#define MAX_NR_RATE_MATCH_PATTERNS 4 +#define MAX_NR_ZP_CSI_RS_RESOURCES 32 +#define MAX_NR_OF_DL_ALLOCATIONS 16 +#define MAX_NR_OF_UL_ALLOCATIONS (16) typedef enum{ dl_resourceAllocationType0 = 1, @@ -473,6 +476,8 @@ typedef struct { */ maxNrofCodeWordsScheduledByDCI_t maxNrofCodeWordsScheduledByDCI; + NR_PDSCH_TimeDomainResourceAllocation_t *pdsch_TimeDomainResourceAllocation[MAX_NR_OF_DL_ALLOCATIONS]; + } PDSCH_Config_t; /*********************************************************************** @@ -483,7 +488,6 @@ typedef struct { * ************************************************************************/ -#define MAX_NR_OF_UL_ALLOCATIONS (16) typedef enum { enable_tpc_accumulation = 0, /* by default it is enable */ diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index c4df96c56a..f07e22a087 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -45,6 +45,7 @@ //#include "PHY/extern.h" #include "SCHED_NR_UE/defs.h" #include "SCHED_NR/extern.h" +#include "SCHED_NR_UE/phy_sch_processing_time.h" //#include //#include "targets/RT/USER/nr-softmodem.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" @@ -3549,7 +3550,17 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id]; unsigned char *apply_ta = &ul_time_alignment->apply_ta; uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; - int ul_tx_timing_adjustment = 6; // temporary hardcoded + uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe; + uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl; + int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1, d_2_1, d; + uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP + // TODO this should corresponds to the switching time as defined in + // TS 38.133 + uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; + uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples; + uint32_t t_subframe = 1; // subframe duration of 1 msec + uint16_t bw_scaling, start_symbol; + float tc_factor; if (dlsch0==NULL) AssertFatal(0,"dlsch0 should be defined at this level \n"); @@ -3558,6 +3569,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, harq_pid = dlsch0->current_harq_pid; is_cw0_active = dlsch0->harq_processes[harq_pid]->status; nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; + start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; @@ -3887,8 +3899,70 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, break; } - /* Time alignment procedure set the TA to be applied 6 slots - // after the reception of the command */ + // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size + switch (ue->frame_parms.N_RB_DL) { + case 106: bw_scaling = 16; break; + case 217: bw_scaling = 32; break; + case 245: bw_scaling = 32; break; + case 273: bw_scaling = 32; break; + default: abort(); + } + + /* Time Alignment procedure + // - UE processing capability 1 + // - Setting the TA update to be applied after the reception of the TA command + // - Timing adjustment computed according to TS 38.213 section 4.2 + // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are + // computed according to sections 5.3 and 6.4 of TS 38.214 */ + factor_mu = 1 << numerology; + N_TA_max = 3846 * bw_scaling / factor_mu; + + /* PDSCH decoding time N_1 for processing capability 1 */ + if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0) + N_1 = pdsch_N_1_capability_1[numerology][1]; + else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available + N_1 = pdsch_N_1_capability_1[numerology][2]; + else + N_1 = pdsch_N_1_capability_1[numerology][3]; + + /* PUSCH preapration time N_2 for processing capability 1 */ + N_2 = pusch_N_2_timing_capability_1[numerology][1]; + mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType; + mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; + + /* d_1_1 depending on the number of PDSCH symbols allocated */ + d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH + if (mapping_type_dl == typeA) + if (nb_symb_sch + start_symbol < 7) + d_1_1 = 7 - (nb_symb_sch + start_symbol); + else + d_1_1 = 0; + else // mapping type B + switch (nb_symb_sch){ + case 7: d_1_1 = 0; break; + case 4: d_1_1 = 3; break; + case 2: d_1_1 = 3 + d; break; + default: break; + } + + /* d_2_1 */ + if (mapping_type_ul == typeB && start_symbol != 0) + d_2_1 = 0; + else + d_2_1 = 1; + + /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time + // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */ + N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu; + N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu; + if (N_t_2 < d_2_2) N_t_2 = d_2_2; + + /* Time alignment procedure */ + // N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc + // N_t_1 + N_t_2 + N_TA_max must be in msec + tc_factor = 64 * 0.509 * 10e-7; + ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe); + if (ul_time_alignment->apply_ta == 1){ ul_time_alignment->ta_slot = (nr_tti_rx + ul_tx_timing_adjustment) % slots_per_frame; if (nr_tti_rx + ul_tx_timing_adjustment > slots_per_frame){ diff --git a/openair1/SCHED_NR_UE/phy_sch_processing_time.h b/openair1/SCHED_NR_UE/phy_sch_processing_time.h new file mode 100644 index 0000000000..1962df22ee --- /dev/null +++ b/openair1/SCHED_NR_UE/phy_sch_processing_time.h @@ -0,0 +1,109 @@ +/* + * 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 phy_sch_processing_time.h + \brief tables for UE PDSCH processing and UE PUSCH preparation procedure time + from TS 38.214 Physical procedures for data v15.6.0 + \author Guido Casati + \date 2019 + \version 0.1 + \company Fraunhofer IIS + \email: guido.casati@iis.fraunhofer.de + \note + \warning +*/ + +/* TS 38.214 Table 5.3-1: PDSCH processing time for PDSCH processing capability 1 +// corresponding to the PDSCH decoding time N_1 [symbols] +// where mu corresponds to the one of {mu_PDCCH, mu_PDSCH, mu_UL} +// resulting with the largest T_proc_1 +// where mu_PDCCH is the SCS of PDCCH scheduling PDSCH +// mu_PDSCH is the SCS of the scheduled PDSCH +// mu_UL is the SCS of the UL channel with which the HARQ-ACK is to be transmitted +// column A is N_1 corresponding to dmrs-AdditionalPosition pos0 in DMRS-DownlinkConfig +// in both dmrs-DownlinkForPDSCH-MappingTypeA and dmrs-DownlinkForPDSCH-MappingTypeB +// column B is N_1 corresponding to corresponds to dmrs-AdditionalPosition !0 +// in DMRS-DownlinkConfig in both dmrs-DownlinkForPDSCH-MappingTypeA, +// dmrs-DownlinkForPDSCH-MappingTypeB or if the higher layer param is not configured +// when PDSCH DM-RS position l1 for the additional DM-RS is l1 = 1,2 +// column C is N_1 corresponding to corresponds to dmrs-AdditionalPosition !0 +// in DMRS-DownlinkConfig in both dmrs-DownlinkForPDSCH-MappingTypeA, +// dmrs-DownlinkForPDSCH-MappingTypeB or if the higher layer param is not configured +// when PDSCH DM-RS position l1 for the additional DM-RS is != 1,2 + +*/ +int8_t pdsch_N_1_capability_1[4][4] = { +/* mu A B C */ +{ 0, 8, 14, 13 }, +{ 1, 10, 13, 13 }, +{ 2, 17, 20, 20 }, +{ 3, 20, 24, 24 }, +}; + +/* TS 38.214 Table 5.3-2: PDSCH processing time for PDSCH processing capability 2 +// corresponding to the PDSCH decoding time N_1 [symbols] +// where mu corresponds to the one of {mu_PDCCH, mu_PDSCH, mu_UL} +// resulting with the largest T_proc_1 +// where mu_PDCCH is the SCS of PDCCH scheduling PDSCH +// mu_PDSCH is the SCS of the scheduled PDSCH +// mu_UL is the SCS of the UL channel with which the HARQ-ACK is to be transmitted +// column A is N_1 corresponding to dmrs-AdditionalPosition pos0 in DMRS-DownlinkConfig in both +// dmrs-DownlinkForPDSCH-MappingTypeA and dmrs-DownlinkForPDSCH-MappingTypeB +// mu == 2 is for FR1 only +*/ +float pdsch_N_1_capability_2[3][2] = { +/* mu A */ +{ 0, 3 }, +{ 1, 4.5 }, +{ 2, 9 }, +}; + +/* TS 38.214 Table 6.4-1: PUSCH preparation time for PUSCH timing capability 1 +// corresponding to the PUSCH preparation time N_2 [symbols] +// where mu corresponds to the one of {mu_DL, mu_UL} +// resulting with the largest T_proc_2 +// where mu_DL is the SCS with which the PDCCH +// carrying the DCI scheduling the PUSCH was transmitted +// mu_UL is the SCS of the UL channel with which PUSCH to be transmitted +*/ +int8_t pusch_N_2_timing_capability_1[4][2] = { +/* mu N_2 */ +{ 0, 10 }, +{ 1, 12 }, +{ 2, 23 }, +{ 3, 36 }, +}; + +/* TS 38.214 Table 6.4-2: PUSCH preparation time for PUSCH timing capability 2 +// corresponding to the PUSCH preparation time N_2 [symbols] +// where mu corresponds to the one of {mu_DL, mu_UL} +// resulting with the largest T_proc_2 +// where mu_DL is the SCS with which the PDCCH +// carrying the DCI scheduling the PUSCH was transmitted +// mu_UL is the SCS of the UL channel with which PUSCH to be transmitted +// mu == 2 is for FR1 only +*/ +float pusch_N_2_timing_capability_2[3][2] = { +/* mu N_2 */ +{ 0, 5 }, +{ 1, 5.5 }, +{ 2, 11 }, +}; \ No newline at end of file From a0cd44947e086ca10ca7ea1742fde8ff344bdd02 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 18 Oct 2019 17:37:10 +0200 Subject: [PATCH 077/343] Bugfix uninitialised vars and conflicting types in simulators after merge --- openair1/SIMULATION/NR_PHY/dlschsim.c | 2 +- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair1/SIMULATION/NR_PHY/pbchsim.c | 2 +- openair1/SIMULATION/NR_PHY/pucchsim.c | 2 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 2 +- openair1/SIMULATION/NR_PHY/ulsim.c | 6 +++++- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index aab762b9e2..96b52790fc 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -56,7 +56,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int nfapi_mode = 0; +uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // needed for some functions diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index bf350cea71..e6dd10b91d 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -63,7 +63,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int nfapi_mode=0; +uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; //Dummy Functions diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index d312eb6f90..33bfc02f33 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -55,7 +55,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int nfapi_mode=0; +uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // needed for some functions diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 757f8abb03..6d590a2458 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -53,7 +53,7 @@ openair0_config_t openair0_cfg[MAX_CARDS]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int nfapi_mode=0; +uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // needed for some functions diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 07105e6e1f..98f6d9b312 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -55,7 +55,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int nfapi_mode = 0; +uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // needed for some functions diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 15e7d3ca0e..14167e1f97 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -64,7 +64,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int nfapi_mode = 0; +uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // dummy functions @@ -394,6 +394,10 @@ int main(int argc, char **argv) gNB = RC.gNB[0][0]; //gNB_config = &gNB->gNB_config; + //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); + gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); + gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; From cfbe18c9eded3b9d5a518e8aab8df74090702875 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 15 Oct 2019 23:46:34 +0200 Subject: [PATCH 078/343] Adaptation of MAC TA procedures to the design of handle_dlsch - introduced new parameter in nr_ue_dl_indication for UL time alignment - moved TA timer logic one level up so that now is executed every slot - set timer value to 80 slots to cope with the sl_ahead design - introduced new TA-related members to gNB MAC instance struct --- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 2 +- openair1/PHY/defs_nr_UE.h | 6 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 48 +--- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 223 +----------------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 26 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 71 +++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 26 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 4 + openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 32 +-- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h | 6 +- 12 files changed, 91 insertions(+), 361 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 1e17f6dab0..d76ffea9cf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -614,7 +614,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, rx_ind.number_pdus = 1; //rx_ind.number_pdus++; if (ue->if_inst && ue->if_inst->dl_indication) - ue->if_inst->dl_indication(&dl_indication); + ue->if_inst->dl_indication(&dl_indication, NULL); return 0; } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 663e005d65..d72979262c 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -871,12 +871,12 @@ typedef struct UE_NR_SCAN_INFO_s { int32_t freq_offset_Hz[3][10]; } UE_NR_SCAN_INFO_t; -typedef struct { +typedef struct NR_UL_TIME_ALIGNMENT { /// flag used by MAC to inform PHY about a TA to be applied unsigned char apply_ta; /// frame and slot when to apply the TA as stated in TS 38.213 setion 4.2 - int16_t ta_frame; - char ta_slot; + int16_t ta_frame; + char ta_slot; /// TA command and TAGID received from the gNB uint8_t ta_command; uint8_t tag_id; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f07e22a087..4bb81961fd 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -3161,7 +3161,7 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, dl_indication.dci_ind = &dci_ind; // send to mac - ue->if_inst->dl_indication(&dl_indication); + ue->if_inst->dl_indication(&dl_indication, NULL); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_rx_pdcch_stats); @@ -3368,7 +3368,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol; uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols; - LOG_I(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); + LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); for (m = s0; m < (s1 + s0); m++) { @@ -3535,7 +3535,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; int ret=0, ret1=0; - uint8_t CC_id = ue->CC_id; NR_UE_PDSCH *pdsch_vars; uint8_t is_cw0_active = 0; uint8_t is_cw1_active = 0; @@ -3548,7 +3547,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, fapi_nr_rx_indication_t rx_ind; // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id]; - unsigned char *apply_ta = &ul_time_alignment->apply_ta; uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe; uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl; @@ -3821,7 +3819,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dl_indication.dci_ind = NULL; //&ue->dci_ind; // send to mac if (ue->if_inst && ue->if_inst->dl_indication) - ue->if_inst->dl_indication(&dl_indication); + ue->if_inst->dl_indication(&dl_indication, ul_time_alignment); } // TODO CRC check for CW0 @@ -3858,46 +3856,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, }*/ if (ue->mac_enabled == 1) { - switch (pdsch) { - case PDSCH: - printf("PDSCH procedures\n"); - nr_ue_send_sdu(ue->Mod_id, - CC_id, - frame_rx, - nr_tti_rx, - dlsch0->harq_processes[harq_pid]->b, - dlsch0->harq_processes[harq_pid]->TBS>>3, - eNB_id, - ul_time_alignment); - break; - case SI_PDSCH: - /*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);*/ - break; - case P_PDSCH: - /*ue_decode_p(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);*/ - break; - case RA_PDSCH: - /*process_rar(ue,proc,eNB_id,mode,abstraction_flag);*/ - break; - case PDSCH1: - /*LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n"); - AssertFatal(1==0,"exiting");*/ - break; - case PMCH: - /*LOG_E(PHY,"Shouldn't have PMCH here\n"); - AssertFatal(1==0,"exiting");*/ - break; - } // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size switch (ue->frame_parms.N_RB_DL) { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6e369ac274..e74531da16 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -137,7 +137,7 @@ uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t @returns void */ void nr_ue_send_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP, uint8_t ttiP, - uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); + uint8_t * pdu, uint16_t pdu_len, uint8_t gNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); void nr_ue_process_mac_pdu( module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 758d165cea..c9b5a0c92e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2047,9 +2047,10 @@ void nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint8_t ttiP, - uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ + uint8_t * pdu, uint16_t pdu_len, uint8_t gNB_index, + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ - printf("nr_ue_send_sdu frame %d\n", frameP); + LOG_D(MAC, "Handling PDU frame %d slot %d\n", frameP, ttiP); // Changes wrt LTE: replaced subframeP with ttiP // TODO double check this and eventually create a type for TTI (tti_t) @@ -2077,8 +2078,8 @@ void nr_ue_send_sdu(module_id_t module_idP, /* #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n", - module_idP, frameP, eNB_index, num_ce, num_sdu); + LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d gNB_index %d : num_ce %d num_sdu %d\n", + module_idP, frameP, gNB_index, num_ce, num_sdu); #endif */ @@ -2094,7 +2095,7 @@ void nr_ue_send_sdu(module_id_t module_idP, // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index, ul_time_alignment); + nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, gNB_index, ul_time_alignment); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); @@ -2110,7 +2111,7 @@ void nr_ue_process_mac_pdu( uint8_t CC_id, uint8_t *pduP, uint16_t mac_pdu_len, - uint8_t eNB_index, + uint8_t gNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ // This function is adapting code from the old @@ -2411,213 +2412,3 @@ void nr_ue_process_mac_pdu( AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n"); } } - -//--------------------------------------------------------------------------------- - - -unsigned char *parse_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) -{ - - unsigned char not_done = 1, num_ces = 0, num_cont_res = - 0, num_padding = 0, num_sdus = 0, lcid, num_sdu_cnt; - unsigned char *mac_header_ptr = mac_header; - unsigned short length, ce_len = 0; - - while (not_done == 1) { - - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - // printf("E=0\n"); - not_done = 0; - } - - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - - if (lcid < UE_CONT_RES) { - //printf("[MAC][UE] header %x.%x.%x\n",mac_header_ptr[0],mac_header_ptr[1],mac_header_ptr[2]); - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = - tb_length - (mac_header_ptr - mac_header) - ce_len; - - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } - } else { - if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) { - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)-> - L_MSB & 0x7f) - << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)-> - L_LSB & 0xff); - mac_header_ptr += 3; -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] parse long sdu, size %x \n", length); -#endif - - } else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; - } - } - -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] sdu %d lcid %d length %d (offset now %ld)\n", - num_sdus, lcid, length, mac_header_ptr - mac_header); -#endif - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // This is a control element subheader - if (lcid == SHORT_PADDING) { - num_padding++; - mac_header_ptr++; - } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - - if (lcid == TIMING_ADV_CMD) { - ce_len++; - } else if (lcid == UE_CONT_RES) { - - // FNA: check MAC Header is one of thoses defined in Annex B of 36.321 - // Check there is only 1 Contention Resolution - if (num_cont_res) { - LOG_W(MAC, - "[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n"); - // exit parsing - return NULL; - - } - // UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader - if ((not_done == 0) - && ((num_sdus) || (num_ces > 1) || (num_padding))) { - LOG_W(MAC, - "[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n", - num_ces, num_sdus, num_padding); - // exit parsing - return NULL; - } - num_cont_res++; - ce_len += 6; - } - } - -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] ce %d lcid %d (offset now %ld)\n", num_ces, - lcid, mac_header_ptr - mac_header); -#endif - } - } - - *num_ce = num_ces; - *num_sdu = num_sdus; - - return (mac_header_ptr); -} - - -//------------------------------------------------------------------------------ -void -nr_ue_send_sdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - sub_frame_t subframeP, - uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index) -//------------------------------------------------------------------------------ -{ - - unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; - - - //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); - - - payload_ptr = - parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, - sdu_len); - -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, - "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n", - module_idP, frameP, eNB_index, num_ce, num_sdu); -#endif - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - - for (i = 0; i < 32; i++) { - LOG_T(MAC, "%x.", sdu[i]); - } - - LOG_T(MAC, "\n"); -#endif - - if (payload_ptr != NULL) { - - for (i = 0; i < num_ce; i++) { - // printf("ce %d : %d\n",i,rx_ces[i]); - switch (rx_ces[i]) { - case UE_CONT_RES: - - break; - - case TIMING_ADV_CMD: - - break; - - case DRX_CMD: - - break; - } - } - - for (i = 0; i < num_sdu; i++) { -#ifdef DEBUG_HEADER_PARSING - LOG_I(MAC, "[UE] SDU %d : LCID %d, length %d\n", i, - rx_lcids[i], rx_lengths[i]); -#endif - if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1)) { - - LOG_D(MAC, - "[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", - module_idP, frameP, rx_lcids[i], eNB_index, - rx_lengths[i]); - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing MAC PDU contents at slot: %d \n", subframeP); - int j; - for (j = 0; j < 20; j++) //rx_lengths[i] - LOG_I(MAC, "%x.", (unsigned char) payload_ptr[j]); - LOG_I(MAC, "\n"); -#endif - mac_rlc_data_ind(module_idP, - 4660, //UE_mac_inst[module_idP].crnti //hardcode value corresponding to the one from the eNB - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - rx_lcids[i], - (char *) payload_ptr, rx_lengths[i], 1, - NULL); - } else { - LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (eNB %d)\n", - module_idP, frameP, rx_lcids[i], eNB_index); - } - payload_ptr += rx_lengths[i]; - } - } // end if (payload_ptr != NULL) - -} - - - diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index fb5f9eccf1..502cf5c7f5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -299,12 +299,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, protocol_ctxt_t ctxt; - int CC_id, i = -1; - UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list; - rnti_t rnti; - - NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; - //nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL; + int CC_id, i = -1, UE_id = 0, ta_update; + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + UE_list_t *UE_list = &gNB->UE_list; + rnti_t rnti; + UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + NR_COMMON_channels_t *cc = gNB->common_channels; start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); @@ -372,6 +372,20 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // Phytest scheduling + // TODO once RACH is available, start ta_timer when UE is connected + if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; + + if (ue_sched_ctl->ta_timer == 0) { + gNB->ta_command = ue_sched_ctl->ta_update; + /* if time is up, then set the timer to not send it for 4 frames + // regardless of the TA value */ + ue_sched_ctl->ta_timer = 80; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + /* MAC CE flag indicating TA length */ + gNB->ta_len = 2; + } + if (slot_rxP == NR_UPLINK_SLOT){ nr_schedule_uss_ulsch_phytest(&RC.nrmac[module_idP]->UL_tti_req[0], frame_rxP, slot_rxP); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 3c654ac66c..a54e7e2765 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -45,22 +45,22 @@ #include "NR_TAG-Id.h" -int nr_generate_dlsch_pdu(unsigned char *sdus_payload, - unsigned char *mac_pdu, +int nr_generate_dlsch_pdu(module_id_t module_idP, + unsigned char *sdus_payload, + unsigned char *mac_pdu, unsigned char num_sdus, unsigned short *sdu_lengths, unsigned char *sdu_lcids, unsigned char drx_cmd, - unsigned short timing_advance_cmd, - NR_TAG_Id_t tag_id, - int ta_length, unsigned char *ue_cont_res_id, unsigned short post_padding){ + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; unsigned char * dlsch_buffer_ptr = sdus_payload; uint8_t last_size = 0; - int offset = 0, mac_ce_size, i; + int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0; // MAC CEs uint8_t mac_header_control_elements[16], *ce_ptr; @@ -81,24 +81,31 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload, // now TA is always send when ta_timer resets regardless of its value // this is done to avoid issues with the timeAlignmentTimer which is // supposed to monitor if the UE received TA or not */ - if (ta_length){ + if (gNB->ta_len){ mac_pdu_ptr->R = 0; mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND; //last_size = 1; mac_pdu_ptr++; // TA MAC CE (1 octet) + timing_advance_cmd = gNB->ta_command; AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n", timing_advance_cmd); ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; + if (gNB->tag->tag_Id != NULL){ + tag_id = gNB->tag->tag_Id; + ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; + } - LOG_D(MAC, "NR MAC CE timing advance command =%d (%d) TAG ID =%d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id); + LOG_D(MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id); mac_ce_size = sizeof(NR_MAC_CE_TA); // Copying bytes for MAC CEs to the mac pdu pointer memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); ce_ptr += mac_ce_size; mac_pdu_ptr += (unsigned char) mac_ce_size; + + // resetting ta flag + gNB->ta_len = 0; } @@ -191,7 +198,7 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ uint16_t sdu_lengths[NR_MAX_NB_RB] = {0}; int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0, ta_update; + int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0, ta_command; // hardcoded parameters // for DMRS configuration type 1 @@ -201,45 +208,27 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ uint16_t R = 697; uint16_t nb_rb = 50 ; uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs - NR_TAG_Id_t tag_id = 0; int UE_id = 0; // UE_list->head is -1 ! UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; //ta_update = ue_sched_ctl->ta_update; for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) { - LOG_D(MAC, "doing nr_schedule_ue_spec for UE_id %d CC_id %d frame %d slot %d\n", - UE_id, CC_id, frameP, slotP); + + LOG_D(MAC, "doing nr_schedule_ue_spec for UE_id %d CC_id %d frame %d slot %d\n", UE_id, CC_id, frameP, slotP); + dl_req = &gNB->DL_req[CC_id].dl_config_request_body; //for (UE_id = UE_list->head; UE_id >= -1; UE_id = UE_list->next[UE_id]) { - // this was taken from the preprocessor - if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; - /* //process retransmission if (round != 8) { } else { // This is a potentially new SDU opportunity */ - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if time is up, then set the timer to not send it for 20 NR_DOWNLINK_SLOT (20 frames) - // regardless of the TA value */ - ue_sched_ctl->ta_timer = 2; //set to 20 when transmission will be in every slot - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - ta_len = 2; - } // else ta_update = 31; - //ta_len = (ta_update != 31) ? 2 : 0; - // retrieve TAG ID - if(gNB->tag->tag_Id != NULL ){ - tag_id = gNB->tag->tag_Id; - } - // fill dlsch_buffer with random data for (i = 0; i < MAX_NR_DLSCH_PAYLOAD_BYTES; i++){ dlsch_buffer[i] = (unsigned char) rand(); @@ -305,17 +294,15 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ } - offset = nr_generate_dlsch_pdu((unsigned char *) dlsch_buffer, - (unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - num_sdus, //num_sdus - sdu_lengths, - sdu_lcids, - 255, // no drx - ta_update, // timing advance - tag_id, - ta_len, - NULL, // contention res id - post_padding); + offset = nr_generate_dlsch_pdu(module_idP, + (unsigned char *) dlsch_buffer, + (unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + num_sdus, //num_sdus + sdu_lengths, + sdu_lcids, + 255, // no drx + NULL, // contention res id + post_padding); // Padding: fill remainder of DLSCH with 0 if (post_padding > 0){ for (int j = 0; j < (TBS - offset); j++) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index ea3ee86db1..2fe9558759 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -390,25 +390,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, post_padding = 1; } - offset = generate_dlsch_header((unsigned char *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0], //DLSCH_pdu.payload[0], - num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); - LOG_D(MAC, "Offset bits: %d \n", offset); - // Probably there should be other actions done before that - // cycle through SDUs and place in dlsch_buffer - //memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); - memcpy(&nr_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); - - // fill remainder of DLSCH with 0 - for (int j = 0; j < (TBS - sdu_length_total - offset); j++) { - //UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; - nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0][offset + sdu_length_total + j] = 0; - } - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config); #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, , TBS size: %d \n \n", frameP, slotP, TBS_bytes); @@ -432,11 +413,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, else { TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config); - for(int i = 0; i < TBS_bytes; i++) { // - ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i] = (unsigned char) rand(); - //LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) if (frameP%100 == 0) { @@ -451,11 +427,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //TX_req->segments[0].segment_length = 8; TX_req->segments[0].segment_length = TBS_bytes +2; TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - } } //for (CC_id=0; CC_idmodule_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind, (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu, - (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH; + (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot,ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_DLSCH; LOG_I(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 5873c84d8f..e46ae2103f 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -37,7 +37,7 @@ #include #include "fapi_nr_ue_interface.h" - +typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t; typedef struct { /// module id @@ -163,7 +163,7 @@ typedef int8_t (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config); * -1: Failed to consume bytes. Abort the mission. * Non-negative return values indicate success, and ignored. */ -typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info); +typedef int (nr_ue_dl_indication_f)(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); /* * Generic type of an application-defined callback to return various @@ -202,7 +202,7 @@ int nr_ue_if_module_kill(uint32_t module_id); /**\brief interface between L1/L2, indicating the downlink related information, like dci_ind and rx_req \param dl_info including dci_ind and rx_request messages*/ -int nr_ue_dl_indication(nr_downlink_indication_t *dl_info); +int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); int nr_ue_ul_indication(nr_uplink_indication_t *ul_info); From 98d2caf59f1b9caf04b69f2af63359cf1292fa03 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 24 Oct 2019 16:04:20 +0200 Subject: [PATCH 079/343] Added compilation option to skip build for already built libraries: - the new option -k allows to skip the built of shared libraries, rfsimulator basicsimulator and transport protocol libraries - default compilation remains untouched as is still building all libraries - this option allows to save a massive amount of time when compiling repeatedly for debugging purposes --- cmake_targets/build_oai | 70 ++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 227e8d888d..595d94bbb8 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -40,6 +40,7 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf MSC_GEN=0 XFORMS="True" +SKIP_SHARED_LIB_FLAG="False" UE_EXPANSION="False" UESIM_EXPANSION="False" PRINT_STATS="False" @@ -152,6 +153,8 @@ Options Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES or \"all\" --usrp-recplay Build for I/Q record-playback modes +-k | --skip-shared-libraries + Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes -h | --help Print this help @@ -367,6 +370,10 @@ function main() { USRP_REC_PLAY="True" echo_info "Enabling USRP record playback mode" shift 1;; + -k | --skip-shared-libraries) + SKIP_SHARED_LIB_FLAG="True" + echo_info "Skipping build of shared libraries, rfsimulator, basicsimulator and transport protocol libraries" + shift;; -h | --help) print_help exit 1;; @@ -558,6 +565,7 @@ function main() { echo "set ( UE_DEBUG_TRACE $UE_DEBUG_TRACE )" >> $cmake_file echo "set ( UE_TIMING_TRACE $UE_TIMING_TRACE )" >> $cmake_file echo "set ( USRP_REC_PLAY $USRP_REC_PLAY )" >> $cmake_file + echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$build_dir/build eval $CMAKE_CMD @@ -587,6 +595,9 @@ function main() { # mandatory shared libraries common to UE and (e/g)NB + if [ "$SKIP_SHARED_LIB_FLAG" = "False" ]; then + echo_info "Building shared libraries common to UE and gNB" + compilations \ $build_dir $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so @@ -595,14 +606,16 @@ function main() { $build_dir coding \ libcoding.so $dbin/libcoding.so - compilations \ - $build_dir nasmesh \ - CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko + compilations \ + $build_dir nasmesh \ + CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko + + compilations \ + $build_dir rb_tool \ + rb_tool $dbin/rb_tool + cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin + fi - compilations \ - $build_dir rb_tool \ - rb_tool $dbin/rb_tool - cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin fi if [ "$UE" = 1 ] ; then @@ -848,28 +861,33 @@ function main() { echo_info "liboai_device.so is not linked to any device library" fi fi - + #build simulators devices - echo_info "Compiling rfsimulator" - compilations \ - $build_dir rfsimulator \ - librfsimulator.so $dbin/librfsimulator.so.$REL - - echo_info "Compiling basicsimulator" - compilations \ - $build_dir tcp_bridge_oai \ - libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL + if [ "$SKIP_SHARED_LIB_FLAG" = "False" ]; then + echo_info "Compiling rfsimulator" + compilations \ + $build_dir rfsimulator \ + librfsimulator.so $dbin/librfsimulator.so.$REL + + echo_info "Compiling basicsimulator" + compilations \ + $build_dir tcp_bridge_oai \ + libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL + fi #build transport protocol libraries (currently only ETHERNET is available) - rm -f liboai_transpro.so - rm -f $dbin/liboai_transpro.so - compilations \ - $build_dir oai_eth_transpro \ - liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL - ln -sf liboai_eth_transpro.so liboai_transpro.so - ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so - echo_info "liboai_transpro.so is linked to ETHERNET transport" - fi + if [ "$SKIP_SHARED_LIB_FLAG" = "False" ]; then + echo_info "Building transport protocol libraries" + rm -f liboai_transpro.so + rm -f $dbin/liboai_transpro.so + compilations \ + $build_dir oai_eth_transpro \ + liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL + ln -sf liboai_eth_transpro.so liboai_transpro.so + ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so + echo_info "liboai_transpro.so is linked to ETHERNET transport" + fi + fi ################### # Doxygen Support # From 361446fda552967339975026d16b0fc29c1e983d Mon Sep 17 00:00:00 2001 From: cig Date: Fri, 8 Nov 2019 15:37:29 +0100 Subject: [PATCH 080/343] Consolidation of TA updates changes in the noS1 mode: - merged nr-schedule_ue_spec into nr_schedule_uss_dlsch_phytest - enabled nr_ue_send_sdu for S1 mode - increased ta_timer to 100 - restored NR_UPLINK_SLOT to 2 (as it was in develop-nr) - fixed logic for S1 and noS1 modes - code cleanup and formatting --- openair1/PHY/impl_defs_nr.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 3 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 9 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 148 +-------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 291 ++++++++++-------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 8 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 3 +- 8 files changed, 186 insertions(+), 280 deletions(-) diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 099ecd122a..7c9ee9fe47 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -120,7 +120,7 @@ SystemInformationBlockType1_nr_t; #define NR_TDD_SET_ALL_SYMBOLS (0x3FFF) #define NR_DOWNLINK_SLOT (0x01) -#define NR_UPLINK_SLOT (0x05) +#define NR_UPLINK_SLOT (0x02) #define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index c9b5a0c92e..761677bafa 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2296,8 +2296,7 @@ void nr_ue_process_mac_pdu( #endif */ - LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", - ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); + LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); break; case DL_SCH_LCID_CON_RES_ID: diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 502cf5c7f5..ab7757164f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -299,7 +299,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, protocol_ctxt_t ctxt; - int CC_id, i = -1, UE_id = 0, ta_update; + int CC_id, i = -1, UE_id = 0; gNB_MAC_INST *gNB = RC.nrmac[module_idP]; UE_list_t *UE_list = &gNB->UE_list; rnti_t rnti; @@ -377,9 +377,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (ue_sched_ctl->ta_timer == 0) { gNB->ta_command = ue_sched_ctl->ta_update; - /* if time is up, then set the timer to not send it for 4 frames + /* if time is up, then set the timer to not send it for 5 frames // regardless of the TA value */ - ue_sched_ctl->ta_timer = 80; + ue_sched_ctl->ta_timer = 100; /* reset ta_update */ ue_sched_ctl->ta_update = 31; /* MAC CE flag indicating TA length */ @@ -391,8 +391,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } if (slot_txP == NR_DOWNLINK_SLOT){ - nr_schedule_ue_spec(module_idP, frame_txP, slot_txP); nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); + // resetting ta flag + gNB->ta_len = 0; } /* diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index a54e7e2765..df194d5452 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -103,9 +103,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); ce_ptr += mac_ce_size; mac_pdu_ptr += (unsigned char) mac_ce_size; - - // resetting ta flag - gNB->ta_len = 0; } @@ -179,147 +176,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, return offset; } -/*TODO expand the scheduling functionalities -this function is just generating a dummy MAC PDU and is used to transmit the TA -The structure of the algorithm is taken from the schedule_ue_spec function in LTE -and is preserved for future reference.*/ -void -nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ - - - gNB_MAC_INST *gNB = RC.nrmac[module_idP]; - UE_list_t *UE_list = &gNB->UE_list; - nfapi_nr_dl_config_request_body_t *dl_req; - - // TODO size corretly the arrays - // at present, preserved the array length from lte code - // however not sure why NR_MAX_NB_RB was used here - unsigned char sdu_lcids[NR_MAX_NB_RB] = {0}; - uint16_t sdu_lengths[NR_MAX_NB_RB] = {0}; - - int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int CC_id, sub_pdu_id, lcid, offset, i, j=0, k=0, ta_command; - - // hardcoded parameters - // for DMRS configuration type 1 - // sdus should come from RLC - static unsigned char dlsch_buffer[MAX_NR_DLSCH_PAYLOAD_BYTES]; - uint8_t Qm = 2; - uint16_t R = 697; - uint16_t nb_rb = 50 ; - uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs - int UE_id = 0; // UE_list->head is -1 ! - - UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - //ta_update = ue_sched_ctl->ta_update; - - for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) { - - LOG_D(MAC, "doing nr_schedule_ue_spec for UE_id %d CC_id %d frame %d slot %d\n", UE_id, CC_id, frameP, slotP); - - dl_req = &gNB->DL_req[CC_id].dl_config_request_body; - - //for (UE_id = UE_list->head; UE_id >= -1; UE_id = UE_list->next[UE_id]) { - - /* - //process retransmission - if (round != 8) { - - } else { // This is a potentially new SDU opportunity */ - - //ta_len = (ta_update != 31) ? 2 : 0; - - // fill dlsch_buffer with random data - for (i = 0; i < MAX_NR_DLSCH_PAYLOAD_BYTES; i++){ - dlsch_buffer[i] = (unsigned char) rand(); - } - - /* - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - //TODO this will be eventually be removed - for (j = 0; j < NB_RB_MAX; j++){ - sdu_lcids[j] = 0x05; // DRB - } - - for (k = 0; k < NB_RB_MAX; k++){ - sdu_lengths[k] = 1; - header_length_total += 2; - sdu_length_total += 1; - }*/ - - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - //TODO this will be eventually be removed - while (TBS >= 3 + header_length_total + sdu_length_total + ta_len){ - if (k < NR_MAX_NB_RB && j < NR_MAX_NB_RB){ - sdu_lcids[j] = 0x05; // DRB - sdu_lengths[k] = 1; - header_length_total += 2; - sdu_length_total += 1; - num_sdus +=1; - k++, j++; - } - else { - break; - } - } - - /* - // RLC data on DCCH - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - } - - // RLC data on DCCH1 - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - } - - // looping over lcid - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // here sdu_lcids[num_sdus] is populated - }*/ - - // there is at least one SDU or TA command - // if (num_sdus > 0 ){ - if (ta_len + sdu_length_total + header_length_total > 0) { - - // Check if there is data from RLC or CE - if (TBS >= 2 + header_length_total + sdu_length_total + ta_len) { - // we have to consider padding - // padding param currently not in use - padding = TBS - header_length_total - sdu_length_total - ta_len - 1; - post_padding = 1; - } else { - post_padding = 0; - } - - - offset = nr_generate_dlsch_pdu(module_idP, - (unsigned char *) dlsch_buffer, - (unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - num_sdus, //num_sdus - sdu_lengths, - sdu_lcids, - 255, // no drx - NULL, // contention res id - post_padding); - // Padding: fill remainder of DLSCH with 0 - if (post_padding > 0){ - for (int j = 0; j < (TBS - offset); j++) - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + j] = 0; - } - - // Printing bit by bit for debugging purpose - /*for (int k = 0; k < TBS; k++){ - printf("MAC PDU %u\n",((( UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][k/8]) & (1 << (k & 7))) >> (k & 7))); - if ((k+1)%8 == 0) - printf("\n"); - }*/ - - } - else { // There is no data from RLC or MAC header, so don't schedule - } - //} - //} // UE_id loop - } // CC_id loop +/* functionalities of this function have been moved to nr_schedule_uss_dlsch_phytest */ +void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 2fe9558759..c93b7a7b9d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -260,68 +260,70 @@ int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, return TBS/8; //Return TBS in bytes } - - - - - - void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config) { - LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n"); - uint8_t CC_id; - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - //NR_COMMON_channels_t *cc = nr_mac->common_channels; - nfapi_nr_dl_config_request_body_t *dl_req; - nfapi_tx_request_pdu_t *TX_req; - uint16_t rnti = 0x1234; - nfapi_nr_config_request_t *cfg = &nr_mac->config[0]; - uint16_t sfn_sf = frameP << 7 | slotP; - // everything here is hard-coded to 30 kHz - //int scs = get_dlscs(cfg); - //int slots_per_frame = get_spf(cfg); - int TBS; - int TBS_bytes; - int lcid; - int ta_len = 0; - int header_length_total=0; - int header_length_last; - int sdu_length_total = 0; - mac_rlc_status_resp_t rlc_status; - uint16_t sdu_lengths[NB_RB_MAX]; - int num_sdus = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - int offset; - int UE_id = 0; - unsigned char sdu_lcids[NB_RB_MAX]; - int padding = 0, post_padding = 0; - UE_list_t *UE_list = &nr_mac->UE_list; - DLSCH_PDU DLSCH_pdu; - //DLSCH_PDU *DLSCH_pdu = (DLSCH_PDU*) malloc(sizeof(DLSCH_PDU)); - for (CC_id=0; CC_idDL_req[CC_id].dl_config_request_body; - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; + gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; + UE_list_t *UE_list = &gNB_mac->UE_list; + nfapi_nr_dl_config_request_body_t *dl_req; + nfapi_tx_request_pdu_t *TX_req; + mac_rlc_status_resp_t rlc_status; + nfapi_nr_config_request_t *cfg = &gNB_mac->config[0]; + + // TODO not sure why NR_MAX_NB_RB was used here + unsigned char sdu_lcids[NB_RB_MAX] = {0}; + uint16_t sdu_lengths[NB_RB_MAX] = {0}; + + int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; + int CC_id, lcid, offset, i, j=0, k=0, header_length_last, TBS_bytes; + + // hardcoded parameters to 30 kHz + // for DMRS configuration type 1 + unsigned char dlsch_buffer[MAX_NR_DLSCH_PAYLOAD_BYTES]; + uint8_t Qm = 2; + uint16_t R = 697; + uint16_t nb_rb = 50; + uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs + int UE_id = 0; // UE_list->head is -1 ! + uint16_t rnti = 0x1234; + uint16_t sfn_sf = frameP << 7 | slotP; + + UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + //ta_update = ue_sched_ctl->ta_update; + + for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) { + + LOG_D(MAC, "Scheduling UE specific search space DCI type 1 for UE_id %d CC_id %d frame %d slot %d\n", UE_id, CC_id, frameP, slotP); + + dl_req = &gNB_mac->DL_req[CC_id].dl_config_request_body; + TX_req = &gNB_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; + ta_len = gNB_mac->ta_len; //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving //through the LTE stack - if (IS_SOFTMODEM_NOS1) { - memset(&DLSCH_pdu, 0, sizeof(DLSCH_pdu)); - int ta_update = 31; - ta_len = 0; + if (IS_SOFTMODEM_NOS1){ + + // Hardcode it for now - TBS = 6784/8; //TBS in bytes + //TBS = 6784/8; //TBS in bytes //nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); //TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size; + /* TODO + // RLC data on DCCH + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + }*/ + + /* TODO + // RLC data on DCCH1 + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + }*/ + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TODO: check if the lcid is active - LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_length_total - sdu_length_total - 3); + LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, TBS - ta_len - header_length_total - sdu_length_total - 3); if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, @@ -337,103 +339,148 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, 0); if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", - module_idP, frameP, - TBS - ta_len - header_length_total - sdu_length_total - 3, - lcid, - header_length_total, - TBS); + LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", + module_idP, frameP, TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, header_length_total, TBS); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS, - (char *)&dlsch_buffer[sdu_length_total], - 0, - 0); - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, + (char *)&dlsch_buffer[sdu_length_total], + 0, + 0); + + LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; + num_sdus++; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + + ue_sched_ctl->uplane_inactivity_timer = 0; } - } else { - // no TBS left + } else { // no TBS left + break; + } + } + + // // last header does not have length field + // if (header_length_total) { + // header_length_total -= header_length_last; + // header_length_total++; + // } + + } //if (IS_SOFTMODEM_NOS1) + else { + //When the --NOS1 option is not enabled, DLSCH transmissions with random data + //occur every time that the current function is called (dlsch phytest mode) + + // fill dlsch_buffer with random data + for (i = 0; i < MAX_NR_DLSCH_PAYLOAD_BYTES; i++){ + dlsch_buffer[i] = (unsigned char) rand(); + } + + //Sending SDUs with size 1 + //Initialize elements of sdu_lcids and sdu_lengths + //TODO this will be eventually be removed + while (TBS >= 3 + header_length_total + sdu_length_total + ta_len){ + if (k < NR_MAX_NB_RB && j < NR_MAX_NB_RB){ + sdu_lcids[j] = 0x05; // DRB + sdu_lengths[k] = 1; + header_length_total += 2; + sdu_length_total += 1; + num_sdus +=1; + k++, j++; + } + else { break; } } + } // else IS_SOFTMODEM_NOS1 - // last header does not have length field - if (header_length_total) { - header_length_total -= header_length_last; - header_length_total++; + // there is at least one SDU or TA command + // if (num_sdus > 0 ){ + if (ta_len + sdu_length_total + header_length_total > 0) { + + // Check if there is data from RLC or CE + if (TBS >= 2 + header_length_total + sdu_length_total + ta_len) { + // we have to consider padding + // padding param currently not in use + padding = TBS - header_length_total - sdu_length_total - ta_len - 1; + post_padding = 1; + } else { + padding = 0; + post_padding = 0; } - if (ta_len + sdu_length_total + header_length_total > 0) { - if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { - padding = TBS - header_length_total - sdu_length_total - ta_len; - post_padding = 0; - } else { - padding = 0; - post_padding = 1; - } - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config); -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, , TBS size: %d \n \n", frameP, slotP, TBS_bytes); + offset = nr_generate_dlsch_pdu(module_idP, + (unsigned char *) dlsch_buffer, + (unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + num_sdus, //num_sdus + sdu_lengths, + sdu_lcids, + 255, // no drx + NULL, // contention res id + post_padding); - for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 - LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - -#endif - //TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_length = TBS_bytes +2; - TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - } //if (ta_len + sdu_length_total + header_length_total > 0) - } //if (IS_SOFTMODEM_NOS1) - //When the --NOS1 option is not enabled, DLSCH transmissions with random data - //occur every time that the current function is called (dlsch phytest mode) - else { - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config); - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - - if (frameP%100 == 0) { - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); - - for(int i = 0; i < 10; i++) { - LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } + // Padding: fill remainder of DLSCH with 0 + if (post_padding > 0){ + for (int j = 0; j < (TBS - offset); j++) + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + j] = 0; } -#endif + TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], gNB_mac->pdu_index[CC_id], dlsch_config); + //TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_length = TBS_bytes +2; - TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + TX_req->segments[0].segment_length = TBS_bytes + 2; + TX_req->segments[0].segment_data = gNB_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; + gNB_mac->TX_req[CC_id].sfn_sf = sfn_sf; + gNB_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + gNB_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + if(IS_SOFTMODEM_NOS1){ + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n \n", frameP, slotP, TBS_bytes); + for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 + LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0])[i]); + } + #endif + } else { + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + if (frameP%100 == 0){ + LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); + for(int i = 0; i < 10; i++) { + LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0])[i]); + } + } + #endif + } + // Printing bit by bit for debugging purpose + /*for (int k = 0; k < TBS; k++){ + printf("MAC PDU %u\n",((( UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][k/8]) & (1 << (k & 7))) >> (k & 7))); + if ((k+1)%8 == 0) + printf("\n"); + }*/ } - } //for (CC_id=0; CC_idUE_list; + gNB_mac = RC.nrmac[gnb_mod_idP]; + UE_list = &gNB_mac->UE_list; + // harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); // memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char)); @@ -176,6 +177,7 @@ nr_rx_sdu(const module_id_t gnb_mod_idP, * NR: smoothing removed */ //UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; + UE_scheduling_control->ta_update = timing_advance; // printf("UE_scheduling_control->ta_update %u\n", UE_scheduling_control->ta_update); // UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e6c0020e10..27e3e1921e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -118,7 +118,7 @@ typedef struct gNB_MAC_INST_s { int ta_command; /// MAC CE flag indicating TA length int ta_len; - /// Common cell resources + /// Common cell resources NR_COMMON_channels_t common_channels[NFAPI_CC_MAX]; /// current PDU index (BCH,DLSCH) uint16_t pdu_index[NFAPI_CC_MAX]; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 2f75e814cd..67b73f60c1 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -74,7 +74,8 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr // L2 Abstraction Layer int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, uint8_t *pduP, uint32_t pdu_len, frame_t frame, int slot, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ - if (IS_SOFTMODEM_NOS1 || IS_SOFTMODEM_RFSIM) + //if (IS_SOFTMODEM_NOS1 || IS_SOFTMODEM_RFSIM) + // sdu should be processed even when is S1 mode because data and timing advance updates are transmitted by the UE nr_ue_send_sdu(module_id, cc_id, frame, slot, pduP, pdu_len, From d34d269d70762fc5b52b4a518bb3ed8eb4668b91 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 26 Nov 2019 10:49:00 +0100 Subject: [PATCH 081/343] reducing the use of rand() which takes too long --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index c93b7a7b9d..6be0e25ff9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -388,9 +388,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //When the --NOS1 option is not enabled, DLSCH transmissions with random data //occur every time that the current function is called (dlsch phytest mode) + // fill dlsch_buffer with random data - for (i = 0; i < MAX_NR_DLSCH_PAYLOAD_BYTES; i++){ - dlsch_buffer[i] = (unsigned char) rand(); + for (i = 0; i < TBS/8; i++){ + dlsch_buffer[i] = (unsigned char) rand(); //i&0xFF; } //Sending SDUs with size 1 From 030fc5a2f581923f15399ae3d13f055aeb0d3119 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 28 Nov 2019 15:54:02 +0100 Subject: [PATCH 082/343] Bugfix segmentation fault in dlsim for missing memory allocation --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index e6dd10b91d..1cdf186c8e 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -552,6 +552,7 @@ int main(int argc, char **argv) nr_gold_pdcch(UE,0,2); RC.nb_nr_macrlc_inst = 1; + RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; From 7e738c2c396a439db2e8a44f608f70c715ccd90d Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 29 Nov 2019 11:46:09 +0100 Subject: [PATCH 083/343] Further fix segmentation fault by also initializing the allocated memory --- openair1/SIMULATION/NR_PHY/dlsim.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1cdf186c8e..a1fbdc8161 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -553,6 +553,8 @@ int main(int argc, char **argv) RC.nb_nr_macrlc_inst = 1; RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); + for (i = 0; i < RC.nb_nr_macrlc_inst; i++) + RC.nb_nr_mac_CC[i] = 1; mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; From 7bdff76ff372a2816bd9fda34cf3e0c9d3c39138 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 29 Nov 2019 12:01:50 +0100 Subject: [PATCH 084/343] Fix autotest tags for nr_dlsim and polartest --- cmake_targets/autotests/test_case_list.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index a407171d01..be699aeba9 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1045,7 +1045,7 @@ $OPENAIR_DIR/targets/bin/polartest.Rel15 -q -s-10 -f0 -q -s-10 -f0 -m1 - polartest.test1 + polartest.test1 polartest.test2 BLER= 0.000000 segmentation fault|assertion|exiting|fatal 3 @@ -1107,8 +1107,7 @@ -n100 -R217 -a80 -n100 -R217 -a80 -b100 -n100 -e28 - nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 - nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 + nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 PDSCH test OK segmentation fault|assertion|exiting|fatal 3 From ad82602e9a4f1b0b1bc59f2b1a79ea27753effb0 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 6 Dec 2019 14:16:43 +0100 Subject: [PATCH 085/343] ENDC X2AP: Implementation of SgNB Addition Request ACK --- openair2/RRC/NR/rrc_gNB_internode.c | 9 +- openair2/RRC/NR/rrc_gNB_nsa.c | 9 +- openair2/X2AP/x2ap_eNB_generate_messages.c | 124 +++++++++++++++++++-- 3 files changed, 130 insertions(+), 12 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c index 93d4e999d4..6cc4615ac3 100644 --- a/openair2/RRC/NR/rrc_gNB_internode.c +++ b/openair2/RRC/NR/rrc_gNB_internode.c @@ -85,13 +85,15 @@ int generate_CG_Config(gNB_RRC_INST *rrc, cg_Config->criticalExtensions.choice.c1->present = NR_CG_Config__criticalExtensions__c1_PR_cg_Config; cg_Config->criticalExtensions.choice.c1->choice.cg_Config = calloc(1,sizeof(NR_CG_Config_IEs_t)); char buffer[1024]; + int total_size; asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RRCReconfiguration, NULL, (void *)reconfig, buffer, 1024); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig = calloc(1,sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig, (const char *)buffer, - (enc_rval.encoded+7)>>3); + (enc_rval.encoded+7)>>3); + total_size = (enc_rval.encoded+7)>>3; LOG_I(RRC,"Dumping NR_RRCReconfiguration message (%jd bytes)\n",(enc_rval.encoded+7)>>3); for (int i=0;i<(enc_rval.encoded+7)>>3;i++) { @@ -117,8 +119,11 @@ int generate_CG_Config(gNB_RRC_INST *rrc, fd = fopen("rbconfig.raw","w"); fwrite((void*)buffer,1,(size_t)((enc_rval.encoded+7)>>3),fd); fclose(fd); + total_size = total_size + ((enc_rval.encoded+7)>>3); - return(0); + LOG_I(RRC, "Total size in generate_CG_Config(): %d \n", total_size); + + return(total_size); } #endif diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 69080cdd20..6353a32927 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -106,7 +106,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ MessageDef *msg; msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = 2048; //Need to verify correct value for the buffer_size // NR RRCReconfiguration @@ -133,14 +132,18 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void*)CG_Config,0,sizeof(*CG_Config)); - generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size // Send to X2 entity to transport to MeNB asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, NULL, (void *)CG_Config, X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size); + 1024); + + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3; + LOG_I(RRC, "Total size in rrc_add_nsa_user(): %d \n", (enc_rval.encoded+7)>>3); itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 156bb1fc45..3bff59882e 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1525,7 +1525,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( X2AP_Pre_emptionCapability_t pre_emptionCapability = X2AP_Pre_emptionCapability_shall_not_trigger_pre_emption; X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability = X2AP_Pre_emptionVulnerability_not_pre_emptable; priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY; - e_rab_setup_t e_MCG_rabs_tobeadded; + e_rab_tobe_added_t e_MCG_rabs_tobeadded; e_MCG_rabs_tobeadded.gtp_teid = 0; e_MCG_rabs_tobeadded.eNB_addr.length = 24; uint8_t buf[20] = { 0 }; @@ -1560,9 +1560,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( /* Prepare the X2AP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; - pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBAdditionPreparation; - pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = X2AP_InitiatingMessage__value_PR_SgNBAdditionRequest; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBAdditionPreparation; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBAdditionRequest; out = &pdu.choice.initiatingMessage.value.choice.SgNBAdditionRequest; ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); @@ -1677,8 +1677,118 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id) { - return 0; + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBAdditionRequestAcknowledge_t *out; + X2AP_SgNBAdditionRequestAcknowledge_IEs_t *ie; + X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs; + X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t *e_RABS_AdmittedToBeAdded_SgNBAddReq_Item; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + int MeNB_UE_X2AP_id = ue_id; + int SgNB_UE_X2AP_id = 0; + + // Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted + // with values coming from RRC. + uint16_t nRencryptionAlgorithms = 0; + uint16_t nRintegrityProtectionAlgorithms = 0; + uint8_t SgNBSecurityKey[32] = { 0 }; + int uEaggregateMaximumBitRateDownlink = 100000000; + int uEaggregateMaximumBitRateUplink = 100000000; + int e_rabs_admitted_tobeadded = 1; + int e_RAB_ID = 1; + long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; + long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; + long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present; + e_rab_setup_t e_SCG_rabs_tobeadded; + e_SCG_rabs_tobeadded.gtp_teid = 0; + e_SCG_rabs_tobeadded.eNB_addr.length = 24; + uint8_t buf[20] = { 0 }; + memcpy(e_SCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + // Prepare the X2AP message to encode + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBAdditionPreparation; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBAdditionRequestAcknowledge; + out = &pdu.choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge; + + // MeNB_UE_X2AP_id + ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = MeNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + // SgNB_UE_X2AP_id + ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = SgNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList; + + for (int i=0;iid = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; + e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; + { + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; + if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent; + + INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID); + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf = + calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); + + memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, + e_SCG_rabs_tobeadded.eNB_addr.buffer, + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); + } + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list, e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNBtoMeNBContainer; + ie->value.choice.SgNBtoMeNBContainer.buf = (uint8_t *)calloc(x2ap_sgnb_addition_req_ACK->rrc_buffer_size, sizeof(uint8_t)); + memcpy(ie->value.choice.SgNBtoMeNBContainer.buf, x2ap_sgnb_addition_req_ACK->rrc_buffer, x2ap_sgnb_addition_req_ACK->rrc_buffer_size); + ie->value.choice.SgNBtoMeNBContainer.size = x2ap_sgnb_addition_req_ACK->rrc_buffer_size; //4096; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; } - - From 62fb80e6deae1dcca4d65d584ab82a784509c1e6 Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 6 Dec 2019 19:15:08 +0100 Subject: [PATCH 086/343] ENDC X2AP: Implementation of SgNB Addition Response handler --- openair2/COMMON/x2ap_messages_types.h | 19 +--- openair2/RRC/LTE/rrc_eNB.c | 7 ++ openair2/RRC/NR/rrc_gNB_internode.c | 2 - openair2/RRC/NR/rrc_gNB_nsa.c | 2 - openair2/X2AP/x2ap_eNB_decoder.c | 4 + openair2/X2AP/x2ap_eNB_handler.c | 136 +++++++++++++++++++++++++- 6 files changed, 151 insertions(+), 19 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 8bcdfe9ea6..4c1cb8c88e 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -345,26 +345,17 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { } x2ap_ENDC_sgnb_addition_req_t; typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { - int ue_x2_id; + int MeNB_ue_x2_id; + + int SgNB_ue_x2_id; /* used for RRC->X2AP in source eNB */ int rnti; - security_capabilities_t security_capabilities; - - /* SgNB Security Key */ - uint8_t kgnb[32]; - - /*next_hop_chaining_coun */ - long int kgnb_ncc; - - /* UE aggregate maximum bitrate */ - ambr_t ue_ambr; - - uint8_t nb_e_rabs_tobeadded; + uint8_t nb_e_rabs_admitted_tobeadded; /* list of e_rab to be added by RRC layers */ - e_rab_tobe_added_t e_rabs_tobeadded[S1AP_MAX_E_RAB]; + e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 122929c4fc..207770537c 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -8525,6 +8525,13 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; } + case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: { + + LOG_I(RRC, "RRC processing of SgNB addition response information to be added... \n"); + break; + } + + /* Messages from eNB app */ case RRC_CONFIGURATION_REQ: LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p)); diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c index 6cc4615ac3..eafc32d923 100644 --- a/openair2/RRC/NR/rrc_gNB_internode.c +++ b/openair2/RRC/NR/rrc_gNB_internode.c @@ -121,8 +121,6 @@ int generate_CG_Config(gNB_RRC_INST *rrc, fclose(fd); total_size = total_size + ((enc_rval.encoded+7)>>3); - LOG_I(RRC, "Total size in generate_CG_Config(): %d \n", total_size); - return(total_size); } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 6353a32927..0bb035c0df 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -143,8 +143,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ 1024); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3; - LOG_I(RRC, "Total size in rrc_add_nsa_user(): %d \n", (enc_rval.encoded+7)>>3); - itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 6535ce0a78..b40abc5cb6 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -96,6 +96,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu) X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); break; + case X2AP_ProcedureCode_id_sgNBAdditionPreparation: + X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); + break; + default: X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome.procedureCode); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 75d5bac702..208e6f716d 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -120,6 +120,12 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_gNB_handle_ENDC_sGNB_addition_response (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { @@ -150,7 +156,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* seNBinitiatedSeNBRelease */ { 0, 0, 0 }, /* seNBCounterCheck */ { 0, 0, 0 }, /* retrieveUEContext */ - { x2ap_gNB_handle_ENDC_sGNB_addition_request, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/ + { x2ap_gNB_handle_ENDC_sGNB_addition_request, x2ap_gNB_handle_ENDC_sGNB_addition_response, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, @@ -1773,3 +1779,131 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, return 0; } + + +static +int x2ap_gNB_handle_ENDC_sGNB_addition_response (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_SgNBAdditionRequestAcknowledge_t *x2SgNBAdditionRequest_ack; + X2AP_SgNBAdditionRequestAcknowledge_IEs_t *ie; + + X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs; + X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t *e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + + DevAssert (pdu != NULL); + x2SgNBAdditionRequest_ack = &pdu->choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge; + + /*if (stream == 0) { + X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); + // TODO: send a x2 failure response + return 0; + }*/ + + X2AP_DEBUG ("Received a new X2 SgNB Addition request\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + X2AP_INFO("X2AP Association id: %d \n",assoc_id); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID; + + + /* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack, + X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID; + + /* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack, + X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + + if (ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count > 0) { + + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count; + + for (int i=0;ivalue.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count;i++) { + + e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *) ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.array[i]; + e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item = &e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; + + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ; + if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ + + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer, + e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, + e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length = + e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; + + OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID, + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid); + } + + } + + } + else { + X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n"); + } + + /* X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer */ + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack, + X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + //X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer; + + if (ie->value.choice.SgNBtoMeNBContainer.size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s + { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } + + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, ie->value.choice.SgNBtoMeNBContainer.buf, ie->value.choice.SgNBtoMeNBContainer.size); + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = ie->value.choice.SgNBtoMeNBContainer.size; + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + return 0; + +} + + + From b106fb1c21726fe7761c5eeb3f76b8b01e7f956d Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 10 Dec 2019 19:39:47 +0100 Subject: [PATCH 087/343] ENDC LTE-RRC: Add processing of Addition Response information elements, to be used for RRCConnectionReconfiguration --- cmake_targets/CMakeLists.txt | 2 +- openair2/RRC/LTE/rrc_eNB.c | 128 ++++++++++++++++++++- openair2/RRC/LTE/rrc_eNB_endc.c | 32 ++++-- openair2/X2AP/x2ap_eNB_generate_messages.c | 2 +- 4 files changed, 149 insertions(+), 15 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e3e6f4c772..426c8cd9fd 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2308,7 +2308,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 + RRC_LIB NR_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 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 207770537c..cbb7b19527 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -8247,6 +8247,129 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); } +void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, x2ap_ENDC_sgnb_addition_req_ACK_t *m) { + + + NR_CG_Config_t *CG_Config = NULL; + + { + int i; + printf("%d: ", m->rrc_buffer_size); + for (i=0; irrc_buffer_size; i++) printf("%2.2x", (unsigned char)m->rrc_buffer[i]); + printf("\n"); + + } + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_CG_Config, + (void **)&CG_Config, + (uint8_t *)m->rrc_buffer, + (int) m->rrc_buffer_size);//m->rrc_buffer_size); + +/* asn_dec_rval_t dec_rval = uper_decode( NULL, + &asn_DEF_LTE_UL_DCCH_Message, + (void **)<E_UL_DCCH_Message, + (uint8_t *)m->rrc_buffer, + (int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size); + + eNB_RRC_INST *rrc=RC.rrc[enb_mod_idP];*/ + + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_CG_Config, CG_Config, 1 ); + return; + } + xer_fprint(stdout,&asn_DEF_NR_CG_Config, CG_Config); + // recreate enough of X2 EN-DC Container + + AssertFatal(CG_Config->criticalExtensions.choice.c1->present == NR_CG_Config__criticalExtensions__c1_PR_cg_Config, + "CG_Config not present\n"); + + OCTET_STRING_t *scg_CellGroupConfig = NULL; + OCTET_STRING_t *nr1_conf = NULL; + + if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig){ + scg_CellGroupConfig = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig; + + { + int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size; + int i; + LOG_I(RRC, "Dumping scg_CellGroupConfig:", size_s); + for (i=0; icriticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->buf[i]); + printf("\n"); + + } + /*scg_conf = calloc(1, sizeof(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig)); + memcpy(scg_conf.buf, CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->buf, CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size); + scg_conf->size = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size;*/ + } + else{ + LOG_W(RRC, "SCG Cell group configuration is not present in the Addition Response message \n"); + return; + } + if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config){ + nr1_conf = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config; + + { + int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size; + int i; + LOG_I(RRC, "Dumping scg_RB_Config:", size_s); + for (i=0; icriticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->buf[i]); + printf("\n"); + + } + /*nr1_conf = calloc(1, sizeof(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config)); + memcpy(nr1_conf->buf,CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->buf, CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size); + nr1_conf->size = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size;*/ + } + else{ + LOG_W(RRC, "SCG RB configuration is not present in the Addition Response message \n"); + return; + } + + protocol_ctxt_t ctxt; + rrc_eNB_ue_context_t *ue_context; + unsigned char buffer[8192]; + int size; + + ue_context = get_first_ue_context(RC.rrc[enb_mod_idP]); + + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + 0, + ENB_FLAG_YES, + 4660,//ue_context->ue_context.rnti, + 0, 0); + + size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf); + + rrc_data_req(&ctxt, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + + + /*NR_CG_ConfigInfo_t *CG_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo)); + CG_ConfigInfo->criticalExtensions.present = NR_CG_ConfigInfo__criticalExtensions_PR_c1; + CG_ConfigInfo->criticalExtensions.choice.c1 = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1)); + CG_ConfigInfo->criticalExtensions.choice.c1->present = NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo; + CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo)); + NR_CG_ConfigInfo_IEs_t *cg_ConfigInfo = CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo; + cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof(*cg_ConfigInfo->ue_CapabilityInfo)); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,NULL,(void*)<E_UL_DCCH_Message->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList,m->rrc_buffer,m->rrc_buffer_size); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, + (const char *)m->rrc_buffer, + (enc_rval.encoded+7)>>3); + parse_CG_ConfigInfo(rrc,CG_ConfigInfo);*/ + +} + + //----------------------------------------------------------------------------- void *rrc_enb_process_itti_msg(void *notUsed) { MessageDef *msg_p; @@ -8526,8 +8649,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { } case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: { - - LOG_I(RRC, "RRC processing of SgNB addition response information to be added... \n"); + rrc_eNB_process_AdditionResponseInformation(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg_p)); break; } @@ -8585,7 +8707,7 @@ rrc_endc_hack_init(); { extern volatile int go_nr; void rrc_go_nr(void); - if (go_nr) rrc_go_nr(); + //if (go_nr) rrc_go_nr(); } } } diff --git a/openair2/RRC/LTE/rrc_eNB_endc.c b/openair2/RRC/LTE/rrc_eNB_endc.c index aa2b3e76cf..ecc92750a7 100644 --- a/openair2/RRC/LTE/rrc_eNB_endc.c +++ b/openair2/RRC/LTE/rrc_eNB_endc.c @@ -38,7 +38,9 @@ extern mui_t rrc_eNB_mui; int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, - int buffer_size) + int buffer_size, + OCTET_STRING_t *scg_group_config, + OCTET_STRING_t *scg_RB_config) { asn_enc_rval_t enc_rval; LTE_DL_DCCH_Message_t dl_dcch_msg; @@ -152,20 +154,30 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, nr.present = LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15_PR_setup; nr.choice.setup.endc_ReleaseAndAdd_r15 = 0; /* FALSE */ - OCTET_STRING_t scg_conf; + OCTET_STRING_t dummy_scg_conf; unsigned char scg_conf_buf[4] = { 0, 0, 0, 0 }; - nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = &scg_conf; - scg_conf.buf = scg_conf_buf; - scg_conf.size = 4; + if (scg_group_config!=NULL) + nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = scg_group_config; //&scg_conf; + else{ + nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = &dummy_scg_conf; + dummy_scg_conf.buf = scg_conf_buf; + dummy_scg_conf.size = 4; + } + long sk_counter = 0; cr_1510.sk_Counter_r15 = &sk_counter; - OCTET_STRING_t nr1_conf; + OCTET_STRING_t dummy_nr1_conf; unsigned char nr1_buf[4] = { 0, 0, 0, 0 }; - cr_1510.nr_RadioBearerConfig1_r15 = &nr1_conf; - nr1_conf.buf = nr1_buf; - nr1_conf.size = 4; + + if(scg_RB_config!=NULL) + cr_1510.nr_RadioBearerConfig1_r15 = scg_RB_config; + else{ + cr_1510.nr_RadioBearerConfig1_r15 = &dummy_nr1_conf; + dummy_nr1_conf.buf = nr1_buf; + dummy_nr1_conf.size = 4; + } OCTET_STRING_t nr2_conf; unsigned char nr2_buf[4] = { 0, 0, 0, 0 }; @@ -221,7 +233,7 @@ void rrc_go_nr(void) ue_context->ue_context.rnti, 0, 0); - size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192); + size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, NULL, NULL); rrc_data_req(&ctxt, DCCH, diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 3bff59882e..eac3da0234 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1532,7 +1532,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); FILE *fd; - fd = fopen("uecap.raw","r"); + fd = fopen("../../../executables/uecap.raw","r"); if (fd != NULL) { OCTET_STRING_t CG_Config_Info; CG_Config_Info.size = 4096; From 84f928e7de63d97e463a5e1b347889e2c82a20d3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 19 Sep 2019 17:53:08 +0200 Subject: [PATCH 088/343] 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 089/343] 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 090/343] 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 9a4d1e81d7bbceca9127de29395dbb2dd8520ba7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 16 Dec 2019 16:17:35 +0100 Subject: [PATCH 091/343] nr-rlc: add function mac_rlc_get_buffer_occupancy_ind Fix also value passed to buffer_status in mac_rlc_status_ind to be aligned with 38.321 (instead of 36.321). --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 61 +++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b56e8b11e9..bac62a186c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -178,11 +178,11 @@ mac_rlc_status_resp_t mac_rlc_status_ind( if (rb != NULL) { nr_rlc_entity_buffer_status_t buf_stat; rb->set_time(rb, nr_rlc_current_time); - /* 36.321 deals with BSR values up to 3000000 bytes, after what it - * reports '> 3000000' (table 6.1.3.1-2). Passing 4000000 is thus + /* 38.321 deals with BSR values up to 81338368 bytes, after what it + * reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus * more than enough. */ - buf_stat = rb->buffer_status(rb, 4000000); + buf_stat = rb->buffer_status(rb, 100000000); ret.bytes_in_buffer = buf_stat.status_size + buf_stat.retx_size + buf_stat.tx_size; @@ -201,6 +201,61 @@ mac_rlc_status_resp_t mac_rlc_status_ind( return ret; } +rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const logical_chan_id_t channel_idP) +{ + nr_rlc_ue_t *ue; + rlc_buffer_occupancy_t ret; + nr_rlc_entity_t *rb; + + if (enb_flagP) { + LOG_E(RLC, "Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%u\n", channel_idP); + exit(1); + } + + /* TODO: handle time a bit more properly */ + if (nr_rlc_current_time_last_frame != frameP || + nr_rlc_current_time_last_subframe != subframeP) { + nr_rlc_current_time++; + nr_rlc_current_time_last_frame = frameP; + nr_rlc_current_time_last_subframe = subframeP; + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + nr_rlc_entity_buffer_status_t buf_stat; + rb->set_time(rb, nr_rlc_current_time); + /* 38.321 deals with BSR values up to 81338368 bytes, after what it + * reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus + * more than enough. + */ + buf_stat = rb->buffer_status(rb, 100000000); + ret = buf_stat.status_size + + buf_stat.retx_size + + buf_stat.tx_size; + } else { + ret = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return ret; +} + int oai_emulation; rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, From 35fda01e862bc639c143c1d3600ad9ee940b0e77 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 16 Dec 2019 16:19:23 +0100 Subject: [PATCH 092/343] nr-rlc: fix some compilation warnings --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index bac62a186c..2d51e5c7f0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -276,7 +276,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); @@ -879,24 +879,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++) 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 093/343] 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 094/343] 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 095/343] 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 096/343] 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 097/343] 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 098/343] 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 099/343] 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 100/343] 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 101/343] 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 102/343] 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 103/343] 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 104/343] 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 105/343] 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 b1f224d11ecdb3941a5746d43cf4faa9892b25b0 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 18 Dec 2019 21:27:30 +0100 Subject: [PATCH 106/343] should not use LTE UE list in NR MAC as sizes are different and causes segfaults --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 26 ++++++++++--------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 6be0e25ff9..e97cceced5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -37,6 +37,8 @@ extern RAN_CONTEXT_t RC; //#define ENABLE_MAC_PAYLOAD_DEBUG 1 +uint8_t mac_payload[MAX_NR_DLSCH_PAYLOAD_BYTES]; + /*Scheduling of DLSCH with associated DCI in common search space * current version has only a DCI for type 1 PDCCH for C_RNTI*/ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, @@ -266,7 +268,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; - UE_list_t *UE_list = &gNB_mac->UE_list; nfapi_nr_dl_config_request_body_t *dl_req; nfapi_tx_request_pdu_t *TX_req; mac_rlc_status_resp_t rlc_status; @@ -286,12 +287,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, uint16_t R = 697; uint16_t nb_rb = 50; uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs - int UE_id = 0; // UE_list->head is -1 ! + int UE_id = 0; uint16_t rnti = 0x1234; uint16_t sfn_sf = frameP << 7 | slotP; - UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - //ta_update = ue_sched_ctl->ta_update; + printf("TBS=%d\n",TBS); for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) { @@ -360,17 +360,19 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; + /* UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - + */ + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; num_sdus++; - ue_sched_ctl->uplane_inactivity_timer = 0; + //ue_sched_ctl->uplane_inactivity_timer = 0; } } else { // no TBS left break; @@ -430,7 +432,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, offset = nr_generate_dlsch_pdu(module_idP, (unsigned char *) dlsch_buffer, - (unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + (unsigned char *) mac_payload, num_sdus, //num_sdus sdu_lengths, sdu_lcids, @@ -441,14 +443,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, // Padding: fill remainder of DLSCH with 0 if (post_padding > 0){ for (int j = 0; j < (TBS - offset); j++) - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + j] = 0; + mac_payload[offset + j] = 0; } TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], gNB_mac->pdu_index[CC_id], dlsch_config); //TX_req->segments[0].segment_length = 8; TX_req->segments[0].segment_length = TBS_bytes + 2; - TX_req->segments[0].segment_data = gNB_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]; + TX_req->segments[0].segment_data = mac_payload; gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; gNB_mac->TX_req[CC_id].sfn_sf = sfn_sf; @@ -459,7 +461,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n \n", frameP, slotP, TBS_bytes); for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 - LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0])[i]); + LOG_I(MAC, "%x. ", mac_payload[i]); } #endif } else { @@ -467,14 +469,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (frameP%100 == 0){ LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); for(int i = 0; i < 10; i++) { - LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0])[i]); + LOG_I(MAC, "%x. ", mac_payload[i]); } } #endif } // Printing bit by bit for debugging purpose /*for (int k = 0; k < TBS; k++){ - printf("MAC PDU %u\n",((( UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][k/8]) & (1 << (k & 7))) >> (k & 7))); + printf("MAC PDU %u\n",((( mac_payload[k/8]) & (1 << (k & 7))) >> (k & 7))); if ((k+1)%8 == 0) printf("\n"); }*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 27e3e1921e..1f00203dcc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -144,6 +144,7 @@ typedef struct gNB_MAC_INST_s { /// NFAPI search space structure nfapi_nr_search_space_t search_space[NFAPI_CC_MAX][NFAPI_NR_MAX_NB_SEARCH_SPACES]; + /// this is an LTE structure and needs to be urgenly updated UE_list_t UE_list; /// UL handle From 4da175f5149cce6fde77eab7e6504bd92930a58c Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 19 Dec 2019 10:06:15 +0100 Subject: [PATCH 107/343] [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 db6eeb277390dbb213956b9700d3a1a912a540c9 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 19 Dec 2019 13:32:53 +0100 Subject: [PATCH 108/343] fixing mac pdu generation. to be checked by fraunhofer --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 6 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 80 +++++++------------ 2 files changed, 33 insertions(+), 53 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index df194d5452..15c96fec94 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -164,13 +164,13 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING; mac_pdu_ptr++; - // compute final offset - offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); - } else { // no MAC subPDU with padding } + // compute final offset + offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); + //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu)); return offset; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index e97cceced5..02f217ced5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -37,7 +37,7 @@ extern RAN_CONTEXT_t RC; //#define ENABLE_MAC_PAYLOAD_DEBUG 1 -uint8_t mac_payload[MAX_NR_DLSCH_PAYLOAD_BYTES]; +uint8_t mac_pdu[MAX_NR_DLSCH_PAYLOAD_BYTES]; /*Scheduling of DLSCH with associated DCI in common search space * current version has only a DCI for type 1 PDCCH for C_RNTI*/ @@ -280,18 +280,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; int CC_id, lcid, offset, i, j=0, k=0, header_length_last, TBS_bytes; - // hardcoded parameters to 30 kHz - // for DMRS configuration type 1 - unsigned char dlsch_buffer[MAX_NR_DLSCH_PAYLOAD_BYTES]; - uint8_t Qm = 2; - uint16_t R = 697; - uint16_t nb_rb = 50; - uint32_t TBS = nr_compute_tbs(Qm, R, nb_rb, 12, 6, 0, 1)/8; // this is in bits TODO use nr_get_tbs int UE_id = 0; uint16_t rnti = 0x1234; uint16_t sfn_sf = frameP << 7 | slotP; - printf("TBS=%d\n",TBS); + uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES]; for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) { @@ -301,31 +294,28 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, TX_req = &gNB_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; ta_len = gNB_mac->ta_len; + TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], gNB_mac->pdu_index[CC_id], dlsch_config); + //printf("TBS_bytes=%d (bytes)\n",TBS_bytes); + //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving //through the LTE stack if (IS_SOFTMODEM_NOS1){ - - // Hardcode it for now - //TBS = 6784/8; //TBS in bytes - //nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); - //TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size; - /* TODO // RLC data on DCCH - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { }*/ /* TODO // RLC data on DCCH1 - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { }*/ for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, TBS - ta_len - header_length_total - sdu_length_total - 3); + module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, @@ -334,14 +324,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3, + TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, 0, 0); if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", - module_idP, frameP, TBS - ta_len - header_length_total - sdu_length_total - 3, - lcid, header_length_total, TBS); + LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", + module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, + lcid, header_length_total, TBS_bytes); sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, @@ -350,8 +340,8 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS, - (char *)&dlsch_buffer[sdu_length_total], + TBS_bytes, + (char *)&mac_sdus[sdu_length_total], 0, 0); @@ -374,7 +364,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //ue_sched_ctl->uplane_inactivity_timer = 0; } - } else { // no TBS left + } else { // no TBS_bytes left break; } } @@ -392,26 +382,17 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, // fill dlsch_buffer with random data - for (i = 0; i < TBS/8; i++){ - dlsch_buffer[i] = (unsigned char) rand(); //i&0xFF; + for (i = 0; i < TBS_bytes; i++){ + mac_sdus[i] = (unsigned char) rand(); //i&0xFF; } //Sending SDUs with size 1 //Initialize elements of sdu_lcids and sdu_lengths - //TODO this will be eventually be removed - while (TBS >= 3 + header_length_total + sdu_length_total + ta_len){ - if (k < NR_MAX_NB_RB && j < NR_MAX_NB_RB){ - sdu_lcids[j] = 0x05; // DRB - sdu_lengths[k] = 1; - header_length_total += 2; - sdu_length_total += 1; - num_sdus +=1; - k++, j++; - } - else { - break; - } - } + sdu_lcids[0] = 0x05; // DRB + sdu_lengths[0] = TBS_bytes-3; + header_length_total += 2; + sdu_length_total += sdu_lengths[0]; + num_sdus +=1; } // else IS_SOFTMODEM_NOS1 // there is at least one SDU or TA command @@ -419,10 +400,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (ta_len + sdu_length_total + header_length_total > 0) { // Check if there is data from RLC or CE - if (TBS >= 2 + header_length_total + sdu_length_total + ta_len) { + if (TBS_bytes >= 2 + header_length_total + sdu_length_total + ta_len) { // we have to consider padding // padding param currently not in use - padding = TBS - header_length_total - sdu_length_total - ta_len - 1; + padding = TBS_bytes - header_length_total - sdu_length_total - ta_len - 1; post_padding = 1; } else { padding = 0; @@ -431,8 +412,8 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, offset = nr_generate_dlsch_pdu(module_idP, - (unsigned char *) dlsch_buffer, - (unsigned char *) mac_payload, + (unsigned char *) mac_sdus, + (unsigned char *) mac_pdu, num_sdus, //num_sdus sdu_lengths, sdu_lcids, @@ -442,15 +423,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, // Padding: fill remainder of DLSCH with 0 if (post_padding > 0){ - for (int j = 0; j < (TBS - offset); j++) - mac_payload[offset + j] = 0; + for (int j = 0; j < (TBS_bytes - offset); j++) + mac_pdu[offset + j] = 0; } - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], gNB_mac->pdu_index[CC_id], dlsch_config); //TX_req->segments[0].segment_length = 8; TX_req->segments[0].segment_length = TBS_bytes + 2; - TX_req->segments[0].segment_data = mac_payload; + TX_req->segments[0].segment_data = mac_pdu; gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; gNB_mac->TX_req[CC_id].sfn_sf = sfn_sf; From 82aebfa6279244fd3797f3c6db8bad43d7dde1ea Mon Sep 17 00:00:00 2001 From: Hongzhi Wang Date: Thu, 7 Nov 2019 11:33:58 +0100 Subject: [PATCH 109/343] 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 110/343] 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 111/343] 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 112/343] 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 113/343] 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 02f16d553054709f72fe87dd6bc860cd1647105e Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 16 Oct 2019 18:01:40 +0200 Subject: [PATCH 114/343] CI: increasing the repeat count since the 1st try will always fail Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5843539f72..2d34439ef7 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 @@ -25,7 +25,7 @@ test-05-tm1 Test-05MHz-TM1 tasks - 2 + 4 030201 040101 030102 000002 040301 000002 040504 000001 040401 000002 030201 From 45f71211c048b700a10ca9c6f60a9e15d968fd22 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 17 Oct 2019 16:51:15 +0200 Subject: [PATCH 115/343] CI: looping on attach/ping/detach sequences Signed-off-by: Raphael Defosseux --- .../enb_usrp210_band7_test_05mhz_tm1.xml | 286 +++++++++++++++++- 1 file changed, 284 insertions(+), 2 deletions(-) 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 2d34439ef7..f5e095ba8a 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,7 +19,7 @@ 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 + 030103 000002 040301 000002 040504 040605 040606 040645 040646 000001 040401 000002 030201 --> test-05-tm1 @@ -28,7 +28,44 @@ 4 030201 040101 - 030102 000002 040301 000002 040504 000001 040401 000002 030201 + 030103 000002 040301 + 000002 040504 000001 + 000002 040505 000001 + 000002 040506 000001 + 000002 040507 000001 + 000002 040508 000001 + 000002 040509 000001 + 000002 040510 000001 + 000002 040511 000001 + 000002 040512 000001 + 000002 040513 000001 + 000002 040514 000001 + 000002 040515 000001 + 000002 040516 000001 + 000002 040517 000001 + 000002 040518 000001 + 000002 040519 000001 + 000002 040520 000001 + 000002 040521 000001 + 000002 040522 000001 + 000002 040523 000001 + 000002 040524 000001 + 000002 040525 000001 + 000002 040526 000001 + 000002 040527 000001 + 000002 040528 000001 + 000002 040529 000001 + 000002 040530 000001 + 000002 040531 000001 + 000002 040532 000001 + 000002 040533 000001 + 000002 040534 000001 + 000002 040535 000001 + 000002 040536 000001 + 000002 040537 000001 + 000002 040538 000001 + 000002 040539 000001 + 040401 000002 030201 @@ -77,6 +114,251 @@ 5 + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -I 192.168.248.159 -c 20 + 5 + + Iperf iperf (5MHz - DL/1Mbps/UDP)(30 sec) From 68dc0d00a197dc3c87dad08ba69d08f34cee77f0 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 18 Oct 2019 16:48:40 +0200 Subject: [PATCH 116/343] CI: fix in looping attach / ping / detach Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 24 ++++-- ...b_ue_usrp210_band7_test_05mhz_tm1_nos1.xml | 2 +- .../enb_usrp210_band7_test_05mhz_tm1.xml | 84 ++++++++++--------- 3 files changed, 60 insertions(+), 50 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index f6cece95c9..2204f0c8c0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -909,20 +909,26 @@ class SSHConnection(): 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) + #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) # Wait - time.sleep(60) + #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) + #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) + #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) + #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) + + # normal procedure without reboot + # 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() 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 index dff0761bd3..c2835d0461 100644 --- 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 @@ -24,7 +24,7 @@ test-05-tm1-nos1-tunnel Test-05MHz-TM1-noS1-tunnel tasks - 2 + 4 030201 090109 030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201 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 f5e095ba8a..6bc52568c3 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,7 +19,6 @@ For more information about the OpenAirInterface (OAI) Software Alliance: contact@openairinterface.org - 030103 000002 040301 000002 040504 040605 040606 040645 040646 000001 040401 000002 030201 --> test-05-tm1 @@ -28,44 +27,44 @@ 4 030201 040101 - 030103 000002 040301 - 000002 040504 000001 - 000002 040505 000001 - 000002 040506 000001 - 000002 040507 000001 - 000002 040508 000001 - 000002 040509 000001 - 000002 040510 000001 - 000002 040511 000001 - 000002 040512 000001 - 000002 040513 000001 - 000002 040514 000001 - 000002 040515 000001 - 000002 040516 000001 - 000002 040517 000001 - 000002 040518 000001 - 000002 040519 000001 - 000002 040520 000001 - 000002 040521 000001 - 000002 040522 000001 - 000002 040523 000001 - 000002 040524 000001 - 000002 040525 000001 - 000002 040526 000001 - 000002 040527 000001 - 000002 040528 000001 - 000002 040529 000001 - 000002 040530 000001 - 000002 040531 000001 - 000002 040532 000001 - 000002 040533 000001 - 000002 040534 000001 - 000002 040535 000001 - 000002 040536 000001 - 000002 040537 000001 - 000002 040538 000001 - 000002 040539 000001 - 040401 000002 030201 + 030103 000002 + 040301 000002 040504 000001 040401 + 040301 000002 040505 000001 040401 + 040301 000002 040506 000001 040401 + 040301 000002 040507 000001 040401 + 040301 000002 040508 000001 040401 + 040301 000002 040509 000001 040401 + 040301 000002 040510 000001 040401 + 040301 000002 040511 000001 040401 + 040301 000002 040512 000001 040401 + 040301 000002 040513 000001 040401 + 040301 000002 040514 000001 040401 + 040301 000002 040515 000001 040401 + 040301 000002 040516 000001 040401 + 040301 000002 040517 000001 040401 + 040301 000002 040518 000001 040401 + 040301 000002 040519 000001 040401 + 040301 000002 040520 000001 040401 + 040301 000002 040521 000001 040401 + 040301 000002 040522 000001 040401 + 040301 000002 040523 000001 040401 + 040301 000002 040524 000001 040401 + 040301 000002 040525 000001 040401 + 040301 000002 040526 000001 040401 + 040301 000002 040527 000001 040401 + 040301 000002 040528 000001 040401 + 040301 000002 040529 000001 040401 + 040301 000002 040530 000001 040401 + 040301 000002 040531 000001 040401 + 040301 000002 040532 000001 040401 + 040301 000002 040533 000001 040401 + 040301 000002 040534 000001 040401 + 040301 000002 040535 000001 040401 + 040301 000002 040536 000001 040401 + 040301 000002 040537 000001 040401 + 040301 000002 040538 000001 040401 + 040301 000002 040539 000001 040401 + 040201 000002 030201 @@ -74,6 +73,11 @@ Initialize UE + + Terminate_UE + Terminate UE + + IdleSleep Sleep for 10 sec @@ -86,7 +90,7 @@ 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 From 1813af8beb18d072e2dc3f4817104e2ad1f6a136 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 11 Nov 2019 20:15:27 +0100 Subject: [PATCH 117/343] CI: fix UL iperf in distributed env Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-inria-r2lab | 4 - ci-scripts/main.py | 99 ++++++++++++++++--- .../enb_ue_usrp210_band7_test_05mhz_tm1.xml | 2 +- .../enb_usrp210_band7_test_05mhz_tm1.xml | 86 ++++++++-------- 4 files changed, 129 insertions(+), 62 deletions(-) diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab index 6ae7522999..778c571645 100644 --- a/ci-scripts/Jenkinsfile-inria-r2lab +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -183,7 +183,6 @@ pipeline { 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\"'" @@ -195,9 +194,6 @@ pipeline { 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 2204f0c8c0..7d11161a1f 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1898,11 +1898,27 @@ class SSHConnection(): def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue): try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) + # Launch ping on the EPC side (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 ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + + if launchFromEpc: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('cd ' + self.EPCSourceCodePath, '\$', 5) + self.command('cd scripts', '\$', 5) + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + else: + cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' + message = cmd + '\n' + logging.debug(cmd) + ret = subprocess.run(cmd, shell=True) + ping_status = ret.returncode + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('cat ' + self.EPCSourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) # TIMEOUT CASE if ping_status < 0: message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' @@ -2212,7 +2228,7 @@ class SSHConnection(): req_bandwidth = '%.1f Gbits/sec' % req_bw req_bw = req_bw * 1000000000 - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) (\((?P[0-9\.]+)%\))', str(self.ssh.before)) + result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P[0-9\.]+)%\))', str(self.ssh.before)) if result is not None: bitrate = result.group('bitrate') packetloss = result.group('packetloss') @@ -2260,6 +2276,8 @@ class SSHConnection(): statusQueue.put(msg) lock.release() return 0 + else: + return -2 def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): @@ -2429,11 +2447,17 @@ class SSHConnection(): 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: - if udpIperf: - cmd = 'nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' else: - cmd = 'nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - logging.debug(cmd + '\n') + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/opt/iperf-2.0.5/bin/' + if udpIperf: + cmd = 'nohup ' + prefix + 'iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' + else: + cmd = 'nohup ' + prefix + 'iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' + logging.debug(cmd) subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') time.sleep(0.5) @@ -2458,7 +2482,12 @@ class SSHConnection(): if (device_id == 'OAI-UE'): iperf_status = self.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) else: - iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if self.ADBCentralized: + iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + iperf_status = self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + self.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + self.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) # TIMEOUT Case if iperf_status < 0: self.close() @@ -2477,12 +2506,12 @@ class SSHConnection(): self.close() else: cmd = 'killall --signal SIGKILL iperf' - logging.debug(cmd + '\n') + logging.debug(cmd) 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): + if (clientStatus == -1) or (clientStatus == -2): if launchFromEpc: time.sleep(1) if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): @@ -2501,6 +2530,8 @@ class SSHConnection(): return useIperf3 = False udpIperf = True + + self.ueIperfVersion = '2.0.5' if (device_id != 'OAI-UE'): self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it @@ -2520,9 +2551,30 @@ class SSHConnection(): self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return + else: + if self.ADBCentralized: + self.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5) + else: + self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60) + result = re.search('iperf version 2.0.5', str(self.ssh.before)) + if result is not None: + self.ueIperfVersion = '2.0.5' + result = re.search('iperf version 2.0.10', str(self.ssh.before)) + if result is not None: + self.ueIperfVersion = '2.0.10' else: useIperf3 = True self.close() + else: + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('iperf --version', '\$', 5) + result = re.search('iperf version 2.0.5', str(self.ssh.before)) + if result is not None: + self.ueIperfVersion = '2.0.5' + result = re.search('iperf version 2.0.10', str(self.ssh.before)) + if result is not None: + self.ueIperfVersion = '2.0.10' + self.close() # in case of iperf, UL has its own function if (not useIperf3): result = re.search('-R', str(self.iperf_args)) @@ -2557,7 +2609,7 @@ class SSHConnection(): 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) - 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) + 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" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60) time.sleep(0.5) self.close() @@ -2593,7 +2645,13 @@ class SSHConnection(): 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' + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' + else: + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/opt/iperf-2.0.5/bin/' + cmd = prefix + '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) @@ -2638,6 +2696,7 @@ class SSHConnection(): self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') else: self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + self.command('fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) # in case of OAI UE: @@ -2782,6 +2841,18 @@ class SSHConnection(): self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE) self.AutoTerminateUEandeNB() return + + self.dummyIperfVersion = '2.0.10' + #cmd = 'iperf --version' + #logging.debug(cmd + '\n') + #iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True) + #result = re.search('iperf version 2.0.5', str(iperfStdout.strip())) + #if result is not None: + # dummyIperfVersion = '2.0.5' + #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) + #if result is not None: + # dummyIperfVersion = '2.0.10' + multi_jobs = [] i = 0 ue_num = len(self.UEIPAddresses) 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 1471b9a016..0196bf1ab6 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 @@ -68,7 +68,7 @@ Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 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 6bc52568c3..964550d872 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 @@ -24,11 +24,11 @@ test-05-tm1 Test-05MHz-TM1 tasks - 4 + 1 - 030201 040101 + 040101 030201 030103 000002 - 040301 000002 040504 000001 040401 + 040301 000002 040504 040605 040606 040645 040646 040401 040301 000002 040505 000001 040401 040301 000002 040506 000001 040401 040301 000002 040507 000001 040401 @@ -114,252 +114,252 @@ Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 Ping ping (5MHz - 20 sec) - -I 192.168.248.159 -c 20 + -c 20 5 @@ -372,8 +372,8 @@ Iperf - iperf (5MHz - DL/12Mbps/UDP)(30 sec) - -u -b 12M -t 30 -i 1 -fm + iperf (5MHz - DL/15Mbps/UDP)(30 sec) + -u -b 15M -t 30 -i 1 -fm 50 @@ -386,8 +386,8 @@ Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec) - -u -b 2M -t 30 -i 1 -fm -R + iperf (5MHz - UL/3.8Mbps/UDP)(30 sec) + -u -b 3.8M -t 30 -i 1 -fm -R 50 From 3775404a6b7799d37f6ce68093e7a09f49f30784 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 29 Nov 2019 11:52:01 +0100 Subject: [PATCH 118/343] CI: add initial support to do X2 HO at Inria Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-inria-r2lab | 13 +- .../inria/enb_usrp210_band7_build.xml | 13 +- ...enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml | 128 ++++++++++++++++++ 3 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab index 778c571645..555017a533 100644 --- a/ci-scripts/Jenkinsfile-inria-r2lab +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -59,6 +59,9 @@ def r2labEPC0IpAddr = r2labBaseIpAddr + r2labEPC0Idx def r2labUE0Idx = '6' def r2labUE0 = 'fit0' + r2labUE0Idx def r2labUE0IpAddr = r2labBaseIpAddr + r2labUE0Idx +def r2labENB1Idx = '16' +def r2labENB1 = 'fit' + r2labENB1Idx +def r2labENB1IpAddr = r2labBaseIpAddr + r2labENB1Idx pipeline { agent { @@ -144,9 +147,9 @@ pipeline { 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}'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx} > /dev/null 2>&1'" + sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx},${r2labENB1Idx}'" + sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'" 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'" @@ -157,7 +160,7 @@ pipeline { 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'" + sh "ssh -t inria_oaici@faraday.inria.fr 'nodes ${r2labUE0Idx},${r2labPythonExeIdx},${r2labEPC0Idx},${r2labENB0Idx},${r2labENB1Idx} && st'" } } } @@ -210,7 +213,7 @@ pipeline { 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}\"'" + 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 --eNB1IPAddress=${r2labENB1IpAddr} --eNB1UserName=${fituser} --eNB1Password=${fitpasswd} --eNB1SourceCodePath=/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 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 776c92106d..d3e9825923 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_build.xml @@ -26,13 +26,24 @@ wrench 010101 + 010102 Build_eNB - Build eNB (USRP) + Build eNB #0 (USRP) -w USRP -c --eNB + 0 + 0 + + + + Build_eNB + Build eNB #1 (USRP) + -w USRP -c --eNB + 1 + 1 diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml new file mode 100644 index 0000000000..f10465f688 --- /dev/null +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml @@ -0,0 +1,128 @@ + + + test-x2-ho-05-tm1 + Test-X2-Handover-05MHz-TM1 + tasks + 1 + + 040101 030201 + 050102 + 030104 000002 + 040301 000002 040540 040615 040616 040655 040656 040401 + 040201 000002 030201 + 050202 + + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + 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 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes + 0 + 0 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_FlexranCtrl + Starting Flexran Controller + + + + Terminate_FlexranCtrl + Stopping Flexran Controller + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec) + -u -b 15M -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/3.8Mbps/UDP)(30 sec) + -u -b 3.8M -t 30 -i 1 -fm -R + 50 + + + From 11f4d2ae012ded626570a388db38d1b47fbb70a4 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 29 Nov 2019 13:57:42 +0100 Subject: [PATCH 119/343] CI: finalizing offline the X2 handover scenario at inria --> to be tested Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 1 + ...enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml | 84 +++++++++++++++++-- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7d11161a1f..3bb44b8f81 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -834,6 +834,7 @@ class SSHConnection(): self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml index f10465f688..af09934d2b 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml @@ -26,11 +26,16 @@ tasks 1 - 040101 030201 + 040101 030201 030202 050102 - 030104 000002 - 040301 000002 040540 040615 040616 040655 040656 040401 - 040201 000002 030201 + 030104 000002 030105 000002 + 040301 000002 + 040540 040615 040616 040655 040656 + 050401 000001 + 040541 040617 040618 040657 040658 + 040401 000001 + 040542 + 040201 000002 030201 030202 050202 @@ -59,15 +64,32 @@ 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 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes + Initialize eNB #0 (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 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 123456 0 0 + + Initialize_eNB + Initialize eNB #1 (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 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].target_enb_x2_ip_address.[0].ipv4 CI_RCC_IP_ADDR --eNBs.[0].target_enb_x2_ip_address.[0].preference ipv4 --eNBs.[0].eNB_ID 0xe01 --eNBs.[0].component_carriers.[0].Nid_cell 1 --eNBs.[0].nr_cellid 98765 + 1 + 1 + + Terminate_eNB - Terminate eNB + Terminate eNB #0 + 0 + 0 + + + + Terminate_eNB + Terminate eNB #1 + 1 + 1 @@ -97,6 +119,20 @@ 5 + + Ping + ping (5MHz - 20 sec) + -c 20 + 50 + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 50 + + Iperf iperf (5MHz - DL/1Mbps/UDP)(30 sec) @@ -111,6 +147,20 @@ 50 + + Iperf + iperf (5MHz - DL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm + 50 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec) + -u -b 15M -t 30 -i 1 -fm + 50 + + Iperf iperf (5MHz - UL/1Mbps/UDP)(30 sec) @@ -125,4 +175,24 @@ 50 + + Iperf + iperf (5MHz - UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 -i 1 -fm -R + 50 + + + + Iperf + iperf (5MHz - UL/3.8Mbps/UDP)(30 sec) + -u -b 3.8M -t 30 -i 1 -fm -R + 50 + + + + Perform_X2_Handover + Doing a Flexran-Controlled X2 Handover + network + + From e88dc6196538581334f5b502bd3e22f90d65ce32 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 29 Nov 2019 15:51:29 +0100 Subject: [PATCH 120/343] CI: some fixes Signed-off-by: Raphael Defosseux --- .../enb.band7.tm1.25PRB.slave.usrpb210.conf | 279 ++++++++++++++++++ ci-scripts/main.py | 1 - ...enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml | 11 +- 3 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf new file mode 100644 index 0000000000..46ab966017 --- /dev/null +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf @@ -0,0 +1,279 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe10; + + 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 10; + 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 */ + target_enb_x2_ip_address = ( + { ipv4 = "CI_RCC_IP_ADDR"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + 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/main.py b/ci-scripts/main.py index 3bb44b8f81..7d11161a1f 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -834,7 +834,6 @@ class SSHConnection(): self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml index af09934d2b..71cddc81b4 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml @@ -33,8 +33,9 @@ 040540 040615 040616 040655 040656 050401 000001 040541 040617 040618 040657 040658 + 050402 000001 + 040542 040401 000001 - 040542 040201 000002 030201 030202 050202 @@ -73,7 +74,7 @@ Initialize_eNB Initialize eNB #1 (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 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].target_enb_x2_ip_address.[0].ipv4 CI_RCC_IP_ADDR --eNBs.[0].target_enb_x2_ip_address.[0].preference ipv4 --eNBs.[0].eNB_ID 0xe01 --eNBs.[0].component_carriers.[0].Nid_cell 1 --eNBs.[0].nr_cellid 98765 + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.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 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 98765 1 1 @@ -195,4 +196,10 @@ network + + Perform_X2_Handover + Doing a Flexran-Controlled X2 Handover + network + + From 45aa72f2bebd98fba5c76a9db76342f2071a2a10 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 5 Dec 2019 06:57:09 +0100 Subject: [PATCH 121/343] CI: improvements Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-inria-r2lab | 8 ++++++-- ci-scripts/main.py | 10 +++++----- .../inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab index 555017a533..3c4dddae8b 100644 --- a/ci-scripts/Jenkinsfile-inria-r2lab +++ b/ci-scripts/Jenkinsfile-inria-r2lab @@ -134,7 +134,7 @@ pipeline { [$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}" + sh "python3 /home/eurecom/inria-scripts/booking-lease.py --get-leases ${r2labuser} ${r2labpassword} | grep -v nightly" } } } @@ -146,15 +146,19 @@ pipeline { 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' + echo '\u2705 \u001B[32mLoad Image for two (2) eNBs\u001B[0m' sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx} > /dev/null 2>&1'" sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx},${r2labENB1Idx}'" sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'" + sh "sleep 5" + sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'" 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}'" + sh "sleep 5" + 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'" diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7d11161a1f..860dcb3ea2 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -801,13 +801,13 @@ class SSHConnection(): # do not reset board twice in IF4.5 case result = re.search('^rru|^enb|^du.band', str(config_file)) if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 10) + self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60) result = re.search('type: b200', str(self.ssh.before)) if result is not None: logging.debug('Found a B2xx device --> resetting it') self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) # Reloading FGPA bin firmware - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 15) + self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60) # Make a copy and adapt to EPC / eNB IP addresses self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); @@ -982,13 +982,13 @@ class SSHConnection(): sys.exit(1) self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) # b2xx_fx3_utils reset procedure - self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 10) + self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) result = re.search('type: b200', str(self.ssh.before)) if result is not None: logging.debug('Found a B2xx device --> resetting it') self.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) # Reloading FGPA bin firmware - self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 15) + self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) else: logging.debug('Did not find any B2xx device') self.command('cd ' + self.UESourceCodePath, '\$', 5) @@ -4053,7 +4053,7 @@ class SSHConnection(): if result is not None: self.UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + self.UhdVersion) - self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 15) + self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60) result = re.search('product: (?P[0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before)) if result is not None: self.UsrpBoard = result.group('usrp_board') diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml index 71cddc81b4..9f25757766 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml @@ -24,7 +24,7 @@ test-x2-ho-05-tm1 Test-X2-Handover-05MHz-TM1 tasks - 1 + 2 040101 030201 030202 050102 From c256932fe59ed8f1dcdef884cd0d035c3e60c9dd Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 11:47:42 +0100 Subject: [PATCH 122/343] 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 34c9aec59e50c41a4ef23b2a7c445d85f7197634 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 8 Jan 2020 14:31:54 +0100 Subject: [PATCH 123/343] CI: simplification of the X2 HO scenario. But sill failing! Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 23 ++++++++++++++++++- ...enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml | 6 ++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 860dcb3ea2..6adf57264b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -134,6 +134,7 @@ class SSHConnection(): self.eNBLogFiles = ['', '', ''] self.eNBOptions = ['', '', ''] self.eNBmbmsEnables = [False, False, False] + self.eNBstatuses = [-1, -1, -1] self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' @@ -899,6 +900,8 @@ class SSHConnection(): 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') + if enbDidSync: + self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId) self.close() self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) @@ -2992,7 +2995,24 @@ class SSHConnection(): def CheckeNBProcess(self, status_queue): try: - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + # At least the instance 0 SHALL be on! + if self.eNBstatuses[0] == 0: + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + elif self.eNBstatuses[0] == 1: + lIpAddr = self.eNB1IPAddress + lUserName = self.eNB1UserName + lPassWord = self.eNB1Password + elif self.eNBstatuses[0] == 2: + lIpAddr = self.eNB2IPAddress + lUserName = self.eNB2UserName + lPassWord = self.eNB2Password + else: + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + self.open(lIpAddr, lUserName, lPassWord) 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 None: @@ -3589,6 +3609,7 @@ class SSHConnection(): else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) self.eNBmbmsEnables[int(self.eNB_instance)] = False + self.eNBstatuses[int(self.eNB_instance)] = -1 def TerminateHSS(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml index 9f25757766..22f8b63266 100644 --- a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml @@ -30,11 +30,9 @@ 050102 030104 000002 030105 000002 040301 000002 - 040540 040615 040616 040655 040656 + 040540 040615 040655 050401 000001 - 040541 040617 040618 040657 040658 - 050402 000001 - 040542 + 040541 040617 040657 040401 000001 040201 000002 030201 030202 050202 From c409da3bb8c0540f4bd1fe45c7a495a581cf8466 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 9 Jan 2020 14:10:04 +0100 Subject: [PATCH 124/343] 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 125/343] 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 c1345294849d0a5dd045231e930bb9515deeb19e Mon Sep 17 00:00:00 2001 From: matzakos Date: Thu, 9 Jan 2020 18:08:46 +0100 Subject: [PATCH 126/343] ENDC: Code cleanup and logs rearrangements --- openair2/RRC/LTE/rrc_defs.h | 1 + openair2/RRC/LTE/rrc_eNB.c | 49 ++++++++------------------------- openair2/RRC/LTE/rrc_eNB_endc.c | 23 ++++++++++++++++ 3 files changed, 35 insertions(+), 38 deletions(-) diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index ad51927caa..b57decb5b3 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -92,6 +92,7 @@ #define PC5_DISCOVERY_PAYLOAD_SIZE 29 +#define DEBUG_SCG_CONFIG 1 typedef enum { UE_STATE_OFF_NETWORK, diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index cbb7b19527..ed302f976b 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -112,6 +112,8 @@ extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP); extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP); extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t *kenb_star); +extern int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config, OCTET_STRING_t *scg_RB_config); +extern struct rrc_eNB_ue_context_s * get_first_ue_context(eNB_RRC_INST *rrc_instance_pP); pthread_mutex_t rrc_release_freelist; RRC_release_list_t rrc_release_info; @@ -8265,15 +8267,6 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, (uint8_t *)m->rrc_buffer, (int) m->rrc_buffer_size);//m->rrc_buffer_size); -/* asn_dec_rval_t dec_rval = uper_decode( NULL, - &asn_DEF_LTE_UL_DCCH_Message, - (void **)<E_UL_DCCH_Message, - (uint8_t *)m->rrc_buffer, - (int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size); - - eNB_RRC_INST *rrc=RC.rrc[enb_mod_idP];*/ - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n"); // free the memory @@ -8291,18 +8284,17 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig){ scg_CellGroupConfig = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig; - +#ifdef DEBUG_SCG_CONFIG { int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size; int i; - LOG_I(RRC, "Dumping scg_CellGroupConfig:", size_s); + LOG_I(RRC, "Dumping scg_CellGroupConfig: %d", size_s); for (i=0; icriticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->buf[i]); printf("\n"); } - /*scg_conf = calloc(1, sizeof(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig)); - memcpy(scg_conf.buf, CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->buf, CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size); - scg_conf->size = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig->size;*/ +#endif + } else{ LOG_W(RRC, "SCG Cell group configuration is not present in the Addition Response message \n"); @@ -8310,18 +8302,16 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, } if(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config){ nr1_conf = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config; - +#ifdef DEBUG_SCG_CONFIG { int size_s = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size; int i; - LOG_I(RRC, "Dumping scg_RB_Config:", size_s); + LOG_I(RRC, "Dumping scg_RB_Config: %d", size_s); for (i=0; icriticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->buf[i]); printf("\n"); } - /*nr1_conf = calloc(1, sizeof(CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config)); - memcpy(nr1_conf->buf,CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->buf, CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size); - nr1_conf->size = CG_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config->size;*/ +#endif } else{ LOG_W(RRC, "SCG RB configuration is not present in the Addition Response message \n"); @@ -8333,7 +8323,7 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, unsigned char buffer[8192]; int size; - ue_context = get_first_ue_context(RC.rrc[enb_mod_idP]); + ue_context = (rrc_eNB_ue_context_t *) get_first_ue_context(RC.rrc[enb_mod_idP]); PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, @@ -8350,23 +8340,6 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - - - /*NR_CG_ConfigInfo_t *CG_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo)); - CG_ConfigInfo->criticalExtensions.present = NR_CG_ConfigInfo__criticalExtensions_PR_c1; - CG_ConfigInfo->criticalExtensions.choice.c1 = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1)); - CG_ConfigInfo->criticalExtensions.choice.c1->present = NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo; - CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo)); - NR_CG_ConfigInfo_IEs_t *cg_ConfigInfo = CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo; - cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof(*cg_ConfigInfo->ue_CapabilityInfo)); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,NULL,(void*)<E_UL_DCCH_Message->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList,m->rrc_buffer,m->rrc_buffer_size); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, - (const char *)m->rrc_buffer, - (enc_rval.encoded+7)>>3); - parse_CG_ConfigInfo(rrc,CG_ConfigInfo);*/ - } @@ -8705,7 +8678,7 @@ rrc_endc_hack_init(); while (1) { (void) rrc_enb_process_itti_msg(NULL); { - extern volatile int go_nr; + //extern volatile int go_nr; void rrc_go_nr(void); //if (go_nr) rrc_go_nr(); } diff --git a/openair2/RRC/LTE/rrc_eNB_endc.c b/openair2/RRC/LTE/rrc_eNB_endc.c index ecc92750a7..c6efb2b166 100644 --- a/openair2/RRC/LTE/rrc_eNB_endc.c +++ b/openair2/RRC/LTE/rrc_eNB_endc.c @@ -164,6 +164,17 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, dummy_scg_conf.size = 4; } +#ifdef DEBUG_SCG_CONFIG + { + int size_s = nr.choice.setup.nr_SecondaryCellGroupConfig_r15->size; + int i; + LOG_I(RRC, "Dumping nr_SecondaryCellGroupConfig: %d", size_s); + for (i=0; ibuf[i]); + printf("\n"); + + } +#endif + long sk_counter = 0; cr_1510.sk_Counter_r15 = &sk_counter; @@ -179,6 +190,18 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, dummy_nr1_conf.size = 4; } +#ifdef DEBUG_SCG_CONFIG + { + int size_s = cr_1510.nr_RadioBearerConfig1_r15->size; + int i; + LOG_I(RRC, "Dumping nr_RadioBearerConfig1: %d", size_s); + for (i=0; ibuf[i]); + printf("\n"); + + } +#endif + + OCTET_STRING_t nr2_conf; unsigned char nr2_buf[4] = { 0, 0, 0, 0 }; cr_1510.nr_RadioBearerConfig2_r15 = &nr2_conf; From 6c3d5cf02d6a419a5f004bd10036a05d7bacc2a2 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 10 Jan 2020 13:27:02 +0100 Subject: [PATCH 127/343] 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 128/343] 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 129/343] 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 130/343] 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 fb9db399aef833c9f813e9a007e28e56ee4d2eaf Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 6 Jan 2020 12:45:37 +0100 Subject: [PATCH 131/343] 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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 1784098b79..a87585289b 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -82,8 +82,8 @@ #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_ENB 4 + #define MAX_MOBILES_PER_ENB_NB_IoT 4 #define MAX_MOBILES_PER_GNB 2//16 #define MAX_eNB 2 #define MAX_gNB 2 From 4472e6d0418ebc3ed1160e1f2a3a7feb656ad32b Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 14 Jan 2020 15:33:40 +0100 Subject: [PATCH 132/343] ENDC: Modifications at the gNB slave conf. file used for ENDC --- .../CONF/gnb.band78.slave.conf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf index b7ebb6ed8c..771f5d1839 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -22,6 +22,7 @@ gNBs = ////////// Physical parameters: ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -147,12 +148,12 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; - ssb_PositionsInBurst_Bitmap = 255; + ssb_PositionsInBurst_Bitmap = 15; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 - ssb_periodicityServingCell = 2 -; + ssb_periodicityServingCell = 2; + # dmrs_TypeA_position # 0 = pos2, 1 = pos3 dmrs_TypeA_Position = 0; @@ -165,15 +166,15 @@ gNBs = #tdd-UL-DL-ConfigurationCommon # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - referenceSubcarrierSpacing = 2; + referenceSubcarrierSpacing = 1; # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 0; - nrofDownlinkSlots = 7; - nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; - nrofUplinkSymbols = 4; + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 2; + nrofDownlinkSymbols = 1; + nrofUplinkSlots = 7; + nrofUplinkSymbols = 7; ssPBCH_BlockPower = 10; } @@ -212,13 +213,13 @@ gNBs = NETWORK_INTERFACES : { - GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.107/24"; + GNB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.75/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.107/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.75/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 - GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.107/23"; + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.75/23"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 }; } @@ -281,4 +282,3 @@ THREAD_STRUCT = ( rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - From 7292fb2505d257478e869f595427038d9cca7060 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 15 Jan 2020 12:56:52 +0100 Subject: [PATCH 133/343] 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 17090f22c12a903d845839f31f3e8e5c7961aee0 Mon Sep 17 00:00:00 2001 From: cig Date: Wed, 15 Jan 2020 15:42:53 +0100 Subject: [PATCH 134/343] Fixed sdu initialization: this was causing assertion failure at UE side --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 02f217ced5..4e404a4e80 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -389,8 +389,8 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //Sending SDUs with size 1 //Initialize elements of sdu_lcids and sdu_lengths sdu_lcids[0] = 0x05; // DRB - sdu_lengths[0] = TBS_bytes-3; - header_length_total += 2; + sdu_lengths[0] = TBS_bytes - ta_len - 3; + header_length_total += 2 + (sdu_lengths[0] >= 128); sdu_length_total += sdu_lengths[0]; num_sdus +=1; } // else IS_SOFTMODEM_NOS1 From 2a92d27badc0791b9c51f2c6842a2c5f5f7c0044 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 15 Jan 2020 15:59:10 +0100 Subject: [PATCH 135/343] 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 136/343] 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 137/343] 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 138/343] 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 139/343] 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 92c100bb5a326dbb26ea914653e873675231fa6d Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Thu, 16 Jan 2020 11:30:27 +0100 Subject: [PATCH 140/343] remove uhd_set_thread_priority function --- executables/nr-ru.c | 7 ------- targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c | 1 - targets/ARCH/COMMON/common_lib.h | 4 ---- targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c | 1 - targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 1 - targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp | 1 - targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 11 ----------- targets/ARCH/tcp_bridge/tcp_bridge.c | 1 - targets/ARCH/tcp_bridge/tcp_bridge_oai.c | 1 - 9 files changed, 28 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index a9c306461c..af8fb6c131 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1250,13 +1250,6 @@ static void *ru_thread_tx( void *param ) { wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); printf( "ru_thread_tx ready\n"); - - if(ru->rfdevice.uhd_set_thread_priority != NULL) - { - LOG_I(PHY,"set ru_thread_tx uhd priority \n"); - ru->rfdevice.uhd_set_thread_priority(); - } - while (!oai_exit) { LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index f6ac1fc6e1..c4e593ca92 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -1147,7 +1147,6 @@ int device_init(openair0_device *device, device->trx_set_gains_func = trx_brf_set_gains; device->openair0_cfg = openair0_cfg; device->priv = (void *)brf; - device->uhd_set_thread_priority = NULL; calibrate_rf(device); diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 7052d6d40b..bba6bcd93d 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -400,10 +400,6 @@ struct openair0_device_t { * \param arg pointer to capabilities or configuration */ void (*configure_rru)(int idx, void *arg); - - /*! \brief set UHD thread priority - */ - void (*uhd_set_thread_priority)(void); }; /* type of device init function, implemented in shared lib */ diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index 259b1fc277..c5822a3650 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -417,7 +417,6 @@ int transport_init(openair0_device *device, device->trx_stop_func = trx_eth_stop; device->trx_set_freq_func = trx_eth_set_freq; device->trx_set_gains_func = trx_eth_set_gains; - device->uhd_set_thread_priority = NULL; if (eth->flags == ETH_RAW_MODE) { device->trx_write_func = trx_eth_write_raw; diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index c563569506..a57ebf8b6d 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -405,7 +405,6 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg){ device->trx_stop_func = trx_lms_stop; device->trx_set_freq_func = trx_lms_set_freq; device->trx_set_gains_func = trx_lms_set_gains; - device->uhd_set_thread_priority = NULL; device->openair0_cfg = openair0_cfg; diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp index 9b11415631..6f1afe47c0 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp @@ -706,7 +706,6 @@ int openair0_dev_init_sodera(openair0_device* device, openair0_config_t *openair device->trx_stop_func = trx_sodera_stop; device->trx_set_freq_func = trx_sodera_set_freq; device->trx_set_gains_func = trx_sodera_set_gains; - device->uhd_set_thread_priority = NULL; s->sample_rate = openair0_cfg[0].sample_rate; s->channelscount = openair0_cfg[0].rx_num_channels; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e2418bcb76..eb8c6ec010 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -893,15 +893,6 @@ int trx_usrp_reset_stats(openair0_device *device) { return(0); } -/*! \brief Set uhd priority - */ -static void uhd_set_thread_priority(void) { - uhd::set_thread_priority_safe(1.0); -} - -void noop_func(void) { - return; -} extern "C" { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { LOG_D(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs); @@ -941,7 +932,6 @@ extern "C" { set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust); 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 { @@ -1294,7 +1284,6 @@ extern "C" { LOG_I(HW,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; - device->uhd_set_thread_priority = uhd_set_thread_priority; s->sample_rate = openair0_cfg[0].sample_rate; // TODO: diff --git a/targets/ARCH/tcp_bridge/tcp_bridge.c b/targets/ARCH/tcp_bridge/tcp_bridge.c index 3e2979f849..8b287acfa1 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge.c @@ -267,7 +267,6 @@ int device_init(openair0_device* device, openair0_config_t *openair0_cfg) device->trx_set_gains_func = tcp_bridge_set_gains; device->trx_write_func = tcp_bridge_write; device->trx_read_func = tcp_bridge_read; - device->uhd_set_thread_priority = NULL; device->priv = tcp_bridge; diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index 7c06d14360..c3d5355876 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -413,7 +413,6 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_freq_func = tcp_bridge_set_freq; device->trx_set_gains_func = tcp_bridge_set_gains; device->trx_write_func = tcp_bridge_write; - device->uhd_set_thread_priority = NULL; if (tcp_bridge->is_enb) { device->trx_read_func = tcp_bridge_read; From c82fd2e444713e50fda0352f64cacbc855eb8c3a Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 16 Jan 2020 12:34:30 +0100 Subject: [PATCH 141/343] 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 e41204899cf1503107406cd0be7a404b22892152 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 16 Jan 2020 14:04:36 +0100 Subject: [PATCH 142/343] Cleanup commented code and old lte code --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 25 - .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 1885 +---------------- 2 files changed, 12 insertions(+), 1898 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 4e404a4e80..59cf43cc06 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -273,7 +273,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, mac_rlc_status_resp_t rlc_status; nfapi_nr_config_request_t *cfg = &gNB_mac->config[0]; - // TODO not sure why NR_MAX_NB_RB was used here unsigned char sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; @@ -295,7 +294,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, ta_len = gNB_mac->ta_len; TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], gNB_mac->pdu_index[CC_id], dlsch_config); - //printf("TBS_bytes=%d (bytes)\n",TBS_bytes); //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving //through the LTE stack @@ -349,14 +347,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; - - /* - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - */ - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; @@ -369,18 +359,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } } - // // last header does not have length field - // if (header_length_total) { - // header_length_total -= header_length_last; - // header_length_total++; - // } - } //if (IS_SOFTMODEM_NOS1) else { //When the --NOS1 option is not enabled, DLSCH transmissions with random data //occur every time that the current function is called (dlsch phytest mode) - // fill dlsch_buffer with random data for (i = 0; i < TBS_bytes; i++){ mac_sdus[i] = (unsigned char) rand(); //i&0xFF; @@ -410,7 +393,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, post_padding = 0; } - offset = nr_generate_dlsch_pdu(module_idP, (unsigned char *) mac_sdus, (unsigned char *) mac_pdu, @@ -427,7 +409,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, mac_pdu[offset + j] = 0; } - //TX_req->segments[0].segment_length = 8; TX_req->segments[0].segment_length = TBS_bytes + 2; TX_req->segments[0].segment_data = mac_pdu; @@ -454,12 +435,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } #endif } - // Printing bit by bit for debugging purpose - /*for (int k = 0; k < TBS; k++){ - printf("MAC PDU %u\n",((( mac_payload[k/8]) & (1 << (k & 7))) >> (k & 7))); - if ((k+1)%8 == 0) - printf("\n"); - }*/ } else { // There is no data from RLC or MAC header, so don't schedule } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index f054d7c140..a707b2fb86 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -28,130 +28,34 @@ * @ingroup _mac */ -/* indented with: indent -kr eNB_scheduler_RA.c */ - #include "LAYER2/NR_MAC_gNB/mac_proto.h" -/* -#include "LAYER2/MAC/mac.h" -#include "LAYER2/MAC/mac_extern.h" -#include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "nfapi/oai_integration/vendor_ext.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" -#include "PHY/LTE_TRANSPORT/transport_common_proto.h" - -#include "RRC/LTE/rrc_extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - -#include "assertions.h" -#include "pdcp.h" - -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif - -#include "ENB_APP/flexran_agent_defs.h" -#include "flexran_agent_ran_api.h" -#include "header.pb-c.h" -#include "flexran.pb-c.h" -#include "flexran_agent_mac.h" -#include - -#include "T.h" - -#include "common/ran_context.h" -extern RAN_CONTEXT_t RC; - -#define ENABLE_MAC_PAYLOAD_DEBUG -#define DEBUG_eNB_SCHEDULER 1 - -extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); -extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); -extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset); -extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req);*/ - -/* -// This table holds the allowable PRB sizes for ULSCH transmissions -uint8_t rb_table[34] = { - 1, 2, 3, 4, 5, // 0-4 - 6, 8, 9, 10, 12, // 5-9 - 15, 16, 18, 20, 24, // 10-14 - 25, 27, 30, 32, 36, // 15-19 - 40, 45, 48, 50, 54, // 20-24 - 60, 64, 72, 75, 80, // 25-29 - 81, 90, 96, 100 // 30-33 -};*/ - -/*extern mui_t rrc_eNB_mui;*/ - -//----------------------------------------------------------------------------- /* * When data are received on PHY and transmitted to MAC */ -void -nr_rx_sdu(const module_id_t gnb_mod_idP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP, - uint8_t *sduP, - const uint16_t sdu_lenP, - const uint16_t timing_advance, - const uint8_t ul_cqi) -//----------------------------------------------------------------------------- -{ +void nr_rx_sdu(const module_id_t gnb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP, + uint8_t *sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, + const uint8_t ul_cqi){ int current_rnti = 0, UE_id = -1, harq_pid = 0; - // int RA_id = 0; - // int old_rnti = -1; - // int old_UE_id = -1; - // int crnti_rx = 0; - // int first_rb = 0; - // unsigned char num_ce = 0; - // unsigned char num_sdu = 0; - // unsigned char *payload_ptr = NULL; - // unsigned char rx_ces[MAX_NUM_CE]; - // unsigned char rx_lcids[NB_RB_MAX]; - // unsigned short rx_lengths[NB_RB_MAX]; - // uint8_t lcgid = 0; - // int lcgid_updated[4] = {0, 0, 0, 0}; - // rrc_eNB_ue_context_t *ue_contextP = NULL; gNB_MAC_INST *gNB_mac = NULL; UE_list_t *UE_list = NULL; UE_sched_ctrl_t *UE_scheduling_control = NULL; - // UE_TEMPLATE *UE_template_ptr = NULL; - /* Init */ current_rnti = rntiP; UE_id = find_nrUE_id(gnb_mod_idP, current_rnti); gNB_mac = RC.nrmac[gnb_mod_idP]; UE_list = &gNB_mac->UE_list; - - // harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); - // memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char)); - // memset(rx_lcids, 0, NB_RB_MAX * sizeof(unsigned char)); - // 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); - - // 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", - // gnb_mod_idP, - // frameP, - // current_rnti, - // sdu_lenP); - // } - - /* Hardcoded UE_id */ - UE_id = 0; + UE_id = 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", gnb_mod_idP, @@ -164,1772 +68,7 @@ nr_rx_sdu(const module_id_t gnb_mod_idP, UE_id, ul_cqi); - // AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); - - if (sduP != NULL) { - // UE_scheduling_control->ul_inactivity_timer = 0; - // UE_scheduling_control->ul_failure_timer = 0; - // UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); - /* LTE: Update with smoothing: 3/4 of old value and 1/4 of new. - * This is the logic that was done in the function - * lte_est_timing_advance_pusch, maybe it's not necessary? - * maybe it's even not correct at all? - * NR: smoothing removed - */ - //UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; - + if (sduP != NULL) UE_scheduling_control->ta_update = timing_advance; - // printf("UE_scheduling_control->ta_update %u\n", UE_scheduling_control->ta_update); - // 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) { - // UE_scheduling_control->ul_out_of_sync = 0; - // mac_eNB_rrc_ul_in_sync(gnb_mod_idP, CC_idP, frameP, subframeP, current_rnti); - // } - - /* Update bytes to schedule */ - // UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; - - // if (UE_template_ptr->scheduled_ul_bytes < 0) { - // UE_template_ptr->scheduled_ul_bytes = 0; - // } - } else { // sduP == NULL => error - // LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n", - // gnb_mod_idP, - // harq_pid, - // CC_idP, - // frameP, - // subframeP, - // UE_scheduling_control->round_UL[CC_idP][harq_pid], - // ul_cqi, - // UE_id, - // current_rnti); - - // if (ul_cqi > 200) { // too high energy pattern - // UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; - // LOG_W(MAC, "[MAC] Too high energy pattern\n"); - // } - - // if (UE_scheduling_control->round_UL[CC_idP][harq_pid] == 3) { - // UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); - // UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; - - // if (UE_scheduling_control->ul_consecutive_errors++ == 10) { - // UE_scheduling_control->ul_failure_timer = 1; - // } - - // /* Update scheduled bytes */ - // UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; - - // if (UE_template_ptr->scheduled_ul_bytes < 0) { - // UE_template_ptr->scheduled_ul_bytes = 0; - // } - - // if (find_RA_id(gnb_mod_idP, CC_idP, current_rnti) != -1) { - // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); - // } - // } else { - // UE_scheduling_control->round_UL[CC_idP][harq_pid]++; - // } - - // /* CDRX UL HARQ timers */ - // 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. - // * Start corresponding CDRX ULRetransmission timer. - // */ - // } - - // 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]; - // 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]; - // memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - // hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - // hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - // hi_dci0_req_body->number_of_hi++; - // hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 0); - // hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - // hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); - // hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - // return; - } - - // if UE_id == -1 - } // else if ((RA_id = find_RA_id(gnb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti - // RA_t *ra = (RA_t *) &(mac->common_channels[CC_idP].ra[RA_id]); - // #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - // if (ra->rach_resource_type > 0) { - // harq_pid = 0; - // } - - // #endif - // AssertFatal(mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 1, - // "maxHARQ %d should be greater than 1\n", - // (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); - // LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", - // gnb_mod_idP, - // harq_pid, - // CC_idP, - // ra->msg3_round, - // current_rnti, - // RA_id, - // ul_cqi); - // first_rb = ra->msg3_first_rb; - - // if (sduP == NULL) { // we've got an error on Msg3 - // LOG_D(MAC, "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", - // gnb_mod_idP, - // CC_idP, - // RA_id, - // ra->msg3_round, - // (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); - - // if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { - // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); - // } 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(gnb_mod_idP, CC_idP, ra, frameP, subframeP); - // } - // /* TODO: program NACK for PHICH? */ - // return; - // } - //} else { - // LOG_W(MAC, "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti); - // return; - //} - - //payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); - - //if (payload_ptr == NULL) { - // LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", - // gnb_mod_idP, - // harq_pid, - // CC_idP, - // current_rnti, - // UE_id); - // return; - //} - - //T(T_ENB_MAC_UE_UL_PDU, - // T_INT(gnb_mod_idP), - // T_INT(CC_idP), - // T_INT(current_rnti), - // T_INT(frameP), - // T_INT(subframeP), - // T_INT(harq_pid), - // T_INT(sdu_lenP), - // T_INT(num_ce), - // T_INT(num_sdu)); - //T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, - // T_INT(gnb_mod_idP), - // T_INT(CC_idP), - // T_INT(current_rnti), - // T_INT(frameP), - // T_INT(subframeP), - // T_INT(harq_pid), - // T_INT(sdu_lenP), - // T_INT(num_ce), - // T_INT(num_sdu), - // T_BUFFER(sduP, sdu_lenP)); - //mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; - //mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; - //mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; - - //if (UE_id != -1) { - // UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; - //} - - ///* Control element */ - //for (int i = 0; i < num_ce; i++) { - // T(T_ENB_MAC_UE_UL_CE, - // T_INT(gnb_mod_idP), - // T_INT(CC_idP), - // T_INT(current_rnti), - // T_INT(frameP), - // T_INT(subframeP), - // T_INT(rx_ces[i])); - - // switch (rx_ces[i]) { // implement and process PHR + CRNTI + BSR - // case POWER_HEADROOM: - // if (UE_id != -1) { - // UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100); - - // if (UE_template_ptr->phr_info > 40) { - // UE_template_ptr->phr_info = 40; - // } - - // LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", - // gnb_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; - // } - - // payload_ptr += sizeof(POWER_HEADROOM_CMD); - // break; - - // case CRNTI: - // old_rnti = (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; - // old_UE_id = find_UE_id(gnb_mod_idP, old_rnti); - // LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", - // gnb_mod_idP, - // frameP, - // subframeP, - // CC_idP, - // rx_ces[i], - // i, - // num_ce, - // old_rnti, - // old_UE_id); - - // /* Receiving CRNTI means that the current rnti has to go away */ - // if (old_UE_id != -1) { - // if (mac_eNB_get_rrc_status(gnb_mod_idP,old_rnti) == RRC_HO_EXECUTION) { - // LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n", - // gnb_mod_idP, - // frameP, - // subframeP, - // 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; - - // if (UE_scheduling_control->ul_out_of_sync > 0) { - // UE_scheduling_control->ul_out_of_sync = 0; - // mac_eNB_rrc_ul_in_sync(gnb_mod_idP, - // CC_idP, - // frameP, - // subframeP, - // old_rnti); - // } - // UE_template_ptr->ul_SR = 1; - // UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; - // UE_list->UE_template[UE_PCCID(gnb_mod_idP, UE_id)][UE_id].configured = 1; - // cancel_ra_proc(gnb_mod_idP, - // CC_idP, - // frameP, - // current_rnti); - // } else { - // /* TODO: if the UE did random access (followed by a MAC uplink with - // * CRNTI) because none of its scheduling request was granted, then - // * according to 36.321 5.4.4 the UE's MAC will notify RRC to release - // * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply - // * default configuration for CQI reporting and scheduling requests, - // * which basically means that the CQI requests won't work anymore and - // * that the UE won't do any scheduling request anymore as long as the - // * eNB doesn't reconfigure the UE. - // * We have to take care of this. As the code is, nothing is done and - // * the UE state in the eNB is wrong. - // */ - // RA_id = find_RA_id(gnb_mod_idP, CC_idP, current_rnti); - - // if (RA_id != -1) { - // RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); - // int8_t ret = mac_rrc_data_ind(gnb_mod_idP, - // 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 - // #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", - // gnb_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; - - // if (UE_scheduling_control->ul_out_of_sync > 0) { - // UE_scheduling_control->ul_out_of_sync = 0; - // mac_eNB_rrc_ul_in_sync(gnb_mod_idP, CC_idP, frameP, subframeP, old_rnti); - // } - // UE_template_ptr->ul_SR = 1; - // UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; - // } else { - // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); - // } - // // break; - // } - // } - // } else { - // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); - // LOG_W(MAC, "[MAC] Can't find old UE_id\n"); - // } - - // crnti_rx = 1; - // payload_ptr += 2; // sizeof(CRNTI) - // break; - - // case TRUNCATED_BSR: - // case SHORT_BSR: - // lcgid = (payload_ptr[0] >> 6); - // LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - // gnb_mod_idP, - // CC_idP, - // rx_ces[i], - // lcgid, - // payload_ptr[0] & 0x3f); - - // if (UE_id != -1) { - // int bsr = 0; - // bsr = payload_ptr[0] & 0x3f; - // lcgid_updated[lcgid] = 1; - // /* Update buffer info */ - // UE_template_ptr->ul_buffer_info[lcgid] = BSR_TABLE[bsr]; - // 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]; - - // RC.eNB[gnb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); - - // if (UE_id == UE_list->head) { - // VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, (payload_ptr[0] & 0x3f)); - // } - - // if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { - // UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; - // } - - // if (mac_eNB_get_rrc_status(gnb_mod_idP,UE_RNTI(gnb_mod_idP, UE_id)) < RRC_CONNECTED) { - // LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", - // gnb_mod_idP, - // CC_idP, - // rx_ces[i], - // UE_template_ptr->estimated_ul_buffer, - // UE_template_ptr->ul_buffer_info[lcgid]); - // } - // } else { - // /* Need error message */ - // } - - // payload_ptr += 1; // sizeof(SHORT_BSR) - // break; - - // case LONG_BSR: - // if (UE_id != -1) { - // int bsr0 = (payload_ptr[0] & 0xFC) >> 2; - // int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); - // int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); - // int bsr3 = payload_ptr[2] & 0x3F; - // lcgid_updated[LCGID0] = 1; - // lcgid_updated[LCGID1] = 1; - // lcgid_updated[LCGID2] = 1; - // lcgid_updated[LCGID3] = 1; - // /* Update buffer info */ - // UE_template_ptr->ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; - // 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", - // gnb_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", - // gnb_mod_idP, - // CC_idP, - // rx_ces[i]); - // } - - // for(int lcgid = 0; lcgid <= LCGID3; lcgid++) { - // if (UE_template_ptr->ul_buffer_info[lcgid] == 0) { - // UE_template_ptr->ul_buffer_creation_time[lcgid] = 0; - // } else if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { - // UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; - // } - // } - // } - - // payload_ptr += 3; // sizeof(LONG_BSR) - // break; - - // default: - // LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", - // gnb_mod_idP, - // CC_idP, - // rx_ces[i]); - // break; - //} // end switch on control element - //} // end for loop on control element - - // for (int i = 0; i < num_sdu; i++) { - // LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", - // i, - // rx_lcids[i], - // rx_lengths[i]); - // T(T_ENB_MAC_UE_UL_SDU, - // T_INT(gnb_mod_idP), - // T_INT(CC_idP), - // T_INT(current_rnti), - // T_INT(frameP), - // T_INT(subframeP), - // T_INT(rx_lcids[i]), - // T_INT(rx_lengths[i])); - // T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, - // T_INT(gnb_mod_idP), - // T_INT(CC_idP), - // T_INT(current_rnti), - // T_INT(frameP), - // T_INT(subframeP), - // T_INT(rx_lcids[i]), - // T_INT(rx_lengths[i]), - // T_BUFFER(payload_ptr, rx_lengths[i])); - - // switch (rx_lcids[i]) { - // case CCCH: - // if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - // LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", - // gnb_mod_idP, - // CC_idP, - // frameP, - // rx_lengths[i], - // CCCH_PAYLOAD_SIZE_MAX, - // sdu_lenP); - // break; - // } - - // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - // gnb_mod_idP, - // CC_idP, - // frameP, - // payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5], - // current_rnti); - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - // RA_id = find_RA_id(gnb_mod_idP, CC_idP, current_rnti); - - // if (RA_id != -1) { - // RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); - // LOG_D(MAC, "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", - // gnb_mod_idP, - // CC_idP, - // RA_id, - // ra->rnti, - // current_rnti, - // ra->state); - - // if (UE_id < 0) { - // memcpy(&(ra->cont_res_id[0]), payload_ptr, 6); - // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", - // gnb_mod_idP, - // CC_idP, - // frameP, - // rx_lengths[i], - // payload_ptr - sduP); - - // if ((UE_id = add_new_ue(gnb_mod_idP, CC_idP, ra->rnti, harq_pid - // #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - // , ra->rach_resource_type - // #endif - // )) == -1) { - // LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); - // cancel_ra_proc(gnb_mod_idP, CC_idP, frameP, current_rnti); // send Connection Reject ??? - // break; - // // kill RA proc - // } else { - // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", - // gnb_mod_idP, - // CC_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]); - // } - // } else { - // LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", - // gnb_mod_idP, - // CC_idP, - // frameP, - // UE_id, - // rx_lengths[i], - // payload_ptr - sduP); - // // kill RA proc - // } - - // mac_rrc_data_ind(gnb_mod_idP, - // CC_idP, - // frameP, subframeP, - // UE_id, - // current_rnti, - // CCCH, - // (uint8_t *) payload_ptr, - // rx_lengths[i], - // 0 - // #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - // ,ra->rach_resource_type > 0 - // #endif - // ); - - // if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest - // // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - // } - - // // prepare transmission of Msg4 - // ra->state = MSG4; - - // if(mac->common_channels[CC_idP].tdd_Config != NULL) { - // switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) { - // case 1: - // ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); - // ra->Msg4_subframe = (subframeP + 7) % 10; - // break; - - // default: - // printf("%s:%d: TODO\n", __FILE__, __LINE__); - // abort(); - // // TODO need to be complete for other tdd configs. - // } - // } else { - // /* Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, - // * Check if this is ok for BL/CE, or if the rule is different - // */ - // ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); - // ra->Msg4_subframe = (subframeP + 4) % 10; - // } - - // UE_scheduling_control->crnti_reconfigurationcomplete_flag = 0; - // } // if RA process is active - - // break; - - // case DCCH: - // case DCCH1: - //#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - // LOG_T(MAC, "offset: %d\n", (unsigned char) ((unsigned char *) payload_ptr - sduP)); - // - // for (int j = 0; j < 32; j++) { - // LOG_T(MAC, "%x ", payload_ptr[j]); - // } - // - // LOG_T(MAC, "\n"); - //#endif - // - // if (UE_id != -1) { - // if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { - // /* Adjust buffer occupancy of the correponding logical channel group */ - // if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) - // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; - // else - // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; - // - // UE_template_ptr->estimated_ul_buffer = - // UE_template_ptr->ul_buffer_info[0] + - // UE_template_ptr->ul_buffer_info[1] + - // UE_template_ptr->ul_buffer_info[2] + - // UE_template_ptr->ul_buffer_info[3]; - // //UE_template_ptr->estimated_ul_buffer += UE_template_ptr->estimated_ul_buffer / 4; - // } - // - // LOG_D(MAC, - // "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", - // gnb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - // rx_lcids[i]); - // mac_rlc_data_ind(gnb_mod_idP, current_rnti, gnb_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(gnb_mod_idP, current_rnti) < RRC_RECONFIGURED) { - // UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - // } - // } - // - // break; - // - // // all the DRBS - // case DTCH: - // default: - //#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - // LOG_T(MAC, "offset: %d\n", - // (unsigned char) ((unsigned char *) payload_ptr - sduP)); - // - // for (int j = 0; j < 32; j++) { - // LOG_T(MAC, "%x ", payload_ptr[j]); - // } - // - // LOG_T(MAC, "\n"); - //#endif - // - // if (rx_lcids[i] < NB_RB_MAX) { - // LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", - // gnb_mod_idP, - // CC_idP, - // frameP, - // rx_lengths[i], - // UE_id, - // rx_lcids[i]); - // - // if (UE_id != -1) { - // /* Adjust buffer occupancy of the correponding logical channel group */ - // LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", - // gnb_mod_idP, - // CC_idP, - // frameP, - // rx_lengths[i], - // UE_id, - // rx_lcids[i], - // UE_template_ptr->lcgidmap[rx_lcids[i]], - // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]]); - // - // if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { - // if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { - // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; - // } else { - // UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; - // } - // - // UE_template_ptr->estimated_ul_buffer = - // UE_template_ptr->ul_buffer_info[0] + - // UE_template_ptr->ul_buffer_info[1] + - // UE_template_ptr->ul_buffer_info[2] + - // UE_template_ptr->ul_buffer_info[3]; - // } - // - // if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - // mac_rlc_data_ind(gnb_mod_idP, current_rnti, gnb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); - // 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]; - // /* 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[gnb_mod_idP], current_rnti); - // - // if (ue_contextP != NULL) { - // ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; - // } else { - // LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", - // gnb_mod_idP, - // CC_idP, - // current_rnti); - // } - // } else { /* rx_length[i] Max size */ - // UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; - // LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", - // gnb_mod_idP, - // CC_idP, - // frameP, - // rx_lcids[i], - // UE_id); - // } - // } else { // end if (UE_id != -1) - // LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", - // gnb_mod_idP, - // CC_idP, - // frameP, - // rx_lcids[i], - // UE_id); - // } - // } - // - // break; - // } - // - // payload_ptr += rx_lengths[i]; - // } - // - // /* CDRX UL HARQ timers */ - // if (UE_id != -1) { - // 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 - // * Stop corresponding CDRX ULRetransmission timer - // */ - // } - // } - // - // /* Program ACK for PHICH */ - // LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", - // 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]; - // memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - // hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - // hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - // hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; - // hi_dci0_req_body->number_of_hi++; - // hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); - // hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - // hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); - // hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - // - // /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ - // if ((num_sdu == 0) && (num_ce == 0)) { - // if (UE_id != -1) - // UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; - // } else { - // if (UE_id != -1) { - // UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; - // UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP; - // UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; - // } - // } - // - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); - // stop_meas(&mac->rx_ulsch_sdu); -} - -//----------------------------------------------------------------------------- -// -// Return the BSR table index corresponding to the number of bytes in input -// -/*uint32_t -bytes_to_bsr_index(int32_t nbytes) -//----------------------------------------------------------------------------- -{ - uint32_t i = 0; - - if (nbytes < 0) { - return (0); } - - while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { - i++; - } - - return (i - 1); -}*/ - -//----------------------------------------------------------------------------- -// Add ue info in eNB_ulsch_info[module_idP][CC_id][UE_id] struct -/* -void -add_ue_ulsch_info(module_id_t module_idP, - int CC_id, - int UE_id, - sub_frame_t subframeP, - UE_ULSCH_STATUS status) -//----------------------------------------------------------------------------- -{ - eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); - eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; - eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; -}*/ - -/*----------------------------------------------------------------------------- -// -// Parse MAC header from ULSCH -/// -unsigned char * -parse_ulsch_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) -//----------------------------------------------------------------------------- -{ - unsigned char not_done = 1; - unsigned char num_ces = 0; - unsigned char num_sdus = 0; - unsigned char lcid = 0; - unsigned char num_sdu_cnt = 0; - unsigned char *mac_header_ptr = NULL; - unsigned short length, ce_len = 0; - // Init - mac_header_ptr = mac_header; - - while (not_done == 1) { - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - not_done = 0; - } - - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - - if (lcid < EXTENDED_POWER_HEADROOM) { - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = tb_length - (mac_header_ptr - mac_header) - ce_len; - - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } - } else { - if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); - } else { // F = 1 - length = ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & 0x7f) << 8) | - (((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB & 0xff); - mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); - } - } - - LOG_D(MAC, "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", - num_sdus, - lcid, - tb_length, - length, - mac_header_ptr - mac_header); - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI - if (lcid == SHORT_PADDING) { - mac_header_ptr++; - } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - - if (lcid == LONG_BSR) { - ce_len += 3; - } else if (lcid == CRNTI) { - ce_len += 2; - } else if ((lcid == POWER_HEADROOM) || (lcid == TRUNCATED_BSR) || (lcid == SHORT_BSR)) { - ce_len++; - } else { - LOG_E(MAC, "unknown CE %d \n", lcid); - return NULL; - } - } - } - } - - *num_ce = num_ces; - *num_sdu = num_sdus; - return (mac_header_ptr); -}*/ - -//----------------------------------------------------------------------------- -// This function is called by PHY layer when it schedules some -// uplink for a random access message 3. -// The MAC scheduler has to skip the RBs used by this message 3 -// (done below in schedule_ulsch). -// This function seems to be unused, the Msg3_subframe is set somewhere else... -// In NFAPI?? -/// -/*void -set_msg3_subframe(module_id_t mod_id, - int CC_id, - int frame, // Not used, remove? - int subframe, // Not used, remove? - int rnti, - int Msg3_frame, // Not used, remove? - int Msg3_subframe) -//----------------------------------------------------------------------------- -{ - int RA_id = 0; - // Init - RA_id = find_RA_id(mod_id, CC_id, rnti); // state == WAITMSG3 instead of state != IDLE (?) - - if (RA_id != -1) { - RC.mac[mod_id]->common_channels[CC_id].ra[RA_id].Msg3_subframe = Msg3_subframe; - } else { - LOG_E(MAC, "[MAC] Unknown RAPROC associated to RNTI %x\n", rnti); - } - - return; -}*/ - -/* -//----------------------------------------------------------------------------- -// -//Main function called for uplink scheduling (DCI0). -// -void -schedule_ulsch(module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP) -//----------------------------------------------------------------------------- -{ - uint16_t first_rb[NFAPI_CC_MAX]; - eNB_MAC_INST *mac = NULL; - slice_info_t *sli = NULL; - 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; - - // For TDD: check subframes where we have to act and return if nothing should be done now - if (cc->tdd_Config) { // Done only for CC_id = 0, assume tdd_Config for all CC_id - int tdd_sfa = cc->tdd_Config->subframeAssignment; - - switch (subframeP) { - case 0: - if ((tdd_sfa == 0) || (tdd_sfa == 3)) - sched_subframe = 4; - else if (tdd_sfa == 6) - sched_subframe = 7; - else - return; - - break; - - case 1: - if ((tdd_sfa == 0) || (tdd_sfa == 1)) - sched_subframe = 7; - else if (tdd_sfa == 6) - sched_subframe = 8; - else - return; - - break; - - case 2: // Don't schedule UL in subframe 2 for TDD - return; - - case 3: - if (tdd_sfa == 2) - sched_subframe = 7; - else - return; - - break; - - case 4: - if (tdd_sfa == 1) - sched_subframe = 8; - else - return; - - break; - - case 5: - if (tdd_sfa == 0) - sched_subframe = 9; - else if (tdd_sfa == 6) - sched_subframe = 2; - else - return; - - break; - - case 6: - if (tdd_sfa == 0 || tdd_sfa == 1) - sched_subframe = 2; - else if (tdd_sfa == 6) - sched_subframe = 3; - else - return; - - break; - - case 7: - return; - - case 8: - if ((tdd_sfa >= 2) && (tdd_sfa <= 5)) - sched_subframe = 2; - else - return; - - break; - - case 9: - if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) - sched_subframe = 3; - else if (tdd_sfa == 6) - sched_subframe = 4; - else - return; - - break; - - default: - return; - } - } - - if (sched_subframe < subframeP) { - sched_frame++; - sched_frame %= 1024; - } - -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int emtc_active[5]; - memset(emtc_active, 0, 5 * sizeof(int)); - schedule_ulsch_rnti_emtc(module_idP, frameP, subframeP, sched_subframe, emtc_active); -#endif - - // Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX - for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) { -#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); - } -#endif - RA_t *ra_ptr = cc->ra; - - // From Louis-Adrien to François: - // The comment bloc below is to configure with a command line. - // I took it from the equivalent part in the fairRR scheduler (around line 2578 in eNB_scheduler_fairRR.c). - // As said in the meeting, it seems to work only for small TBS. - // The cause of false RA still present with this fix is to investigate. - // - // Note: in the get_prach_prb_offset() function below, the last argument is frameP in eNB_scheduler_fairRR.c - // I think it should be sched_frame instead. This parameter has only impacts in case TDD and preamble format 4. - // To confirm. - // - // - // int start_rb = 0; - // int nb_rb = 6; - // LTE_DL_FRAME_PARMS *frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms); - // - // if (is_prach_subframe(frame_parms, sched_frame, sched_subframe) == 1) { - // start_rb = get_prach_prb_offset(frame_parms, - // frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - // frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, - // 0, // tdd_mapindex - // sched_frame); // Nf - // - // first_rb[CC_id] = start_rb + nb_rb; - // } - - // - // Check if RA (Msg3) is active in this subframeP, if so skip the PRB used for Msg3 - // Msg3 is using 1 PRB so we need to increase first_rb accordingly - // Not sure about the break (can there be more than 1 active RA procedure per CC_id and per subframe?) - // - for (int ra_index = 0; ra_index < NB_RA_PROC_MAX; ra_index++, ra_ptr++) { - if ((ra_ptr->state == WAITMSG3) && (ra_ptr->Msg3_subframe == sched_subframe)) { - if (first_rb[CC_id] < ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb) { - first_rb[CC_id] = ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb; - } - - // Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling - // on the same time resources. Also the performance improvement of breaking is low, - // since we will loop until the end, most of the time. - // I'm letting the break as a reminder, in case of misunderstanding the spec. - // - // break; - } - } - } - - // Run each enabled slice-specific schedulers one by one - for (int i = 0; i < sli->n_ul; i++) { - // By default the scheduler is schedule_ulsch_rnti (see below) - sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); - } - - stop_meas(&mac->schedule_ulsch); -}*/ - -/* -//----------------------------------------------------------------------------- -// Schedule the DCI0 for ULSCH -void -nr_schedule_ulsch_rnti(module_id_t module_idP, - int slice_idx, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframeP, - uint16_t *first_rb) -//----------------------------------------------------------------------------- -{ - rnti_t rnti = -1; - uint8_t aggregation = 2; - uint8_t round_index = 0; - uint8_t harq_pid = 0; - uint8_t status = 0; - uint8_t rb_table_index = -1; - uint8_t dlsch_flag = 0; - uint16_t ul_req_index = 0; - uint32_t cqi_req = 0; - uint32_t cshift = 0; - uint32_t ndi = 0; - uint32_t tpc = 0; - int32_t snr = 0; - int32_t target_snr = 0; - int32_t framex10psubframe = 0; - static int32_t tpc_accumulated = 0; - int sched_frame = 0; - int CC_id = 0; - eNB_MAC_INST *mac = NULL; - COMMON_channels_t *cc = NULL; - UE_list_t *UE_list = NULL; - slice_info_t *sli = NULL; - UE_TEMPLATE *UE_template_ptr = NULL; - UE_sched_ctrl_t *UE_sched_ctrl_ptr = NULL; - int rvidx_tab[4] = {0, 2, 3, 1}; - int first_rb_slice[NFAPI_CC_MAX]; - int n_rb_ul_tab[NFAPI_CC_MAX]; - // Init - mac = RC.mac[module_idP]; - cc = mac->common_channels; - UE_list = &(mac->UE_list); - sli = &(mac->slice_info); - memset(first_rb_slice, 0, NFAPI_CC_MAX * sizeof(int)); - memset(n_rb_ul_tab, 0, NFAPI_CC_MAX * sizeof(int)); - sched_frame = frameP; - - if (sched_subframeP < subframeP) { - sched_frame++; - sched_frame %= 1024; - } - - // NFAPI struct init - nfapi_hi_dci0_request_t *hi_dci0_req = &(mac->HI_DCI0_req[CC_id][subframeP]); - 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; - nfapi_ul_config_request_t *ul_req_tmp = &(mac->UL_req_tmp[CC_id][sched_subframeP]); - nfapi_ul_config_request_body_t *ul_req_tmp_body = &(ul_req_tmp->ul_config_request_body); - nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; - hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; - - // 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) - // - for 50: 2 RBs - // - for 100: 3 RBs - // This is totally arbitrary and might even be wrong. - // We suppose 'first_rb[]' has been correctly populated by the caller, - // 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); - } - 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 - // pre_allocated_rb_table_index_ul - /// - ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_frame, sched_subframeP, first_rb); - - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx]; - } - - // loop over all active UEs until end of function - for (int UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - 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 - if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured == FALSE) { - LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping UE scheduling \n", - module_idP, - frameP, - subframeP, - UE_id); - continue; - } - - rnti = UE_RNTI(module_idP, UE_id); - - if (rnti == NOT_A_RNTI) { - LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n", - module_idP, - frameP, - subframeP, - UE_id); - continue; - } - - // loop over all active UL CC_ids for this UE until end of function - 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); - round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid]; - AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n", - round_index, - UE_id, - rnti); - LOG_D(MAC, "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP, - frameP, - subframeP, - sched_frame, - sched_subframeP, - harq_pid, - UE_id, - rnti, - CC_id, - aggregation, - n_rb_ul_tab[CC_id]); - // Seems unused, only for debug // - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template_ptr->estimated_ul_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer); - - // - //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 - // - if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) { - LOG_D(MAC, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %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_index, - UE_template_ptr->ul_SR, - 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); - - // New transmission - if (round_index == 0) { - // 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); - - continue; - } - - // Should format_flag be 2 in CCE_allocation_infeasible??? - // 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); - - 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) { - case 1: - if(subframeP == 1 || subframeP == 6) { - cqi_req=0; - } - break; - - case 3: - if(subframeP == 1) { - cqi_req=0; - } - break; - - default: - LOG_E(MAC," TDD config not supported\n"); - break; - } - } - - if(cqi_req == 1) { - UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP; - } - } - } else { - LOG_D(MAC,"Clearing CQI request timer\n"); - UE_sched_ctrl_ptr->cqi_req_flag = 0; - UE_sched_ctrl_ptr->cqi_received = 0; - UE_sched_ctrl_ptr->cqi_req_timer = 0; - } - } - - //Power control - // - //Compute the expected ULSCH RX snr (for the stats) - //This is the normalized RX snr and this should be constant (regardless of mcs) - //Is not in dBm, unit from nfapi, converting to dBm - // - 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 - // - framex10psubframe = (UE_template_ptr->pusch_tpc_tx_frame * 10) + UE_template_ptr->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_ptr->pusch_tpc_tx_frame = frameP; - UE_template_ptr->pusch_tpc_tx_subframe = subframeP; - - if (snr > target_snr + 4) { - tpc = 0; // -1 - tpc_accumulated--; - } else if (snr < target_snr - 4) { - tpc = 2; // +1 - tpc_accumulated++; - } 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, - tpc_accumulated, - snr, - target_snr); - } - - ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator - UE_template_ptr->oldNDI_UL[harq_pid] = ndi; - 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_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid]; - - // CDRX - 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 - } - - if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul; - } else { - UE_template_ptr->mcs_UL[harq_pid] = 10; - rb_table_index = 5; // for PHR - } - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template_ptr->mcs_UL[harq_pid]; - - while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) || - (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) { - rb_table_index--; - } - - UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->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_ptr->mcs_UL[harq_pid]), - T_INT(first_rb_slice[CC_id]), - T_INT(rb_table[rb_table_index]), - T_INT(UE_template_ptr->TBS_UL[harq_pid]), - T_INT(ndi)); - // Store information for possible retransmission - UE_template_ptr->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_template_ptr->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; - UE_template_ptr->cqi_req[harq_pid] = cqi_req; - UE_sched_ctrl_ptr->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_ptr->ul_scheduled); - } - - // Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update - LOG_D(MAC, "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", - module_idP, - CC_id, - UE_id, - rnti, - UE_template_ptr->scheduled_ul_bytes, - UE_template_ptr->TBS_UL[harq_pid]); - UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid]; - LOG_D(MAC, "scheduled_ul_bytes, new %d\n", - UE_template_ptr->scheduled_ul_bytes); - // Cyclic shift for DM-RS - 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_ptr->cshift[harq_pid] = cshift; - // Setting DCI0 NFAPI struct - 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]; - memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template_ptr->mcs_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template_ptr->DAI_ul[sched_subframeP]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; - hi_dci0_req_body->number_of_dci++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = frameP << 4 | subframeP; - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - sched_frame, - sched_subframeP); - ul_req_index = 0; - dlsch_flag = 0; - - for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { - if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { - dlsch_flag = 1; - LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n", - frameP, - subframeP, - rnti, - ul_req_index); - break; - } - } - - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], - cqi_req, - cc, - UE_template_ptr->physicalConfigDedicated, - get_tmode(module_idP, CC_id, UE_id), - mac->ul_handle, - rnti, - first_rb_slice[CC_id], // resource_block_start - rb_table[rb_table_index], // number_of_resource_blocks - UE_template_ptr->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index])); -#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], - UE_template_ptr->rach_resource_type > 2 ? 2 : 1, - 1, // total_number_of_repetitions - 1, // repetition_number - (frameP * 10) + subframeP); - } -#endif - - if (dlsch_flag == 1) { - if (cqi_req == 1) { - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = - NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = - rb_table[rb_table_index]; - } else { - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = - NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - } - - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); - } else { - ul_req_tmp_body->number_of_pdus++; - } - - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - mac->ul_handle++; - ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP; - 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); - LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", - harq_pid, - frameP, - subframeP, - sched_frame, - sched_subframeP, - cqi_req, - UE_id, - rnti); - // Increment first rb for next UE allocation - first_rb_slice[CC_id] += rb_table[rb_table_index]; - } else { // round_index > 0 => retransmission - 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_ptr->mcs_UL[harq_pid]), - T_INT(UE_template_ptr->first_rb_ul[harq_pid]), - T_INT(UE_template_ptr->nb_rb_ul[harq_pid]), - T_INT(round_index)); - // Add UL_config PDUs - LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, - frameP, - subframeP, - UE_id, - rnti, - sched_frame, - sched_subframeP); - ul_req_index = 0; - dlsch_flag = 0; - cqi_req = UE_template_ptr->cqi_req[harq_pid]; - - for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { - if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { - dlsch_flag = 1; - LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n", - frameP, - subframeP, - rnti, - ul_req_index); - break; - } - } - - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], - cqi_req, - cc, - UE_template_ptr->physicalConfigDedicated, - get_tmode(module_idP, CC_id, UE_id), - mac->ul_handle, - rnti, - UE_template_ptr->first_rb_ul[harq_pid], // resource_block_start - UE_template_ptr->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template_ptr->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template_ptr->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round_index & 3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 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], - UE_template_ptr->rach_resource_type > 2 ? 2 : 1, - 1, // total_number_of_repetitions - 1, // repetition_number - (frameP * 10) + subframeP); - } -#endif - - if(dlsch_flag == 1) { - if(cqi_req == 1) { - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= - NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = - UE_template_ptr->nb_rb_ul[harq_pid]; - } else { - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = - NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = - UE_template_ptr->nb_rb_ul[harq_pid]; - } - - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information, subframeP); - } else { - ul_req_tmp_body->number_of_pdus++; - } - - mac->ul_handle++; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - 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); - - // HACK: RBs used by retransmission have to be reserved. - // The current mechanism uses the notion of 'first_rb', so - // we skip all RBs below the ones retransmitted. This is - // not correct. Imagine only RB 23 is retransmitted, then all - // RBs < 23 will be marked unusable for new transmissions (case where round == 0). - // Note also that this code works only if the preprocessor orders - // UEs with retransmission with higher priority than UEs with new - // transmission. - // All this should be cleaned up properly. - // - 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 - } // UE_is_to_be_scheduled - } // loop over all active CC_ids - } // loop over UE_ids -}*/ \ No newline at end of file +} \ No newline at end of file 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 143/343] 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 1f92529452a6c3a2e1123cdddfa2d76dc57903b7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Jan 2020 12:05:25 +0100 Subject: [PATCH 144/343] harmonize calloc parameters use: type *x = calloc(1, sizeof(*x)); everywhere to avoid bad types inside the sizeof. --- openair2/RRC/NR/rrc_gNB_reconfig.c | 386 ++++++++++++++--------------- 1 file changed, 193 insertions(+), 193 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 4e25818a76..84b99ed25e 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -58,31 +58,31 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t)); secondaryCellGroup->cellGroupId = scg_id; - NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(NR_RLC_BearerConfig_t)); + NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); RLC_BearerConfig->logicalChannelIdentity = 4; - RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(struct NR_RLC_BearerConfig__servedRadioBearer)); + RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=5; - RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(long)); + RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC)); *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true; - RLC_BearerConfig->rlc_Config=calloc(1,sizeof(struct NR_RLC_Config)); + RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; - RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(struct NR_RLC_Config__am)); - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(NR_SN_FieldLengthAM_t)); + RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am)); + RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); *RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64; RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500; RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(NR_SN_FieldLengthAM_t)); + RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); *RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15; - RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(struct NR_LogicalChannelConfig)); + RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters)); RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; @@ -91,32 +91,32 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(long)); + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup)); *RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false; RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL; - secondaryCellGroup->rlc_BearerToAddModList = calloc(1,sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); + secondaryCellGroup->rlc_BearerToAddModList = calloc(1,sizeof(*secondaryCellGroup->rlc_BearerToAddModList)); ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig); - secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(NR_MAC_CellGroupConfig_t)); + secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig)); secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL; secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL; - secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(NR_BSR_Config_t)); + secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config)); secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf80; secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf320; - secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(NR_TAG_Config_t)); + secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config)); secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; - secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(struct NR_TAG_Config__tag_ToAddModList)); - struct NR_TAG *tag=calloc(1,sizeof(struct NR_TAG)); + secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList)); + struct NR_TAG *tag=calloc(1,sizeof(*tag)); tag->tag_Id = 0; tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); - secondaryCellGroup->mac_CellGroupConfig->phr_Config = calloc(1,sizeof(struct NR_SetupRelease_PHR_Config)); + secondaryCellGroup->mac_CellGroupConfig->phr_Config = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->phr_Config)); secondaryCellGroup->mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(NR_PHR_Config_t)); + secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup)); secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf20; secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf0; secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB3; @@ -129,11 +129,11 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->mac_CellGroupConfig->ext1 = NULL; - secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(struct NR_PhysicalCellGroupConfig)); + secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig)); secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH=NULL; secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH=NULL; - secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=calloc(1,sizeof(NR_P_Max_t)); + secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1)); *secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=20; secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook=NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic; secondaryCellGroup->physicalCellGroupConfig->tpc_SRS_RNTI=NULL; @@ -143,10 +143,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->physicalCellGroupConfig->cs_RNTI=NULL; secondaryCellGroup->physicalCellGroupConfig->ext1=NULL; - secondaryCellGroup->spCellConfig = calloc(1,sizeof(struct NR_SpCellConfig)); - secondaryCellGroup->spCellConfig->servCellIndex = calloc(1,sizeof(NR_ServCellIndex_t)); + secondaryCellGroup->spCellConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig)); + secondaryCellGroup->spCellConfig->servCellIndex = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->servCellIndex)); *secondaryCellGroup->spCellConfig->servCellIndex = servCellIndex; - secondaryCellGroup->spCellConfig->reconfigurationWithSync=calloc(1,sizeof(struct NR_ReconfigurationWithSync)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->reconfigurationWithSync)); secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon=servingcellconfigcommon; secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity=(phy_test==1) ? 0x1234 : (taus()&0xffff); secondaryCellGroup->spCellConfig->reconfigurationWithSync->t304=NR_ReconfigurationWithSync__t304_ms2000; @@ -155,29 +155,29 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup; - secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(struct NR_RLF_TimersAndConstants)); + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->t310 = NR_RLF_TimersAndConstants__t310_ms2000; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n10; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n311 = NR_RLF_TimersAndConstants__n311_n1; - secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(struct NR_RLF_TimersAndConstants__ext1)); + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311_v1530 = NR_RLF_TimersAndConstants__ext1__t311_v1530_ms30000; secondaryCellGroup->spCellConfig->rlmInSyncOutOfSyncThreshold = NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(NR_ServingCellConfig_t)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->tdd_UL_DL_ConfigurationDedicated = NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(struct NR_BWP_DownlinkDedicated)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdcch_Config=NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config=calloc(1,sizeof(struct NR_SetupRelease_PDSCH_Config)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup = calloc(1,sizeof(struct NR_PDSCH_Config)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(struct NR_SetupRelease_DMRS_DownlinkConfig)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(struct NR_DMRS_DownlinkConfig)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; @@ -185,165 +185,165 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(long)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList)); - NR_TCI_State_t*tci0=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci0=calloc(1,sizeof(*tci0)); tci0->tci_StateId=0; tci0->qcl_Type1.cell=NULL; - tci0->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci0->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci0->qcl_Type1.bwp_Id)); *tci0->qcl_Type1.bwp_Id=1; tci0->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci0->qcl_Type1.referenceSignal.choice.csi_rs = 2; tci0->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci0); - NR_TCI_State_t*tci1=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci1=calloc(1,sizeof(*tci1)); tci1->tci_StateId=1; tci1->qcl_Type1.cell=NULL; - tci1->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci1->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci1->qcl_Type1.bwp_Id)); *tci1->qcl_Type1.bwp_Id=1; tci1->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci1->qcl_Type1.referenceSignal.choice.csi_rs = 6; tci1->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci1); - NR_TCI_State_t*tci2=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci2=calloc(1,sizeof(*tci2)); tci2->tci_StateId=2; tci2->qcl_Type1.cell=NULL; - tci2->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci2->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci2->qcl_Type1.bwp_Id)); *tci2->qcl_Type1.bwp_Id=1; tci2->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci2->qcl_Type1.referenceSignal.choice.csi_rs = 10; tci2->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci2); - NR_TCI_State_t *tci3=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t *tci3=calloc(1,sizeof(*tci3)); tci3->tci_StateId=3; tci3->qcl_Type1.cell=NULL; - tci3->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci3->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci3->qcl_Type1.bwp_Id)); *tci3->qcl_Type1.bwp_Id=1; tci3->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci3->qcl_Type1.referenceSignal.choice.csi_rs = 14; tci3->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci3); - NR_TCI_State_t*tci4=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci4=calloc(1,sizeof(*tci4)); tci4->tci_StateId=4; tci4->qcl_Type1.cell=NULL; - tci4->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci4->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci4->qcl_Type1.bwp_Id)); *tci4->qcl_Type1.bwp_Id=1; tci4->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci4->qcl_Type1.referenceSignal.choice.csi_rs = 18; tci4->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci4); - NR_TCI_State_t*tci5=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci5=calloc(1,sizeof(*tci5)); tci5->tci_StateId=5; tci5->qcl_Type1.cell=NULL; - tci5->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci5->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci5->qcl_Type1.bwp_Id)); *tci5->qcl_Type1.bwp_Id=1; tci5->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci5->qcl_Type1.referenceSignal.choice.csi_rs = 22; tci5->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci5); - NR_TCI_State_t*tci6=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci6=calloc(1,sizeof(*tci6)); tci6->tci_StateId=6; tci6->qcl_Type1.cell=NULL; - tci6->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci6->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci6->qcl_Type1.bwp_Id)); *tci6->qcl_Type1.bwp_Id=1; tci6->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci6->qcl_Type1.referenceSignal.choice.csi_rs = 26; tci6->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci6); - NR_TCI_State_t*tci7=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci7=calloc(1,sizeof(*tci7)); tci7->tci_StateId=7; tci7->qcl_Type1.cell=NULL; - tci7->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci7->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci7->qcl_Type1.bwp_Id)); *tci7->qcl_Type1.bwp_Id=1; tci7->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tci7->qcl_Type1.referenceSignal.choice.csi_rs = 30; tci7->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci7); - NR_TCI_State_t*tci8=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci8=calloc(1,sizeof(*tci8)); tci8->tci_StateId=8; tci8->qcl_Type1.cell=NULL; - tci8->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci8->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci8->qcl_Type1.bwp_Id)); *tci8->qcl_Type1.bwp_Id=1; tci8->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci8->qcl_Type1.referenceSignal.choice.ssb = 0; tci8->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci8); - NR_TCI_State_t*tci9=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci9=calloc(1,sizeof(*tci9)); tci9->tci_StateId=9; tci9->qcl_Type1.cell=NULL; - tci9->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci9->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci9->qcl_Type1.bwp_Id)); *tci9->qcl_Type1.bwp_Id=1; tci9->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci9->qcl_Type1.referenceSignal.choice.ssb = 1; tci9->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci9); - NR_TCI_State_t*tci10=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci10=calloc(1,sizeof(*tci10)); tci10->tci_StateId=10; tci10->qcl_Type1.cell=NULL; - tci10->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci10->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci10->qcl_Type1.bwp_Id)); *tci10->qcl_Type1.bwp_Id=1; tci10->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci10->qcl_Type1.referenceSignal.choice.ssb = 2; tci10->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci10); - NR_TCI_State_t*tci11=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci11=calloc(1,sizeof(*tci11)); tci11->tci_StateId=11; tci11->qcl_Type1.cell=NULL; - tci11->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci11->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci11->qcl_Type1.bwp_Id)); *tci11->qcl_Type1.bwp_Id=1; tci11->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci11->qcl_Type1.referenceSignal.choice.ssb = 3; tci11->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci11); - NR_TCI_State_t*tci12=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci12=calloc(1,sizeof(*tci12)); tci12->tci_StateId=12; tci12->qcl_Type1.cell=NULL; - tci12->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci12->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci12->qcl_Type1.bwp_Id)); *tci12->qcl_Type1.bwp_Id=1; tci12->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci12->qcl_Type1.referenceSignal.choice.ssb = 4; tci12->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci12); - NR_TCI_State_t*tci13=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci13=calloc(1,sizeof(*tci13)); tci13->tci_StateId=13; tci13->qcl_Type1.cell=NULL; - tci13->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci13->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci13->qcl_Type1.bwp_Id)); *tci13->qcl_Type1.bwp_Id=1; tci13->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci13->qcl_Type1.referenceSignal.choice.ssb = 5; tci13->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci13); - NR_TCI_State_t*tci14=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci14=calloc(1,sizeof(*tci14)); tci14->tci_StateId=14; tci14->qcl_Type1.cell=NULL; - tci14->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci14->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci14->qcl_Type1.bwp_Id)); *tci14->qcl_Type1.bwp_Id=1; tci14->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci14->qcl_Type1.referenceSignal.choice.ssb = 6; tci14->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci14); - NR_TCI_State_t*tci15=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tci15=calloc(1,sizeof(*tci15)); tci15->tci_StateId=15; tci15->qcl_Type1.cell=NULL; - tci15->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tci15->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci15->qcl_Type1.bwp_Id)); *tci15->qcl_Type1.bwp_Id=1; tci15->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tci15->qcl_Type1.referenceSignal.choice.ssb = 7; @@ -361,12 +361,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table=NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(long)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(struct NR_PDSCH_Config__prb_BundlingType__staticBundling)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = - calloc(1,sizeof(long)); + calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToAddModList=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToReleaseList=NULL; @@ -377,23 +377,23 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->sps_Config = NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig = calloc(1,sizeof(struct NR_SetupRelease_RadioLinkMonitoringConfig)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->present = NR_SetupRelease_RadioLinkMonitoringConfig_PR_setup; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup = calloc(1,sizeof(struct NR_RadioLinkMonitoringConfig)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->failureDetectionResourcesToAddModList=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->failureDetectionResourcesToReleaseList=NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount = calloc(1,sizeof(long)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount = NR_RadioLinkMonitoringConfig__beamFailureInstanceMaxCount_n3; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = calloc(1,sizeof(long)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = NR_RadioLinkMonitoringConfig__beamFailureDetectionTimer_pbfd2; secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList= NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList = calloc(1,sizeof(struct NR_ServingCellConfig__downlinkBWP_ToAddModList)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList)); - NR_BWP_Downlink_t *bwp=calloc(1,sizeof(NR_BWP_Downlink_t)); + NR_BWP_Downlink_t *bwp=calloc(1,sizeof(*bwp)); bwp->bwp_Id=1; - bwp->bwp_Common=calloc(1,sizeof(NR_BWP_DownlinkCommon_t)); + bwp->bwp_Common=calloc(1,sizeof(*bwp->bwp_Common)); // copy common BWP size from initial BWP except for bandwdith memcpy((void*)&bwp->bwp_Common->genericParameters, &servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters, @@ -401,41 +401,41 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Common->genericParameters.locationAndBandwidth=PRBalloc_to_locationandbandwidth(servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0); - bwp->bwp_Common->pdcch_ConfigCommon=calloc(1,sizeof(NR_SetupRelease_PDCCH_ConfigCommon_t)); + bwp->bwp_Common->pdcch_ConfigCommon=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon)); bwp->bwp_Common->pdcch_ConfigCommon->present = NR_SetupRelease_PDCCH_ConfigCommon_PR_setup; - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup = calloc(1,sizeof(NR_PDCCH_ConfigCommon_t)); + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup = calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup)); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=NULL; - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList)); - NR_SearchSpace_t *ss=calloc(1,sizeof(NR_SearchSpace_t)); + NR_SearchSpace_t *ss=calloc(1,sizeof(*ss)); ss->searchSpaceId = 1; - ss->controlResourceSetId=calloc(1,sizeof(NR_ControlResourceSetId_t)); + ss->controlResourceSetId=calloc(1,sizeof(*ss->controlResourceSetId)); *ss->controlResourceSetId=0; - ss->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(struct NR_SearchSpace__monitoringSlotPeriodicityAndOffset)); + ss->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss->monitoringSlotPeriodicityAndOffset)); ss->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; ss->duration=NULL; - ss->monitoringSymbolsWithinSlot = calloc(1,sizeof(BIT_STRING_t)); + ss->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss->monitoringSymbolsWithinSlot)); ss->monitoringSymbolsWithinSlot->buf = calloc(1,2); // should be '1100 0000 0000 00'B (LSB first!), first two symols in slot, adjust if needed ss->monitoringSymbolsWithinSlot->buf[1] = 0; ss->monitoringSymbolsWithinSlot->buf[0] = (1<<7) | (1<<6); ss->monitoringSymbolsWithinSlot->size = 2; ss->monitoringSymbolsWithinSlot->bits_unused = 2; - ss->nrofCandidates = calloc(1,sizeof(struct NR_SearchSpace__nrofCandidates)); + ss->nrofCandidates = calloc(1,sizeof(*ss->nrofCandidates)); ss->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; ss->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; - ss->searchSpaceType = calloc(1,sizeof(struct NR_SearchSpace__searchSpaceType)); + ss->searchSpaceType = calloc(1,sizeof(*ss->searchSpaceType)); ss->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; - ss->searchSpaceType->choice.common=calloc(1,sizeof(struct NR_SearchSpace__searchSpaceType__common)); - ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(struct NR_SearchSpace__searchSpaceType__common__dci_Format0_0_AndFormat1_0)); + ss->searchSpaceType->choice.common=calloc(1,sizeof(*ss->searchSpaceType->choice.common)); + ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss); @@ -443,14 +443,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->pagingSearchSpace=NULL; - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=calloc(1,sizeof(NR_SearchSpaceId_t)); + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)); *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=1; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ext1=NULL; - bwp->bwp_Common->pdsch_ConfigCommon=calloc(1,sizeof(NR_SetupRelease_PDSCH_ConfigCommon_t)); + bwp->bwp_Common->pdsch_ConfigCommon=calloc(1,sizeof(*bwp->bwp_Common->pdsch_ConfigCommon)); bwp->bwp_Common->pdsch_ConfigCommon->present = NR_SetupRelease_PDSCH_ConfigCommon_PR_setup; - bwp->bwp_Common->pdsch_ConfigCommon->choice.setup = calloc(1,sizeof(NR_PDSCH_ConfigCommon_t)); - bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList = calloc(1,sizeof(NR_PDSCH_TimeDomainResourceAllocationList_t)); + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup = calloc(1,sizeof(*bwp->bwp_Common->pdsch_ConfigCommon->choice.setup)); + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList = calloc(1,sizeof(*bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)); // copy PDSCH TimeDomainResourceAllocation from InitialBWP @@ -466,12 +466,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list,pdschi); } - bwp->bwp_Dedicated=calloc(1,sizeof(NR_BWP_DownlinkDedicated_t)); + bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated)); - bwp->bwp_Dedicated->pdcch_Config=calloc(1,sizeof(NR_SetupRelease_PDCCH_Config_t)); + bwp->bwp_Dedicated->pdcch_Config=calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config)); bwp->bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup; - bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(NR_PDCCH_Config_t)); - bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(struct NR_PDCCH_Config__controlResourceSetToAddModList)); + bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup)); + bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList)); NR_ControlResourceSet_t *coreset0 = calloc(1,sizeof(*coreset0)); coreset0->controlResourceSetId=1; // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B, @@ -488,10 +488,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco coreset0->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; - coreset0->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(struct NR_ControlResourceSet__tci_StatesPDCCH_ToAddList)); + coreset0->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList)); NR_TCI_StateId_t *tci[8]; for (int i=0;i<8;i++) { - tci[i]=calloc(1,sizeof(NR_TCI_StateId_t)); + tci[i]=calloc(1,sizeof(*tci[i])); *tci[i] = i; ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]); } @@ -501,17 +501,17 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset0); - bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(struct NR_PDCCH_Config__searchSpacesToAddModList)); - NR_SearchSpace_t *ss3 = calloc(1,sizeof(NR_SearchSpace_t)); - NR_SearchSpace_t *ss2 = calloc(1,sizeof(NR_SearchSpace_t)); + bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList)); + NR_SearchSpace_t *ss3 = calloc(1,sizeof(*ss3)); + NR_SearchSpace_t *ss2 = calloc(1,sizeof(*ss2)); ss3->searchSpaceId=3; - ss3->controlResourceSetId=calloc(1,sizeof(NR_ControlResourceSetId_t)); + ss3->controlResourceSetId=calloc(1,sizeof(*ss3->controlResourceSetId)); *ss3->controlResourceSetId=1; ss3->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss3->monitoringSlotPeriodicityAndOffset)); ss3->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; ss3->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0; ss3->duration=NULL; - ss3->monitoringSymbolsWithinSlot = calloc(1,sizeof(BIT_STRING_t)); + ss3->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss3->monitoringSymbolsWithinSlot)); ss3->monitoringSymbolsWithinSlot->buf = calloc(1,2); ss3->monitoringSymbolsWithinSlot->size = 2; ss3->monitoringSymbolsWithinSlot->bits_unused = 2; @@ -532,13 +532,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ss3->searchSpaceType->choice.common->dci_Format2_3=NULL; ss2->searchSpaceId=2; - ss2->controlResourceSetId=calloc(1,sizeof(NR_ControlResourceSetId_t)); + ss2->controlResourceSetId=calloc(1,sizeof(*ss2->controlResourceSetId)); *ss2->controlResourceSetId=1; ss2->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss2->monitoringSlotPeriodicityAndOffset)); ss2->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; ss2->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0; ss2->duration=NULL; - ss2->monitoringSymbolsWithinSlot = calloc(1,sizeof(BIT_STRING_t)); + ss2->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss2->monitoringSymbolsWithinSlot)); ss2->monitoringSymbolsWithinSlot->buf = calloc(1,2); ss2->monitoringSymbolsWithinSlot->size = 2; ss2->monitoringSymbolsWithinSlot->bits_unused = 2; @@ -566,11 +566,11 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config)); bwp->bwp_Dedicated->pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup; - bwp->bwp_Dedicated->pdsch_Config->choice.setup = calloc(1,sizeof(struct NR_PDSCH_Config)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(struct NR_SetupRelease_DMRS_DownlinkConfig)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(struct NR_DMRS_DownlinkConfig)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; @@ -578,165 +578,165 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(long)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(struct NR_PDSCH_Config__tci_StatesToAddModList)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); - NR_TCI_State_t*tcid0=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid0=calloc(1,sizeof(*tcid0)); tcid0->tci_StateId=0; tcid0->qcl_Type1.cell=NULL; - tcid0->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid0->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid0->qcl_Type1.bwp_Id)); *tcid0->qcl_Type1.bwp_Id=1; tcid0->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid0->qcl_Type1.referenceSignal.choice.csi_rs = 2; tcid0->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid0); - NR_TCI_State_t*tcid1=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid1=calloc(1,sizeof(*tcid1)); tcid1->tci_StateId=0; tcid1->qcl_Type1.cell=NULL; - tcid1->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid1->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid1->qcl_Type1.bwp_Id)); *tcid1->qcl_Type1.bwp_Id=1; tcid1->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid1->qcl_Type1.referenceSignal.choice.csi_rs = 6; tcid1->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid1); - NR_TCI_State_t*tcid2=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid2=calloc(1,sizeof(*tcid2)); tcid2->tci_StateId=2; tcid2->qcl_Type1.cell=NULL; - tcid2->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid2->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid2->qcl_Type1.bwp_Id)); *tcid2->qcl_Type1.bwp_Id=1; tcid2->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid2->qcl_Type1.referenceSignal.choice.csi_rs = 10; tcid2->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid2); - NR_TCI_State_t*tcid3=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid3=calloc(1,sizeof(*tcid3)); tcid3->tci_StateId=3; tcid3->qcl_Type1.cell=NULL; - tcid3->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid3->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid3->qcl_Type1.bwp_Id)); *tcid3->qcl_Type1.bwp_Id=1; tcid3->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid3->qcl_Type1.referenceSignal.choice.csi_rs = 14; tcid3->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid3); - NR_TCI_State_t*tcid4=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid4=calloc(1,sizeof(*tcid4)); tcid4->tci_StateId=4; tcid4->qcl_Type1.cell=NULL; - tcid4->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid4->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid4->qcl_Type1.bwp_Id)); *tcid4->qcl_Type1.bwp_Id=1; tcid4->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid4->qcl_Type1.referenceSignal.choice.csi_rs = 18; tcid4->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid4); - NR_TCI_State_t*tcid5=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid5=calloc(1,sizeof(*tcid5)); tcid5->tci_StateId=5; tcid5->qcl_Type1.cell=NULL; - tcid5->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid5->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid5->qcl_Type1.bwp_Id)); *tcid5->qcl_Type1.bwp_Id=1; tcid5->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid5->qcl_Type1.referenceSignal.choice.csi_rs = 22; tcid5->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid5); - NR_TCI_State_t*tcid6=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid6=calloc(1,sizeof(*tcid6)); tcid6->tci_StateId=6; tcid6->qcl_Type1.cell=NULL; - tcid6->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid6->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid6->qcl_Type1.bwp_Id)); *tcid6->qcl_Type1.bwp_Id=1; tcid6->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid6->qcl_Type1.referenceSignal.choice.csi_rs = 26; tcid6->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid6); - NR_TCI_State_t*tcid7=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid7=calloc(1,sizeof(*tcid7)); tcid7->tci_StateId=7; tcid7->qcl_Type1.cell=NULL; - tcid7->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid7->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid7->qcl_Type1.bwp_Id)); *tcid7->qcl_Type1.bwp_Id=1; tcid7->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; tcid7->qcl_Type1.referenceSignal.choice.csi_rs = 30; tcid7->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid7); - NR_TCI_State_t*tcid8=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid8=calloc(1,sizeof(*tcid8)); tcid8->tci_StateId=8; tcid8->qcl_Type1.cell=NULL; - tcid8->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid8->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid8->qcl_Type1.bwp_Id)); *tcid8->qcl_Type1.bwp_Id=1; tcid8->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid8->qcl_Type1.referenceSignal.choice.ssb = 0; tcid8->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid8); - NR_TCI_State_t*tcid9=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid9=calloc(1,sizeof(*tcid9)); tcid9->tci_StateId=9; tcid9->qcl_Type1.cell=NULL; - tcid9->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid9->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid9->qcl_Type1.bwp_Id)); *tcid9->qcl_Type1.bwp_Id=1; tcid9->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid9->qcl_Type1.referenceSignal.choice.ssb = 1; tcid9->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid9); - NR_TCI_State_t*tcid10=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid10=calloc(1,sizeof(*tcid10)); tcid10->tci_StateId=10; tcid10->qcl_Type1.cell=NULL; - tcid10->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid10->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid10->qcl_Type1.bwp_Id)); *tcid10->qcl_Type1.bwp_Id=1; tcid10->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid10->qcl_Type1.referenceSignal.choice.ssb = 2; tcid10->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid10); - NR_TCI_State_t*tcid11=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid11=calloc(1,sizeof(*tcid11)); tcid11->tci_StateId=11; tcid11->qcl_Type1.cell=NULL; - tcid11->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid11->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid11->qcl_Type1.bwp_Id)); *tcid11->qcl_Type1.bwp_Id=1; tcid11->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid11->qcl_Type1.referenceSignal.choice.ssb = 3; tcid11->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid11); - NR_TCI_State_t*tcid12=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid12=calloc(1,sizeof(*tcid12)); tcid12->tci_StateId=12; tcid12->qcl_Type1.cell=NULL; - tcid12->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid12->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid12->qcl_Type1.bwp_Id)); *tcid12->qcl_Type1.bwp_Id=1; tcid12->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid12->qcl_Type1.referenceSignal.choice.ssb = 4; tcid12->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid12); - NR_TCI_State_t*tcid13=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid13=calloc(1,sizeof(*tcid13)); tcid13->tci_StateId=13; tcid13->qcl_Type1.cell=NULL; - tcid13->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid13->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid13->qcl_Type1.bwp_Id)); *tcid13->qcl_Type1.bwp_Id=1; tcid13->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid13->qcl_Type1.referenceSignal.choice.ssb = 5; tcid13->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid13); - NR_TCI_State_t*tcid14=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid14=calloc(1,sizeof(*tcid14)); tcid14->tci_StateId=14; tcid14->qcl_Type1.cell=NULL; - tcid14->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid14->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid14->qcl_Type1.bwp_Id)); *tcid14->qcl_Type1.bwp_Id=1; tcid14->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid14->qcl_Type1.referenceSignal.choice.ssb = 6; tcid14->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid14); - NR_TCI_State_t*tcid15=calloc(1,sizeof(NR_TCI_State_t)); + NR_TCI_State_t*tcid15=calloc(1,sizeof(*tcid15)); tcid15->tci_StateId=15; tcid15->qcl_Type1.cell=NULL; - tcid15->qcl_Type1.bwp_Id=calloc(1,sizeof(NR_BWP_Id_t)); + tcid15->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid15->qcl_Type1.bwp_Id)); *tcid15->qcl_Type1.bwp_Id=1; tcid15->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; tcid15->qcl_Type1.referenceSignal.choice.ssb = 7; @@ -754,12 +754,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1; bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(long)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1; bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(struct NR_PDSCH_Config__prb_BundlingType__staticBundling)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = - calloc(1,sizeof(long)); + calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; bwp->bwp_Dedicated->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToAddModList=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToReleaseList=NULL; @@ -780,12 +780,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1; bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(long)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1; bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(struct NR_PDSCH_Config__prb_BundlingType__staticBundling)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = - calloc(1,sizeof(long)); + calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; bwp->bwp_Dedicated->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToAddModList=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToReleaseList=NULL; @@ -796,15 +796,15 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL; bwp->bwp_Dedicated->sps_Config = NULL; - bwp->bwp_Dedicated->radioLinkMonitoringConfig = calloc(1,sizeof(struct NR_SetupRelease_RadioLinkMonitoringConfig)); + bwp->bwp_Dedicated->radioLinkMonitoringConfig = calloc(1,sizeof(*bwp->bwp_Dedicated->radioLinkMonitoringConfig)); bwp->bwp_Dedicated->radioLinkMonitoringConfig->present = NR_SetupRelease_RadioLinkMonitoringConfig_PR_setup; - bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup = calloc(1,sizeof(struct NR_RadioLinkMonitoringConfig)); + bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup)); bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->failureDetectionResourcesToAddModList=NULL; bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->failureDetectionResourcesToReleaseList=NULL; - bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount = calloc(1,sizeof(long)); + bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount = calloc(1,sizeof(*bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount)); *bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureInstanceMaxCount = NR_RadioLinkMonitoringConfig__beamFailureInstanceMaxCount_n3; - bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = calloc(1,sizeof(long)); + bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = calloc(1,sizeof(*bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer)); *bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = NR_RadioLinkMonitoringConfig__beamFailureDetectionTimer_pbfd2; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list,bwp); @@ -816,12 +816,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig)); - NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1,sizeof(NR_BWP_UplinkDedicated_t)); + NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1,sizeof(*initialUplinkBWP)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP = initialUplinkBWP; initialUplinkBWP->pucch_Config = NULL; initialUplinkBWP->pusch_Config = calloc(1,sizeof(*initialUplinkBWP->pusch_Config)); initialUplinkBWP->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; - NR_PUSCH_Config_t *pusch_Config = calloc(1,sizeof(NR_PUSCH_Config_t)); + NR_PUSCH_Config_t *pusch_Config = calloc(1,sizeof(*pusch_Config)); initialUplinkBWP->pusch_Config->choice.setup = pusch_Config; pusch_Config->txConfig=calloc(1,sizeof(*pusch_Config->txConfig)); *pusch_Config->txConfig= NR_PUSCH_Config__txConfig_codebook; @@ -843,16 +843,16 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pusch_Config->pusch_PowerControl->msg3_Alpha = calloc(1,sizeof(*pusch_Config->pusch_PowerControl->msg3_Alpha)); *pusch_Config->pusch_PowerControl->msg3_Alpha = NR_Alpha_alpha1; pusch_Config->pusch_PowerControl->p0_NominalWithoutGrant = NULL; - pusch_Config->pusch_PowerControl->p0_AlphaSets = calloc(1,sizeof(pusch_Config->pusch_PowerControl->p0_AlphaSets)); - NR_P0_PUSCH_AlphaSet_t *aset = calloc(1,sizeof(NR_P0_PUSCH_AlphaSet_t)); + pusch_Config->pusch_PowerControl->p0_AlphaSets = calloc(1,sizeof(*pusch_Config->pusch_PowerControl->p0_AlphaSets)); + NR_P0_PUSCH_AlphaSet_t *aset = calloc(1,sizeof(*aset)); aset->p0_PUSCH_AlphaSetId=0; aset->p0=calloc(1,sizeof(*aset->p0)); *aset->p0 = 0; aset->alpha=calloc(1,sizeof(*aset->alpha)); *aset->alpha=NR_Alpha_alpha1; ASN_SEQUENCE_ADD(&pusch_Config->pusch_PowerControl->p0_AlphaSets->list,aset); - pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList = calloc(1,sizeof(pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList)); - NR_PUSCH_PathlossReferenceRS_t *pl = calloc(1,sizeof(NR_PUSCH_PathlossReferenceRS_t)); + pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList = calloc(1,sizeof(*pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList)); + NR_PUSCH_PathlossReferenceRS_t *pl = calloc(1,sizeof(*pl)); pl->pusch_PathlossReferenceRS_Id=0; pl->referenceSignal.present = NR_PUSCH_PathlossReferenceRS__referenceSignal_PR_csi_RS_Index; pl->referenceSignal.choice.csi_RS_Index=0; @@ -881,7 +881,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); initialUplinkBWP->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; - NR_SRS_Config_t *srs_Config = calloc(1,sizeof(NR_SRS_Config_t)); + NR_SRS_Config_t *srs_Config = calloc(1,sizeof(*srs_Config)); initialUplinkBWP->srs_Config->choice.setup=srs_Config; srs_Config->srs_ResourceSetToReleaseList=NULL; srs_Config->srs_ResourceSetToAddModList=calloc(1,sizeof(*srs_Config->srs_ResourceSetToAddModList)); @@ -937,7 +937,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)); - NR_BWP_Uplink_t *ubwp = calloc(1,sizeof(NR_BWP_Uplink_t)); + NR_BWP_Uplink_t *ubwp = calloc(1,sizeof(*ubwp)); ubwp->bwp_Id=1; ubwp->bwp_Common = calloc(1,sizeof(*ubwp->bwp_Common)); // copy bwp_Common from Initial UL BWP except for bandwidth @@ -953,15 +953,15 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated)); ubwp->bwp_Dedicated->pucch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; - NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(NR_PUCCH_Config_t)); + NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->choice.setup=pucch_Config; pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(NR_PUCCH_ResourceSet_t)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(NR_PUCCH_ResourceSet_t)); + NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); + NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(NR_PUCCH_ResourceId_t)); - NR_PUCCH_ResourceId_t *pucchresset0id1=calloc(1,sizeof(NR_PUCCH_ResourceId_t)); + NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); + NR_PUCCH_ResourceId_t *pucchresset0id1=calloc(1,sizeof(*pucchresset0id1)); *pucchresset0id0=1; ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); *pucchresset0id1=2; @@ -971,8 +971,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(NR_PUCCH_ResourceId_t)); - NR_PUCCH_ResourceId_t *pucchresset1id1=calloc(1,sizeof(NR_PUCCH_ResourceId_t)); + NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); + NR_PUCCH_ResourceId_t *pucchresset1id1=calloc(1,sizeof(*pucchresset1id1)); *pucchresset1id0=3; ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); *pucchresset1id1=4; @@ -1032,7 +1032,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucch_Config->format2->choice.setup)); + NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); pucch_Config->format2->choice.setup = pucchfmt2; pucchfmt2->interslotFrequencyHopping=NULL; pucchfmt2->additionalDMRS=NULL; @@ -1047,7 +1047,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); long *delay[8]; for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(long)); + delay[i] = calloc(1,sizeof(*delay[i])); *delay[i] = (i<6) ? (i+2) : 0; ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); } @@ -1063,17 +1063,17 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); pucch_Config->spatialRelationInfoToReleaseList=NULL; pucch_Config->pucch_PowerControl=calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(long)); + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = calloc(1,sizeof(long)); + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1)); *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(long)); + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = calloc(1,sizeof(long)); + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3)); *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = calloc(1,sizeof(long)); + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4)); *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = 0; - pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); + pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); p00->p0_PUCCH_Id=1; p00->p0_PUCCH_Value = 0; @@ -1099,7 +1099,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp); - secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(NR_BWP_Id_t)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = 1; secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching = NULL; @@ -1109,7 +1109,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdcch_ServingCellConfig=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig)); - NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = calloc(1,sizeof(NR_PDSCH_ServingCellConfig_t)); + NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = calloc(1,sizeof(*pdsch_servingcellconfig)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->present = NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup; secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup = pdsch_servingcellconfig; pdsch_servingcellconfig->codeBlockGroupTransmission = NULL; @@ -1125,7 +1125,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->present = NR_SetupRelease_CSI_MeasConfig_PR_setup; - NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1,sizeof(NR_CSI_MeasConfig_t)); + NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1,sizeof(*csi_MeasConfig)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup = csi_MeasConfig; csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList)); @@ -1575,9 +1575,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList)); csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL; - NR_NZP_CSI_RS_ResourceSet_t *nzpresset0=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSet_t)); + NR_NZP_CSI_RS_ResourceSet_t *nzpresset0=calloc(1,sizeof(*nzpresset0)); nzpresset0->nzp_CSI_ResourceSetId=0; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset00=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset00=calloc(1,sizeof(*nzpresset00)); *nzpresset00=0; ASN_SEQUENCE_ADD(&nzpresset0->nzp_CSI_RS_Resources.list,nzpresset00); nzpresset0->repetition=NULL; @@ -1585,19 +1585,19 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco nzpresset0->trs_Info=NULL; ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset0); if (n_physical_antenna_ports > 1) { - NR_NZP_CSI_RS_ResourceSet_t *nzpresset3=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSet_t)); + NR_NZP_CSI_RS_ResourceSet_t *nzpresset3=calloc(1,sizeof(*nzpresset3)); nzpresset3->nzp_CSI_ResourceSetId=3; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset30=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset30=calloc(1,sizeof(*nzpresset30)); *nzpresset30=2; ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset30); if (n_physical_antenna_ports > 3) { - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset31=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset31=calloc(1,sizeof(*nzpresset31)); *nzpresset31=3; ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset31); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset32=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset32=calloc(1,sizeof(*nzpresset32)); *nzpresset32=4; ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset32); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset33=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset33=calloc(1,sizeof(*nzpresset33)); *nzpresset33=5; ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset33); ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset3); @@ -1611,18 +1611,18 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco } if (n_physical_antenna_ports > 7) { - NR_NZP_CSI_RS_ResourceSet_t *nzpresset4=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSet_t)); + NR_NZP_CSI_RS_ResourceSet_t *nzpresset4=calloc(1,sizeof(*nzpresset4)); nzpresset4->nzp_CSI_ResourceSetId=4; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset40=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset40=calloc(1,sizeof(*nzpresset40)); *nzpresset40=6; ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset40); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset41=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset41=calloc(1,sizeof(*nzpresset41)); *nzpresset41=7; ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset41); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset42=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset42=calloc(1,sizeof(*nzpresset42)); *nzpresset42=8; ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset42); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset43=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset43=calloc(1,sizeof(*nzpresset43)); *nzpresset43=9; ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset43); nzpresset4->repetition=calloc(1,sizeof(*nzpresset4->repetition)); @@ -1633,18 +1633,18 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset4); } if (n_physical_antenna_ports > 15) { - NR_NZP_CSI_RS_ResourceSet_t *nzpresset5=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSet_t)); + NR_NZP_CSI_RS_ResourceSet_t *nzpresset5=calloc(1,sizeof(*nzpresset5)); nzpresset5->nzp_CSI_ResourceSetId=5; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset50=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset50=calloc(1,sizeof(*nzpresset50)); *nzpresset50=10; ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset50); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset51=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset51=calloc(1,sizeof(*nzpresset51)); *nzpresset51=11; ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset51); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset52=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset52=calloc(1,sizeof(*nzpresset52)); *nzpresset52=12; ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset52); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset53=calloc(1,sizeof(NR_NZP_CSI_RS_ResourceSetId_t)); + NR_NZP_CSI_RS_ResourceSetId_t *nzpresset53=calloc(1,sizeof(*nzpresset53)); *nzpresset53=13; ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset53); nzpresset5->repetition=calloc(1,sizeof(*nzpresset5->repetition)); @@ -1846,7 +1846,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco csires8->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires8); - NR_CSI_ResourceConfig_t *csires9 = calloc(1,sizeof(*csires10)); + NR_CSI_ResourceConfig_t *csires9 = calloc(1,sizeof(*csires9)); csires9->csi_ResourceConfigId=9; csires9->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); @@ -2023,7 +2023,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); - reconfig->secondaryCellGroup = calloc(1,sizeof(OCTET_STRING_t)); + reconfig->secondaryCellGroup = calloc(1,sizeof(*reconfig->secondaryCellGroup)); OCTET_STRING_fromBuf(reconfig->secondaryCellGroup, (const char*)scg_buffer, (enc_rval.encoded+7)>>3); From 2865eb95a6a59b8faaab9bdaf733c1d3d783e80c Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 17 Jan 2020 12:43:07 +0100 Subject: [PATCH 145/343] ENDC X2AP: Add generation of X2 sGNB Reconfiguration Complete message --- openair2/X2AP/x2ap_eNB.c | 6 +-- openair2/X2AP/x2ap_eNB_generate_messages.c | 62 +++++++++++++++++++++- openair2/X2AP/x2ap_eNB_generate_messages.h | 5 +- openair2/X2AP/x2ap_eNB_handler.c | 10 ++-- 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 2586d1aa63..39c3d77816 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -447,7 +447,7 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, } static -void x2ap_eNB_handle_sgNB_add_req_ack(instance_t instance, +void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_ENDC_sgnb_addition_req_ACK) { /* TODO: remove this hack (the goal is to find the correct @@ -483,7 +483,7 @@ void x2ap_eNB_handle_sgNB_add_req_ack(instance_t instance, //target = x2ap_get_eNB(NULL, 17, 0); target = x2ap_is_eNB_id_in_list (3585); //Currently hardcoded. Need to extract it differently DevAssert(target != NULL); - x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target, x2ap_ENDC_sgnb_addition_req_ACK, 0); + x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target, x2ap_ENDC_sgnb_addition_req_ACK, 0); } @@ -553,7 +553,7 @@ void *x2ap_task(void *arg) { break; case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: - x2ap_eNB_handle_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_gNB_trigger_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(received_msg)); LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n"); diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index eac3da0234..6dc4b675d1 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1673,7 +1673,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( } -int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, +int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id) { @@ -1792,3 +1792,63 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in return ret; } + + +int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBReconfigurationComplete_t *out; + X2AP_SgNBReconfigurationComplete_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBReconfigurationCompletion; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReconfigurationComplete; + out = &pdu.choice.initiatingMessage.value.choice.SgNBReconfigurationComplete; + + ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_SgNB_UE_X2AP_ID; + ie->value.choice.SgNB_UE_X2AP_ID = SgNB_ue_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_ResponseInformationSgNBReconfComp; + ie->value.choice.ResponseInformationSgNBReconfComp.present = X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp; + // meNBtoSgNBContainer should contain the RRCReconfigurationComplete message from the UE but in the specs 36.423(9.1.4.4) its presence is not mandatory + ie->value.choice.ResponseInformationSgNBReconfComp.choice.success_SgNBReconfComp.meNBtoSgNBContainer = NULL; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n"); + return -1; + } + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; + +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 9afcda6749..114ed84a68 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -72,6 +72,9 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); -int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id); +int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id); + +int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id); #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 208e6f716d..dc412d958b 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -121,7 +121,7 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_X2AP_PDU_t *pdu); static -int x2ap_gNB_handle_ENDC_sGNB_addition_response (instance_t instance, +int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu); @@ -156,7 +156,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* seNBinitiatedSeNBRelease */ { 0, 0, 0 }, /* seNBCounterCheck */ { 0, 0, 0 }, /* retrieveUEContext */ - { x2ap_gNB_handle_ENDC_sGNB_addition_request, x2ap_gNB_handle_ENDC_sGNB_addition_response, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/ + { x2ap_gNB_handle_ENDC_sGNB_addition_request, x2ap_eNB_handle_ENDC_sGNB_addition_response, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, @@ -1477,7 +1477,7 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, DevAssert(instance_p != NULL); x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); - return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); + return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); // Not the right place to call the X2 function. Used only initially for testing. } @@ -1782,7 +1782,7 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, static -int x2ap_gNB_handle_ENDC_sGNB_addition_response (instance_t instance, +int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu) @@ -1901,6 +1901,8 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_response (instance_t instance, itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(instance_p, x2ap_eNB_data,0,0); // Not the right place to call the X2 function. Used only initially for testing. + return 0; } From 41b739ebff51a9b655da6ac80a33789a41d10456 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 17 Jan 2020 13:09:07 +0100 Subject: [PATCH 146/343] ENDC X2AP: Add handling of sGNB Reconfiguration Complete message at gNB side --- openair2/COMMON/x2ap_messages_def.h | 1 + openair2/COMMON/x2ap_messages_types.h | 20 +++++++ openair2/RRC/NR/rrc_gNB.c | 4 ++ openair2/RRC/NR/rrc_gNB_reconfig.c | 4 +- openair2/X2AP/x2ap_eNB_decoder.c | 3 + openair2/X2AP/x2ap_eNB_handler.c | 86 ++++++++++++++++++++++++++- 6 files changed, 115 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index ddc2b255a5..8438fd1037 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -54,3 +54,4 @@ MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_sen /*SGnb bearer addition messages X2AP <-> RRC */ MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req) MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t , x2ap_ENDC_sgnb_addition_req_ACK) +MESSAGE_DEF(X2AP_ENDC_SGNB_RECONF_COMPLETE , MESSAGE_PRIORITY_MED, x2ap_ENDC_reconf_complete_t , x2ap_ENDC_sgnb_reconf_complete) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 4c1cb8c88e..23d6e543fa 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -40,6 +40,7 @@ #define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req #define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req #define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK +#define X2AP_ENDC_SGNB_RECONF_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_reconf_complete #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 @@ -68,6 +69,13 @@ typedef enum { X2AP_TX2_RELOC_OVERALL_TIMEOUT } x2ap_handover_cancel_cause_t; +typedef enum { + X2AP_RECONF_RESPONSE_SUCCESS, + X2AP_RECONF_RESPONSE_REJECT + /* Extensions may appear below */ + +} x2ap_sgNB_reconf_response_information_t; + typedef struct x2ap_handover_cancel_s { int rnti; x2ap_handover_cancel_cause_t cause; @@ -374,5 +382,17 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { } x2ap_ENDC_sgnb_addition_req_ACK_t; +typedef struct x2ap_ENDC_reconf_complete_s { + int MeNB_ue_x2_id; + + int SgNB_ue_x2_id; + + x2ap_sgNB_reconf_response_information_t reconf_response; + + uint8_t rrc_buffer[4096 /* arbitrary, big enough */]; + int rrc_buffer_size; + +} x2ap_ENDC_reconf_complete_t; + #endif /* X2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 81425d7640..eff5f61166 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -449,6 +449,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p)); break; + case X2AP_ENDC_SGNB_RECONF_COMPLETE: + LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n"); + break; + default: LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 84b99ed25e..98744abd2a 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -375,7 +375,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToAddModList=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToReleaseList=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->sps_Config = NULL; + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->sps_Config = NULL; //calloc(1,sizeof(struct NR_SetupRelease_SPS_Config)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->radioLinkMonitoringConfig->present = NR_SetupRelease_RadioLinkMonitoringConfig_PR_setup; @@ -794,7 +794,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToAddModList=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToReleaseList=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL; - bwp->bwp_Dedicated->sps_Config = NULL; + bwp->bwp_Dedicated->sps_Config = NULL; //calloc(1,sizeof(struct NR_SetupRelease_SPS_Config)); bwp->bwp_Dedicated->radioLinkMonitoringConfig = calloc(1,sizeof(*bwp->bwp_Dedicated->radioLinkMonitoringConfig)); bwp->bwp_Dedicated->radioLinkMonitoringConfig->present = NR_SetupRelease_RadioLinkMonitoringConfig_PR_setup; diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index b40abc5cb6..93b82c2765 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -65,6 +65,9 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) case X2AP_ProcedureCode_id_sgNBAdditionPreparation: X2AP_INFO("X2AP_ProcedureCode_id_sgNBAdditionPreparation message!\n"); break; + case X2AP_ProcedureCode_id_sgNBReconfigurationCompletion: + X2AP_INFO("X2AP_ProcedureCode_id_sgNBReconfigurationCompletion message!\n"); + break; default: X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index dc412d958b..c80507a78f 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -126,6 +126,12 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { @@ -157,7 +163,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* seNBCounterCheck */ { 0, 0, 0 }, /* retrieveUEContext */ { x2ap_gNB_handle_ENDC_sGNB_addition_request, x2ap_eNB_handle_ENDC_sGNB_addition_response, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/ - { 0, 0, 0 }, + { x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBReconfigurationCompletion*/ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, @@ -1907,5 +1913,83 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, } +static +int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) { + + X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete; + X2AP_SgNBReconfigurationComplete_IEs_t *ie; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + + DevAssert (pdu != NULL); + x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete; + + /*if (stream == 0) { + X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); + // TODO: send a x2 failure response + return 0; + }*/ + + X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + X2AP_INFO("X2AP Association id: %d \n",assoc_id); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE); + + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID; + + + /* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, + X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID; + + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, + X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + if(ie->value.choice.ResponseInformationSgNBReconfComp.present == X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){ + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_SUCCESS; + } + else { + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_REJECT; + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); + + + return 0; +} + From ad5706c88d1da6a6b9e49730b90be03704a3b6d4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Jan 2020 16:56:57 +0100 Subject: [PATCH 147/343] activate NR measurements for NR capable UEs many things hardcoded, to be refined --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 9 ++- openair2/RRC/LTE/rrc_defs.h | 1 + openair2/RRC/LTE/rrc_eNB.c | 89 +++++++++++++++++++++++++--- 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 71b767684a..ed9f5a161e 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3456,10 +3456,17 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, r14_30.nonCriticalExtension = &r15_10; OCTET_STRING_t req_freq; - unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 + + //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; + unsigned char req_freq_buf[21] = { +0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a + }; req_freq.buf = req_freq_buf; req_freq.size = 5; + req_freq.size = 21; r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index b57decb5b3..2540ee09bd 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -645,6 +645,7 @@ typedef struct eNB_RRC_UE_s { uint32_t ue_rrc_inactivity_timer; uint8_t e_rab_release_command_flag; int8_t reestablishment_xid; + int does_nr; } eNB_RRC_UE_t; typedef uid_t ue_uid_t; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 00e17b686b..086f7c3a8b 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -2815,11 +2815,14 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t LTE_MAC_MainConfig_t *mac_MainConfig = NULL; LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; LTE_MeasObjectToAddMod_t *MeasObj = NULL; + LTE_MeasObjectToAddMod_t *MeasObj2 = NULL; LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + LTE_ReportConfigToAddMod_t *ReportConfig_NR = NULL; LTE_MeasIdToAddModList_t *MeasId_list = NULL; LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + LTE_MeasIdToAddMod_t *MeasId6; long *sr_ProhibitTimer_r9 = NULL; long *logicalchannelgroup = NULL; long *logicalchannelgroup_drb = NULL; @@ -3116,6 +3119,16 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t MeasId5->measObjectId = 1; MeasId5->reportConfigId = 6; ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5); + + if (ue_context_pP->ue_context.does_nr) { + MeasId6 = calloc(1, sizeof(LTE_MeasIdToAddMod_t)); + if (MeasId6 == NULL) exit(1); + MeasId6->measId = 7; + MeasId6->measObjectId = 2; + MeasId6->reportConfigId = 7; + ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId6); + } + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; // Add one EUTRA Measurement Object MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); @@ -3165,6 +3178,27 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; + if (ue_context_pP->ue_context.does_nr) { + MeasObj2 = calloc(1, sizeof(LTE_MeasObjectToAddMod_t)); + if (MeasObj2 == NULL) exit(1); + MeasObj2->measObjectId = 2; + MeasObj2->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15; + MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = 642256; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016) + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15; + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0; + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4; + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30; + MeasObj2->measObject.choice.measObjectNR_r15.quantityConfigSet_r15 = 1; + MeasObj2->measObject.choice.measObjectNR_r15.ext1 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1)); + if (MeasObj2->measObject.choice.measObjectNR_r15.ext1 == NULL) exit(1); + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1__bandNR_r15)); + if (MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 == NULL) exit(1); + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->present = LTE_MeasObjectNR_r15__ext1__bandNR_r15_PR_setup; + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78; + + ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj2); + } + if (!ue_context_pP->ue_context.measurement_info->events) { ue_context_pP->ue_context.measurement_info->events = CALLOC(1,sizeof(*(ue_context_pP->ue_context.measurement_info->events))); } @@ -3177,6 +3211,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3)); ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4)); ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); + if (ue_context_pP->ue_context.does_nr) { + ReportConfig_NR = CALLOC(1, sizeof(*ReportConfig_NR)); + } ReportConfig_per->reportConfigId = 1; ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -3282,6 +3319,30 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); + + if (ue_context_pP->ue_context.does_nr) { + ReportConfig_NR->reportConfigId = 7; + ReportConfig_NR->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigInterRAT; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.present = LTE_ReportConfigInterRAT__triggerType_PR_event; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.present = LTE_ReportConfigInterRAT__triggerType__event__eventId_PR_eventB1_NR_r15; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.present = LTE_ThresholdNR_r15_PR_nr_RSRP_r15; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.choice.nr_RSRP_r15 = 46; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = FALSE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.hysteresis = 2; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms80; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.maxReportCells = 4; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.reportAmount = LTE_ReportConfigInterRAT__reportAmount_infinity; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7 = calloc(1, sizeof(struct LTE_ReportConfigInterRAT__ext7)); + if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7 == NULL) exit(1); + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 = calloc(1, sizeof(struct LTE_ReportQuantityNR_r15)); + if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 == NULL) exit(1); + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = TRUE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = TRUE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = TRUE; + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_NR); + } + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; /* A3 event update */ @@ -7660,18 +7721,28 @@ rrc_eNB_decode_dcch( ue_context_p->ue_context.UE_Capability = 0; } + int eutra_index = -1; + + for (i = 0; i < ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count; i++) { + if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type == LTE_RAT_Type_eutra) { + if (eutra_index != -1) { + LOG_E(RRC, "fatal: more than 1 eutra capability\n"); + exit(1); + } + eutra_index = i; + } + /* todo: improve nr dual connectivity capability checking */ + if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type == LTE_RAT_Type_eutra_nr) + ue_context_p->ue_context.does_nr = 1; + } + dec_rval = uper_decode(NULL, &asn_DEF_LTE_UE_EUTRA_Capability, (void **)&ue_context_p->ue_context.UE_Capability, - ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. - choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. - array[0]->ueCapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. - choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. - array[0]->ueCapabilityRAT_Container.size, 0, 0); - ue_context_p->ue_context.UE_Capability_size = ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. - choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. - array[0]->ueCapabilityRAT_Container.size; + ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.buf, + ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.size, + 0, 0); + ue_context_p->ue_context.UE_Capability_size = ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[eutra_index]->ueCapabilityRAT_Container.size; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); From f2d90e79e392d33c71bf42f5de4708268279beb4 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 17 Jan 2020 21:39:34 +0100 Subject: [PATCH 148/343] 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 149/343] 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 150/343] 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 151/343] 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 152/343] 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) From dff766ae15875c4ae8819e859579e34738e610a4 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jan 2020 10:34:41 +0100 Subject: [PATCH 153/343] =?UTF-8?q?=09*HOTFIX:=20After=20develop/develop-n?= =?UTF-8?q?r=20merge=20UE=20was=20crashing=20with=20MBMS=20U-Plane=20traff?= =?UTF-8?q?ic=20running=20=09-New=20MAC=20SDU=20integrity=20check=20in=20u?= =?UTF-8?q?e=5Fprocedures=20.c=20introduced=20for=20MCH=20channels.=20=09-?= =?UTF-8?q?This=20SDU=20behavior=20didn=E2=80=99t=20show=20up=20with=20for?= =?UTF-8?q?mer=20develop=20=09-TOCHECK=20whether=20NFAPI=20was=20properly?= =?UTF-8?q?=20merged=20on=20the=20eNB=20side.=20=09-eNB=5Fscheduler=5Fmch?= =?UTF-8?q?=20has=20been=20slightly=20rearranged.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *BUGFIX: -In dlsch_demodulation.c “ rxF_comp_d.m” was continuously being written to disk *New reference config file added (lte-fdd-mbms-basic-sim.conf) for rfsim environment --- .../conf_files/lte-fdd-mbms-basic-sim.conf | 418 ++++++++++++++++++ .../PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c | 8 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 181 +++++--- openair2/LAYER2/MAC/ue_procedures.c | 3 + 4 files changed, 552 insertions(+), 58 deletions(-) create mode 100644 ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf diff --git a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf new file mode 100644 index 0000000000..53261ec32d --- /dev/null +++ b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf @@ -0,0 +1,418 @@ +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 = 93; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + 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 = -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 = -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 */ + + ////////// 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 = "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 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +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 = 1; #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=5; #this must be properly defined lcid:6+service:0 -> rab_id:5 //with new RLC set lcid either 4 or 5 + } + ); + } + ); + + mbms_sf_config_list = ( + { + radioframe_allocation_period=0; #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 + + }; + } +); + + +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 = "ens3"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_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/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 412cd3fbef..2fd84f563c 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -547,10 +547,10 @@ int rx_pdsch(PHY_VARS_UE *ue, pdsch_vars[eNB_id]->log2_maxh, measurements); // log2_maxh+I0_shift - if (symbol == 5) { - LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - } - +// if (symbol == 5) { +// LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); +// } +// if ((rx_type==rx_IC_single_stream) && (eNB_id_in_connected_eNB)) { dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 2d308430a5..e351b69bb0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -48,11 +48,11 @@ #include "pdcp.h" #include "assertions.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif - -#include "SIMULATION/TOOLS/sim.h" // for taus +//#if defined(ENABLE_ITTI) +//#include "intertask_interface.h" +//#endif +// +#include "SIMULATION/TOOLS/sim.h" // for taus #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 @@ -60,37 +60,38 @@ extern RAN_CONTEXT_t RC; - -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; - } +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; + } } static uint32_t bytes_in_buffer=0; -static uint8_t msi_pmch_stop=0; +static uint32_t msi_pmch_stop=0; //static uint8_t msi_active=0; //static uint8_t msi_pmch_stop2=0; uint16_t mbms_rab_id = 2047; -static uint8_t msi_sfs=0; +static uint32_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) @@ -121,8 +122,9 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, int mcch_mcs = -1; uint16_t TBS, j = -1, padding = 0, post_padding = 0; mac_rlc_status_resp_t rlc_status; + //mac_rlc_status_resp_t rlc_status2; int num_mtch; - int msi_length, i, k; + int msi_length=0, 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; @@ -511,9 +513,11 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC // there is MSI (MCH Scheduling Info) + uint16_t msi_control_element[29], *msi_ptr; + char *buffer_pointer=NULL; if (msi_flag == 1) { // Create MSI here - uint16_t msi_control_element[29], *msi_ptr; + //uint16_t msi_control_element[29], *msi_ptr; msi_ptr = &msi_control_element[0]; //((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH @@ -543,9 +547,11 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, msi_pmch_stop = msi_sfs-1; else msi_pmch_stop = msi_sfs; + + 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 > 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 @@ -584,6 +590,8 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, memcpy((char *) &mch_buffer[sdu_length_total], msi_control_element, msi_length); + buffer_pointer = (char *) &mch_buffer[sdu_length_total]; + sdu_lcids[num_sdus] = MCH_SCHDL_INFO; sdu_lengths[num_sdus] = msi_length; sdu_length_total += sdu_lengths[num_sdus]; @@ -594,12 +602,26 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } // there is MCCH if (mcch_flag == 1) { + + //LOG_E(MAC, + //"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (mod %d)\n",module_idP, CC_id, frameP, subframeP,frameP%2==0); + if(1/*frameP%2==0*/){ 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], + 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 + } + else{ + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (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_COUNTING, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], +// i); // this is the mbsfn sync area index + } mcch_sdu_length+=1; //RLC ? @@ -629,6 +651,15 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sdu_lcids[num_sdus] = MCCH_LCHANID; sdu_lengths[num_sdus] = mcch_sdu_length; + // LOG_W(MAC,"MCCH RLC %x:",(unsigned char)mch_buffer[sdu_length_total]); + // for (int kk = 7; kk >= 0; kk--) + // { + // printf("%d",(((unsigned char)mch_buffer[sdu_length_total]) >> kk) & 1 ? '1' : '0'); + // } + // printf("\n"); + //mch_buffer[sdu_length_total] = (unsigned char)0; + + if (sdu_lengths[num_sdus] > 128) { header_len_mcch = 3; } @@ -641,6 +672,7 @@ schedule_MBMS_NFAPI(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)); // do not let mcch and mtch multiplexing when relaying is active @@ -686,7 +718,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9; rlc_status = - mac_rlc_status_ind(module_idP, 0, frameP, subframeP, + mac_rlc_status_ind(module_idP, 0/*0xfffd*/, frameP, subframeP, module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, //MTCH, @@ -697,36 +729,77 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, bytes_in_buffer = rlc_status.bytes_in_buffer; - msi_sfs = rlc_status.bytes_in_buffer/TBS+(rlc_status.bytes_in_buffer%TBS?1:0); + if( !(mcch_flag==1 || msi_flag==1) ) + msi_sfs = rlc_status.bytes_in_buffer/(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)+(rlc_status.bytes_in_buffer%(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)?1:0); + //uint16_t msi_control_element[29], *msi_ptr; + // + // + uint16_t TBS_MTCH = + get_TBS_DL(cc->pmch_Config[0]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth)); + if(msi_flag==1 && buffer_pointer!=NULL){ + msi_ptr = &msi_control_element[0]; + + //memcpy(buffer_pointer, + // msi_control_element, msi_length); + + // msi_pmch_stop = rlc_status.bytes_in_buffer/TBS+(rlc_status.bytes_in_buffer%TBS?1:0); + msi_pmch_stop = (rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0); + + if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9) + LOG_E(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; + } + LOG_I(MAC,"frameP %d, subframeP %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d\n",frameP,subframeP,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB); + //LOG_W(MAC,"frameP %d, subframeP %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d msi_calc:%d remainder %d\n",frameP,subframeP,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,rlc_status.bytes_in_buffer/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0),((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0)); + + memcpy(buffer_pointer, + msi_control_element, msi_length); + + } 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); + "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS_MTCH %d pmch_stop %d msi_sfs %d\n", + MTCH, frameP, subframeP, rlc_status.bytes_in_buffer,TBS_MTCH,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_flag!=1 || mcch_flag!=1)) /*|| (rlc_status.bytes_in_buffer > 0 && (msi_flag==1 || mcch_flag==1))*//*|| msi_sfs > cc->pmch_Config[0]->sf_AllocEnd_r9 */ /*msi_pmch_stop>=num_sf_alloc*/ ) { //if(rlc_status.bytes_in_buffer > 0){ - LOG_I(MAC, + LOG_D(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 + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0/*0xfffd*/, 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] ,0, 0 ); + + // LOG_I(MAC,"RLC %x:",(unsigned char)mch_buffer[sdu_length_total]); + // for (int kk = 7; kk >= 0; kk--) + // { + // printf("%d",(((unsigned char)mch_buffer[sdu_length_total]) >> kk) & 1 ? '1' : '0'); + // } + // printf("\n"); //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, + LOG_D(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) + if (msi_pmch_stop != 0 && msi_flag !=1) msi_pmch_stop--; @@ -833,14 +906,14 @@ schedule_MBMS_NFAPI(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 + //if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xfffd, // 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; @@ -1370,7 +1443,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, header_len_msi = 3; } - LOG_D(MAC, + LOG_W(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); @@ -1485,7 +1558,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9; rlc_status = - mac_rlc_status_ind(module_idP, 0, frameP, subframeP, + mac_rlc_status_ind(module_idP, 0/*0xfffd*/, frameP, subframeP, module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, //MTCH, @@ -1510,7 +1583,7 @@ 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, 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 + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0/*0xfffd*/, 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] ,0, @@ -1632,14 +1705,14 @@ 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) { + //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); - } + //} /* for (j=0;jMCH_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); } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index d4277917eb..1244125bb6 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -746,6 +746,9 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, LOG_D(MAC, "[UE %d] parse_mch_header, found %d sdus\n", module_idP, num_sdu); + if(sdu[0]==0 && sdu[1]==0) + num_sdu=0; + for (i = 0; i < num_sdu; i++) { if (rx_lcids[i] == MCH_SCHDL_INFO) { if (rx_lengths[i] & 0x01) { From a21c1b1f73aa315452b4aee6f144cc6ca2946125 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 10 Oct 2019 16:30:45 +0200 Subject: [PATCH 154/343] Remove unused sleep function() --- openair2/ENB_APP/flexran_agent_timer.c | 12 ------------ openair2/ENB_APP/flexran_agent_timer.h | 3 --- 2 files changed, 15 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index 143c2df889..621fe9f846 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -172,18 +172,6 @@ err_code_t flexran_agent_destroy_timers(void) { return 0; } -void flexran_agent_sleep_until(struct timespec *ts, int delay) { - ts->tv_nsec += delay; - - if(ts->tv_nsec >= 1000*1000*1000) { - ts->tv_nsec -= 1000*1000*1000; - ts->tv_sec++; - } - - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL); -} - - err_code_t flexran_agent_stop_timer(long timer_id) { struct flexran_agent_timer_element_s *e=NULL; struct flexran_agent_timer_element_s search; diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index 06443c14d1..d72490f38f 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -125,8 +125,5 @@ Protocol__FlexranMessage * flexran_agent_process_timeout(long timer_id, void* ti /* Comparator function comparing two timers. Decides the ordering of the timers */ int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b); -/*Specify a delay in nanoseconds to timespec and sleep until then*/ -void flexran_agent_sleep_until(struct timespec *ts, int delay); - /* RB_PROTOTYPE is for .h files */ RB_PROTOTYPE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); From 7415d08138a9e982faf0bf88291284026b4fe647 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 15 Oct 2019 10:05:57 +0200 Subject: [PATCH 155/343] FlexRAN: Simplify stats request handling * only set up timer for sending requests * simplify interface for timer setup * on timer expiry, do not pass through stats request function but directly send the reply * Remove whatever report structure and use stats request directly for inferring the data to send --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 47 +- .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 8 +- .../MAC/flexran_agent_mac_internal.h | 6 - .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 28 +- .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.h | 6 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 39 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.h | 10 +- openair2/ENB_APP/flexran_agent.c | 2 - openair2/ENB_APP/flexran_agent_common.h | 10 +- openair2/ENB_APP/flexran_agent_defs.h | 34 -- openair2/ENB_APP/flexran_agent_handler.c | 478 +++++------------- openair2/ENB_APP/flexran_agent_timer.c | 46 +- openair2/ENB_APP/flexran_agent_timer.h | 18 +- 13 files changed, 221 insertions(+), 511 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 51ec781de3..d64c1d3ea7 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -63,9 +63,12 @@ pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER; int flexran_agent_mac_stats_reply(mid_t mod_id, - const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, - Protocol__FlexCellStatsReport **cell_report) { + int n_ue, + uint32_t ue_flags, + Protocol__FlexCellStatsReport **cell_report, + int n_cc, + uint32_t cc_flags) { // Protocol__FlexHeader *header; @@ -75,18 +78,16 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, int enb_id = mod_id; /* Allocate memory for list of UE reports */ - if (report_config->nr_ue > 0) { + if (n_ue > 0) { - for (i = 0; i < report_config->nr_ue; i++) { + for (i = 0; i < n_ue; i++) { - UE_id = flexran_get_mac_ue_id(mod_id, i); - - ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; - ue_report[i]->has_rnti = 1; + const rnti_t rnti = ue_report[i]->rnti; + UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti); /* Check flag for creation of buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { //TODO should be automated ue_report[i]->n_bsr = 4; uint32_t *elem; @@ -103,7 +104,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Check flag for creation of PHR report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { ue_report[i]->phr = flexran_get_ue_phr (enb_id, UE_id); // eNB_UE_list->UE_template[UE_PCCID(enb_id,UE_id)][UE_id].phr_info; ue_report[i]->has_phr = 1; ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR; @@ -111,7 +112,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Check flag for creation of RLC buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs Protocol__FlexRlcBsr ** rlc_reports; rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); @@ -157,7 +158,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Check flag for creation of MAC CE buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { // TODO: Fill in the actual MAC CE buffer status report ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id, UE_id, 0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the @@ -169,7 +170,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Check flag for creation of DL CQI report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { // TODO: Fill in the actual DL CQI report for the UE based on its configuration Protocol__FlexDlCqiReport * dl_report; dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); @@ -420,7 +421,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Check flag for creation of paging buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI //set in the report must be a P-RNTI Protocol__FlexPagingBufferReport *paging_report; @@ -474,7 +475,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Check flag for creation of UL CQI report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { //Fill in the full UL CQI report of the UE Protocol__FlexUlCqiReport *full_ul_report; @@ -559,7 +560,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI; } - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { Protocol__FlexMacStats *macstats; macstats = malloc(sizeof(Protocol__FlexMacStats)); @@ -668,15 +669,15 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } /* Allocate memory for list of cell reports */ - if (report_config->nr_cc > 0) { + if (n_cc > 0) { // Fill in the Cell reports - for (i = 0; i < report_config->nr_cc; i++) { + for (i = 0; i < n_cc; i++) { /* Check flag for creation of noise and interference report */ - if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + if(cc_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { // TODO: Fill in the actual noise and interference report for this cell Protocol__FlexNoiseInterferenceReport *ni_report; ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); @@ -710,8 +711,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, error: if (cell_report != NULL) { - if (report_config->nr_cc > 0) { - for (i = 0; i < report_config->nr_cc; i++) { + if (n_cc > 0) { + for (i = 0; i < n_cc; i++) { if (cell_report[i]->noise_inter_report != NULL) { free(cell_report[i]->noise_inter_report); cell_report[i]->noise_inter_report = NULL; @@ -723,8 +724,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } if (ue_report != NULL) { - if (report_config->nr_ue > 0) { - for (i = 0; i < report_config->nr_ue; i++) { + if (n_ue > 0) { + for (i = 0; i < n_ue; i++) { if (ue_report[i]->bsr != NULL) { free(ue_report[i]->bsr); ue_report[i]->bsr = NULL; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 8ca855a6b3..68a572e2b2 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -52,7 +52,13 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg); /* Statistics reply protocol message constructor and destructor */ -int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_mac_stats_reply(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags, + Protocol__FlexCellStatsReport **cell_report, + int n_cc, + uint32_t cc_flags); int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* DL MAC scheduling decision protocol message constructor (empty command) and destructor */ diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 01fc51f6a6..957fe6065e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -61,12 +61,6 @@ err_code_t flexran_agent_init_cont_mac_stats_update(mid_t mod_id); err_code_t flexran_agent_destroy_cont_mac_stats_update(mid_t mod_id); -/*Enable/Disable the continuous stats update service for the MAC*/ -err_code_t flexran_agent_enable_cont_mac_stats_update(mid_t mod_id, xid_t xid, - stats_request_config_t *stats_req); - -err_code_t flexran_agent_disable_cont_mac_stats_update(mid_t mod_id); - Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_report, Protocol__FlexranMessage *old_report); diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index 293ebab7a8..67da5fa452 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -65,25 +65,17 @@ void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, int flexran_agent_pdcp_stats_reply(mid_t mod_id, - const report_config_t *report_config, - Protocol__FlexUeStatsReport **ue_report, - Protocol__FlexCellStatsReport **cell_report) { - - - // Protocol__FlexHeader *header; - int i; - // int cc_id = 0; - - - /* Allocate memory for list of UE reports */ - if (report_config->nr_ue > 0) { + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags) { + if (n_ue > 0) { - for (i = 0; i < report_config->nr_ue; i++) { - const rnti_t rnti = report_config->ue_report_type[i].ue_rnti; + for (int i = 0; i < n_ue; i++) { + const rnti_t rnti = ue_report[i]->rnti; const uint16_t uid = flexran_get_pdcp_uid_from_rnti(mod_id, rnti); /* Check flag for creation of buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) { Protocol__FlexPdcpStats *pdcp_aggr_stats; pdcp_aggr_stats = malloc(sizeof(Protocol__FlexPdcpStats)); @@ -129,12 +121,6 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, error: LOG_W(FLEXRAN_AGENT, "Can't allocate PDCP stats\n"); - - /* if (cell_report != NULL) - free(cell_report); - if (ue_report != NULL) - free(ue_report); - */ return -1; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h index 246f9709b5..11decf0298 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h @@ -48,9 +48,9 @@ /* Send to the controller all the pdcp stat updates that occured during this subframe*/ int flexran_agent_pdcp_stats_reply(mid_t mod_id, - const report_config_t *report_config, - Protocol__FlexUeStatsReport **ue_report, - Protocol__FlexCellStatsReport **cell_report); + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags); int flexran_agent_pdcp_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* Get the stats from RAN API and aggregate them per USER*/ diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 6299e101a4..92c9917622 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -380,18 +380,15 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t* measRes int flexran_agent_rrc_stats_reply(mid_t mod_id, - const report_config_t *report_config, - Protocol__FlexUeStatsReport **ue_report, - Protocol__FlexCellStatsReport **cell_report) { - - if (report_config->nr_ue > 0) { - rnti_t rntis[report_config->nr_ue]; - flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue); - for (int i = 0; i < report_config->nr_ue; i++) { - const rnti_t rnti = rntis[i]; + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags) { + if (n_ue > 0) { + for (int i = 0; i < n_ue; i++) { + const rnti_t rnti = ue_report[i]->rnti; /* Check flag for creation of buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { /*Source cell EUTRA Measurements*/ Protocol__FlexRrcMeasurements *rrc_measurements; @@ -531,7 +528,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, } return 0; error: - for (int i = 0; i < report_config->nr_ue; i++) { + for (int i = 0; i < n_ue; i++) { if (ue_report[i]->rrc_measurements && ue_report[i]->rrc_measurements->neigh_meas != NULL) { for (int j = 0; j < ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++) { free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); @@ -540,8 +537,6 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, } } - if (cell_report != NULL) - free(cell_report); if (ue_report != NULL) free(ue_report); return -1; @@ -575,20 +570,18 @@ int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply) } int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id, - const report_config_t *report_config, - Protocol__FlexUeStatsReport **ue_report, - Protocol__FlexCellStatsReport **cell_report) { + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags) { /* This function fills the GTP part of the statistics. The necessary * information is, for our purposes, completely maintained in the RRC layer. * It would be possible to add a GTP module that handles this, though. */ - if (report_config->nr_ue > 0) { - rnti_t rntis[report_config->nr_ue]; - flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue); - for (int i = 0; i < report_config->nr_ue; i++) { - const rnti_t rnti = rntis[i]; + if (n_ue > 0) { + for (int i = 0; i < n_ue; i++) { + const rnti_t rnti = ue_report[i]->rnti; /* Check flag for creation of buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS) { + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_GTP_STATS) { /* get number of rabs for this UE */ const int num_e_rab = flexran_agent_rrc_gtp_num_e_rab(mod_id, rnti); @@ -618,7 +611,7 @@ int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id, } return 0; error: - for (int i = 0; i < report_config->nr_ue; i++) { + for (int i = 0; i < n_ue; i++) { if (!ue_report[i]->gtp_stats) continue; for (int r = 0; r < ue_report[i]->n_gtp_stats; ++r) { if (ue_report[i]->gtp_stats[r]) { diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index fdf00ff841..1aa110a3e9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -57,12 +57,18 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *); /* Statistics reply protocol message constructor and destructor */ -int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_rrc_stats_reply(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags); int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* Statistic reply for GTP statistics which OAI stores also in the RRC layer. * This might be moved to a separate GTP module in the future */ -int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_rrc_gtp_stats_reply(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags); int flexran_agent_rrc_gtp_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* Fill the RRC part of a ue_config message */ diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index f73e808865..e6ecf4250d 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -202,8 +202,6 @@ int flexran_agent_start(mid_t mod_id) *flexran_agent_register_channel(mod_id, channel, FLEXRAN_AGENT_MAC); */ - /*Initialize the continuous stats update mechanism*/ - flexran_agent_init_cont_stats_update(mod_id); pthread_t t; threadCreate(&t, receive_thread, flexran, "flexran", -1, OAI_PRIORITY_RT); diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index f116eb6591..4887842fa6 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -153,21 +153,17 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, Protocol__FlexranMessage *flexran_agent_handle_timed_task(void *args); /*Top level Statistics hanlder*/ +Protocol__FlexranMessage *flexran_agent_send_stats_reply(void *args); int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); /* Function to be used to handle reply message . */ -int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); +int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const Protocol__FlexStatsRequest *stats_req, Protocol__FlexranMessage **msg); int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg); /* Top level Statistics request protocol message constructor and destructor */ -int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); +//int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); -err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id); - -err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; -err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id); - /* Handle a received eNB config reply message as an "order" to reconfigure. It * does not come as a reconfiguration message as this is a "structured" * ProtoBuf message (as opposed to "unstructured" YAML). There is no destructor diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 706688286d..1b6102590b 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -193,38 +193,4 @@ typedef struct { } agent_reconf_rrc; - -/* These structs will be used to give - instructions for the type of stats reports - we need to create */ - - -typedef struct { - uint16_t ue_rnti; - uint32_t ue_report_flags; /* Indicates the report elements - required for this UE id. See - FlexRAN specification 1.2.4.2 */ -} ue_report_type_t; - -typedef struct { - uint16_t cc_id; - uint32_t cc_report_flags; /* Indicates the report elements - required for this CC index. See - FlexRAN specification 1.2.4.3 */ -} cc_report_type_t; - -typedef struct { - int nr_ue; - ue_report_type_t *ue_report_type; - int nr_cc; - cc_report_type_t *cc_report_type; -} report_config_t; - -typedef struct stats_request_config_s{ - uint8_t report_type; - uint8_t report_frequency; - uint16_t period; /*In number of subframes*/ - report_config_t *config; -} stats_request_config_t; - #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index e089675b62..e7ce0f317b 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -196,335 +196,186 @@ err_code_t flexran_agent_destroy_flexran_message(Protocol__FlexranMessage *msg) /* Top Level Statistics Report +*/ - */ - - - -int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg){ - - // TODO: Must deal with sanitization of input - // TODO: Must check if RNTIs and cell ids of the request actually exist - // TODO: Must resolve conflicts among stats requests - - int i; - err_code_t err_code = 0; - xid_t xid; - uint32_t usec_interval, sec_interval; - - //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 - int enb_id = mod_id; - - //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - //UE_list_t *eNB_UE_list= &eNB->UE_list; - - report_config_t report_config; - - uint32_t ue_flags = 0; - uint32_t c_flags = 0; - +int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { + *msg = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; - Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; - xid = (stats_req->header)->xid; + const xid_t xid = stats_req->header->xid; - // Check the type of request that is made - switch(stats_req->body_case) { - case PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ; - Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; - if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF) { - /*Disable both periodic and continuous updates*/ - // flexran_agent_disable_cont_stats_update(mod_id); - flexran_agent_destroy_timer_by_task_id(xid); - *msg = NULL; - return 0; - } else { //One-off, periodical or continuous reporting - //Set the proper flags - ue_flags = comp_req->ue_report_flags; - c_flags = comp_req->cell_report_flags; - //Create a list of all eNB RNTIs and cells + if (stats_req->body_case != PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST) { + LOG_E(FLEXRAN_AGENT, "only complete stats are supported at the moment\n"); + return -1; + } + Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; + flexran_agent_timer_args_t *timer_args = NULL; - //Set the number of UEs and create list with their RNTIs stats configs - report_config.nr_ue = 0; - if (flexran_agent_get_rrc_xface(mod_id)) - report_config.nr_ue = flexran_get_rrc_num_ues(mod_id); - else if (flexran_agent_get_mac_xface(mod_id)) - report_config.nr_ue = flexran_get_mac_num_ues(mod_id); - - if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id) - && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) { - const int nrrc = flexran_get_rrc_num_ues(mod_id); - const int nmac = flexran_get_mac_num_ues(mod_id); - report_config.nr_ue = nrrc < nmac ? nrrc : nmac; - LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n", - __func__, nrrc, nmac, report_config.nr_ue); - } - report_config.ue_report_type = malloc(sizeof(ue_report_type_t) * report_config.nr_ue); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - if (flexran_agent_get_rrc_xface(mod_id)) { - rnti_t rntis[report_config.nr_ue]; - flexran_get_rrc_rnti_list(mod_id, rntis, report_config.nr_ue); - for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = rntis[i]; - report_config.ue_report_type[i].ue_report_flags = ue_flags; - } - } - if (flexran_agent_get_mac_xface(mod_id) && !flexran_agent_get_rrc_xface(mod_id)) { - for (i = 0; i < report_config.nr_ue; i++) { - const int UE_id = flexran_get_mac_ue_id(mod_id, i); - report_config.ue_report_type[i].ue_rnti = flexran_get_mac_ue_crnti(enb_id, UE_id); - report_config.ue_report_type[i].ue_report_flags = ue_flags; - } - } - //Set the number of CCs and create a list with the cell stats configs - report_config.nr_cc = MAX_NUM_CCs; - report_config.cc_report_type = malloc(sizeof(cc_report_type_t) * report_config.nr_cc); - if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = i; - report_config.cc_report_type[i].cc_report_flags = c_flags; - } - /* Check if request was periodical */ - if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) { - /* Create a one off flexran message as an argument for the periodical task */ - Protocol__FlexranMessage *timer_msg = NULL; - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - if (flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg) == -1) { - err_code = -100; - goto error; - } - /* Create a timer */ - long timer_id = 0; - flexran_agent_timer_args_t *timer_args = malloc(sizeof(flexran_agent_timer_args_t)); - memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); - timer_args->mod_id = enb_id; - timer_args->msg = timer_msg; - /*Convert subframes to usec time*/ - usec_interval = 1000*comp_req->sf; - sec_interval = 0; - /*add seconds if required*/ - if (usec_interval >= 1000*1000) { - sec_interval = usec_interval/(1000*1000); - usec_interval = usec_interval%(1000*1000); - } - flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, - enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, - flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); - } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { - /*If request was for continuous updates, disable the previous configuration and - set up a new one*/ - flexran_agent_disable_cont_stats_update(mod_id); - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config); - } - } - break; - case PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST:; - Protocol__FlexCellStatsRequest *cell_req = stats_req->cell_stats_request; - // UE report config will be blank - report_config.nr_ue = 0; - report_config.ue_report_type = NULL; - report_config.nr_cc = cell_req->n_cell; - report_config.cc_report_type = malloc(sizeof(cc_report_type_t) * report_config.nr_cc); - if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = cell_req->cell[i]; - report_config.cc_report_type[i].cc_report_flags = cell_req->flags; - } - break; - case PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST:; - Protocol__FlexUeStatsRequest *ue_req = stats_req->ue_stats_request; - // Cell report config will be blank - report_config.nr_cc = 0; - report_config.cc_report_type = NULL; - report_config.nr_ue = ue_req->n_rnti; - report_config.ue_report_type = malloc(sizeof(ue_report_type_t) * report_config.nr_ue); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_ue; i++) { - const int UE_id = flexran_get_mac_ue_id(mod_id, i); - report_config.ue_report_type[i].ue_rnti = ue_req->rnti[UE_id]; - report_config.ue_report_type[i].ue_report_flags = ue_req->flags; - } - break; + switch (comp_req->report_frequency) { + case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF: + flexran_agent_destroy_timer_by_task_id(xid); + return 0; + case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE: + LOG_E(FLEXRAN_AGENT, "one-shot timer not implemented yet\n"); + return -1; + case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL: + /* Create a one off flexran message as an argument for the periodical task */ + timer_args = calloc(1, sizeof(flexran_agent_timer_args_t)); + AssertFatal(timer_args, "cannot allocate memory for timer\n"); + timer_args->mod_id = mod_id; + timer_args->msg = input; + flexran_agent_create_timer(mod_id, comp_req->sf, + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, + flexran_agent_send_stats_reply, timer_args); + /* return 1: do not dispose comp_req message we received, we still need it */ + return 1; + case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS: + LOG_E(FLEXRAN_AGENT, "unsupported report frequency continuous\n"); + return -1; default: - //TODO: Add appropriate error code - err_code = -100; - goto error; + LOG_E(FLEXRAN_AGENT, "unknown report frequency\n"); + return -1; } - - if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } - - if (report_config.ue_report_type) - free(report_config.ue_report_type); - if (report_config.cc_report_type) - free(report_config.cc_report_type); - - return 0; - - error : - LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured\n", __func__, err_code); - return err_code; } /* Top level reply */ +Protocol__FlexranMessage *flexran_agent_send_stats_reply(void *args) { + const flexran_agent_timer_args_t *timer_args = args; + const mid_t enb_id = timer_args->mod_id; + const Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)timer_args->msg; + const Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; + const xid_t xid = stats_req->header->xid; -int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg){ + Protocol__FlexranMessage *reply = NULL; + err_code_t rc = flexran_agent_stats_reply(enb_id, xid, stats_req, &reply); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured, cannot send stats_reply\n", + __func__, rc); + return NULL; + } + return reply; +} + +int flexran_agent_stats_reply(mid_t enb_id, + xid_t xid, + const Protocol__FlexStatsRequest *stats_req, + Protocol__FlexranMessage **msg) { Protocol__FlexHeader *header = NULL; Protocol__FlexUeStatsReport **ue_report = NULL; Protocol__FlexCellStatsReport **cell_report = NULL; Protocol__FlexStatsReply *stats_reply_msg = NULL; err_code_t err_code = PROTOCOL__FLEXRAN_ERR__UNEXPECTED; - int i,j; + AssertFatal(stats_req->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST, + "%s() handles only complete stats requests\n", + __func__); + const uint32_t cell_flags = stats_req->complete_stats_request->cell_report_flags; + const uint32_t ue_flags = stats_req->complete_stats_request->ue_report_flags; - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) { - goto error; + /* TODO: get_number in own function */ + int n_ue = 0; + if (flexran_agent_get_rrc_xface(enb_id)) + n_ue = flexran_get_rrc_num_ues(enb_id); + else if (flexran_agent_get_mac_xface(enb_id)) + n_ue = flexran_get_mac_num_ues(enb_id); + + if (flexran_agent_get_rrc_xface(enb_id) && flexran_agent_get_mac_xface(enb_id) + && flexran_get_rrc_num_ues(enb_id) != flexran_get_mac_num_ues(enb_id)) { + const int nrrc = flexran_get_rrc_num_ues(enb_id); + const int nmac = flexran_get_mac_num_ues(enb_id); + n_ue = nrrc < nmac ? nrrc : nmac; + LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n", + __func__, nrrc, nmac, n_ue); } - stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); - - if (stats_reply_msg == NULL) { - goto error; + rnti_t rntis[n_ue]; + if (flexran_agent_get_rrc_xface(enb_id)) + flexran_get_rrc_rnti_list(enb_id, rntis, n_ue); + if (flexran_agent_get_mac_xface(enb_id) && !flexran_agent_get_rrc_xface(enb_id)) { + for (int i = 0; i < n_ue; i++) { + const int UE_id = flexran_get_mac_ue_id(enb_id, i); + rntis[i] = flexran_get_mac_ue_crnti(enb_id, UE_id); + } } - protocol__flex_stats_reply__init(stats_reply_msg); - stats_reply_msg->header = header; - - stats_reply_msg->n_ue_report = report_config->nr_ue; - stats_reply_msg->n_cell_report = report_config->nr_cc; - - // UE report - - ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue); + int n_cc = MAX_NUM_CCs; + ue_report = calloc(n_ue, sizeof(Protocol__FlexUeStatsReport *)); if (ue_report == NULL) { goto error; } - - for (i = 0; i < report_config->nr_ue; i++) { - - ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); - if (ue_report[i] == NULL) { - goto error; - } - protocol__flex_ue_stats_report__init(ue_report[i]); - ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; - ue_report[i]->has_rnti = 1; - ue_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */ - + for (int i = 0; i < n_ue; i++) { + ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); + if (ue_report[i] == NULL) { + goto error; + } + protocol__flex_ue_stats_report__init(ue_report[i]); + ue_report[i]->rnti = rntis[i]; + ue_report[i]->has_rnti = 1; + ue_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */ } - // cell rpoert - - cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc); + cell_report = calloc(n_cc, sizeof(Protocol__FlexCellStatsReport *)); if (cell_report == NULL) { goto error; } - - for (i = 0; i < report_config->nr_cc; i++) { - - cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); - if(cell_report[i] == NULL) { - goto error; - } - - protocol__flex_cell_stats_report__init(cell_report[i]); - cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id; - cell_report[i]->has_carrier_index = 1; - cell_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */ - + for (int i = 0; i < n_cc; i++) { + cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); + if(cell_report[i] == NULL) { + goto error; + } + protocol__flex_cell_stats_report__init(cell_report[i]); + cell_report[i]->carrier_index = i; + cell_report[i]->has_carrier_index = 1; + cell_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */ } /* MAC reply split */ if (flexran_agent_get_mac_xface(enb_id) - && flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + && flexran_agent_mac_stats_reply(enb_id, + ue_report, n_ue, ue_flags, + cell_report, n_cc, cell_flags) < 0) { err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; goto error; } /* RRC reply split */ if (flexran_agent_get_rrc_xface(enb_id) - && flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + && flexran_agent_rrc_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) { err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; goto error; } /* PDCP reply split */ if (flexran_agent_get_pdcp_xface(enb_id) - && flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + && flexran_agent_pdcp_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) { err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; goto error; } /* GTP reply split, currently performed through RRC module */ if (flexran_agent_get_rrc_xface(enb_id) - && flexran_agent_rrc_gtp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + && flexran_agent_rrc_gtp_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) { err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; goto error; } - stats_reply_msg->cell_report = cell_report; - stats_reply_msg->ue_report = ue_report; - - *msg = malloc(sizeof(Protocol__FlexranMessage)); - if(*msg == NULL) { + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) { goto error; } + stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); + AssertFatal(stats_reply_msg, "no memory for stats_reply_msg\n"); + protocol__flex_stats_reply__init(stats_reply_msg); + stats_reply_msg->header = header; + stats_reply_msg->n_ue_report = n_ue; + stats_reply_msg->ue_report = ue_report; + stats_reply_msg->n_cell_report = n_cc; + stats_reply_msg->cell_report = cell_report; + + *msg = malloc(sizeof(Protocol__FlexranMessage)); + AssertFatal(*msg, "no memory for stats_reply container msg\n"); protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; @@ -546,7 +397,7 @@ error : } if (ue_report != NULL) { - for (j = 0; j < report_config->nr_ue; j++) { + for (int j = 0; j < n_ue; j++) { if (ue_report[j] != NULL) { free(ue_report[j]); } @@ -556,7 +407,7 @@ error : } if (cell_report != NULL) { - for (j = 0; j < report_config->nr_cc; j++) { + for (int j = 0; j < n_cc; j++) { if (cell_report[j] != NULL) { free(cell_report[j]); } @@ -572,6 +423,7 @@ error : Top Level Request */ +/* int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, @@ -678,6 +530,7 @@ int flexran_agent_stats_request(mid_t mod_id, //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } +*/ int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG) @@ -719,88 +572,3 @@ int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg) free(msg); return 0; } - -err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id) { - /*Disable the continuous updates for the MAC*/ - if (pthread_mutex_lock(stats_context[mod_id].mutex)) { - goto error; - } - stats_context[mod_id].cont_update = 0; - stats_context[mod_id].xid = 0; - if (stats_context[mod_id].stats_req != NULL) { - flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req); - } - if (stats_context[mod_id].prev_stats_reply != NULL) { - flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); - } - if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { - goto error; - } - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id); - return -1; - -} - -err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, - xid_t xid, stats_request_config_t *stats_req) { - - if (pthread_mutex_lock(stats_context[mod_id].mutex)) { - goto error; - } - - Protocol__FlexranMessage *req_msg = NULL; - - flexran_agent_stats_request(mod_id, xid, stats_req, &req_msg); - - if (req_msg != NULL) { - stats_context[mod_id].stats_req = req_msg; - stats_context[mod_id].prev_stats_reply = NULL; - - stats_context[mod_id].cont_update = 1; - stats_context[mod_id].xid = xid; - } - - if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { - goto error; - } - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id); - return -1; -} - - -err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) { - - - /*Initially the continuous update is set to false*/ - stats_context[mod_id].cont_update = 0; - stats_context[mod_id].is_initialized = 1; - stats_context[mod_id].stats_req = NULL; - stats_context[mod_id].prev_stats_reply = NULL; - stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t)); - if (stats_context[mod_id].mutex == NULL) - goto error; - if (pthread_mutex_init(stats_context[mod_id].mutex, NULL) != 0) - goto error; - - return 0; - - error: - return -1; -} - -err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) { - - stats_context[mod_id].cont_update = 0; - stats_context[mod_id].is_initialized = 0; - flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req); - flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); - free(stats_context[mod_id].mutex); - - return 1; -} diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index 621fe9f846..e4ce1b82d4 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -58,48 +58,48 @@ int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct return 0; } -err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, +err_code_t flexran_agent_create_timer(mid_t mod_id, + uint32_t sf, uint32_t timer_type, - xid_t xid, + xid_t xid, flexran_agent_timer_callback_t cb, - void *timer_args, - long *timer_id) { - struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); - DevAssert(e != NULL); - //uint32_t timer_id; + void *timer_args) { int ret=-1; - if ((interval_sec == 0) && (interval_usec == 0 )) { - free(e); + if (sf <= 0) return TIMER_NULL; - } - if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) { - free(e); + if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) return TIMER_TYPE_INVALIDE; - } + uint32_t interval_usec = sf * 1000; + uint32_t interval_sec = 0; + if (interval_usec >= 1000 * 1000) { + interval_sec = interval_usec / (1000 * 1000); + interval_usec = interval_usec % (1000 * 1000); + } + struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); + DevAssert(e != NULL); + long timer_id = 0; + AssertFatal(e, "cannot allocate memory for FlexRAN timer!\n"); if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT) { ret = timer_setup(interval_sec, interval_usec, TASK_FLEXRAN_AGENT, - instance, + mod_id, TIMER_ONE_SHOT, timer_args, - timer_id); + &timer_id); e->type = TIMER_ONE_SHOT; } else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ) { ret = timer_setup(interval_sec, interval_usec, TASK_FLEXRAN_AGENT, - instance, + mod_id, TIMER_PERIODIC, timer_args, - timer_id); + &timer_id); e->type = TIMER_PERIODIC; } @@ -108,10 +108,10 @@ err_code_t flexran_agent_create_timer(uint32_t interval_sec, return TIMER_SETUP_FAILED; } - e->agent_id = agent_id; - e->instance = instance; + e->agent_id = mod_id; + e->instance = mod_id; e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; - e->timer_id = *timer_id; + e->timer_id = timer_id; e->xid = xid; e->timer_args = timer_args; e->cb = cb; diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index d72490f38f..4fbf44a7e2 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -89,17 +89,13 @@ typedef struct flexran_agent_timer_instance_s{ err_code_t flexran_agent_init_timer(void); -/* Create a timer for some agent related event with id xid. Will store the id - of the generated timer in timer_id */ -err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - flexran_agent_timer_callback_t cb, - void* timer_args, - long *timer_id); +/* Create a timer for some agent related event with id xid. */ +err_code_t flexran_agent_create_timer(mid_t mod_id, + uint32_t sf, + uint32_t timer_type, + xid_t xid, + flexran_agent_timer_callback_t cb, + void *timer_args); /* Destroy all existing timers */ err_code_t flexran_agent_destroy_timers(void); From 5c4aa309ebe2c75c02209d3caa499eeadba43c89 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 17 Oct 2019 17:30:23 +0200 Subject: [PATCH 156/343] FlexRAN: helper function to get No. UEs --- openair2/ENB_APP/flexran_agent_common.c | 37 ++++++++++++++---------- openair2/ENB_APP/flexran_agent_common.h | 4 +++ openair2/ENB_APP/flexran_agent_handler.c | 16 +--------- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index ac18f16069..552c58555b 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -598,21 +598,7 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl goto error; ue_config_reply_msg->header = header; - ue_config_reply_msg->n_ue_config = 0; - - if (flexran_agent_get_rrc_xface(mod_id)) - ue_config_reply_msg->n_ue_config = flexran_get_rrc_num_ues(mod_id); - else if (flexran_agent_get_mac_xface(mod_id)) - ue_config_reply_msg->n_ue_config = flexran_get_mac_num_ues(mod_id); - - if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id) - && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) { - const int nrrc = flexran_get_rrc_num_ues(mod_id); - const int nmac = flexran_get_mac_num_ues(mod_id); - ue_config_reply_msg->n_ue_config = nrrc < nmac ? nrrc : nmac; - LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %lu UEs\n", - __func__, nrrc, nmac, ue_config_reply_msg->n_ue_config); - } + ue_config_reply_msg->n_ue_config = flexran_agent_get_num_ues(mod_id); Protocol__FlexUeConfig **ue_config; @@ -935,3 +921,24 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto *msg = NULL; return 0; } + +int flexran_agent_get_num_ues(mid_t mod_id) { + const int has_rrc = flexran_agent_get_rrc_xface(mod_id) != NULL; + const int has_mac = flexran_agent_get_mac_xface(mod_id) != NULL; + DevAssert(has_rrc || has_mac); + if (has_rrc && !has_mac) + return flexran_get_rrc_num_ues(mod_id); + if (!has_rrc && has_mac) + return flexran_get_mac_num_ues(mod_id); + + /* has both */ + const int nrrc = flexran_get_rrc_num_ues(mod_id); + const int nmac = flexran_get_mac_num_ues(mod_id); + if (nrrc != nmac) { + const int n_ue = nrrc < nmac ? nrrc : nmac; + LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n", + __func__, nrrc, nmac, n_ue); + return n_ue; + } + return nrrc; +} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 4887842fa6..fcca7d4212 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -179,4 +179,8 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void* params, Prot * request message. */ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg); +/* Return the number of UEs in the BS of this agent across RRC/MAC. If they + * disagree, prints an error and returns the minimum of both. */ +int flexran_agent_get_num_ues(mid_t mod_id); + #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index e7ce0f317b..c3e9286441 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -274,21 +274,7 @@ int flexran_agent_stats_reply(mid_t enb_id, const uint32_t cell_flags = stats_req->complete_stats_request->cell_report_flags; const uint32_t ue_flags = stats_req->complete_stats_request->ue_report_flags; - /* TODO: get_number in own function */ - int n_ue = 0; - if (flexran_agent_get_rrc_xface(enb_id)) - n_ue = flexran_get_rrc_num_ues(enb_id); - else if (flexran_agent_get_mac_xface(enb_id)) - n_ue = flexran_get_mac_num_ues(enb_id); - - if (flexran_agent_get_rrc_xface(enb_id) && flexran_agent_get_mac_xface(enb_id) - && flexran_get_rrc_num_ues(enb_id) != flexran_get_mac_num_ues(enb_id)) { - const int nrrc = flexran_get_rrc_num_ues(enb_id); - const int nmac = flexran_get_mac_num_ues(enb_id); - n_ue = nrrc < nmac ? nrrc : nmac; - LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n", - __func__, nrrc, nmac, n_ue); - } + int n_ue = flexran_agent_get_num_ues(enb_id); rnti_t rntis[n_ue]; if (flexran_agent_get_rrc_xface(enb_id)) From 233affc9dd32d43f437d770b65a3b264bcaba652 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 17 Oct 2019 17:30:52 +0200 Subject: [PATCH 157/343] FlexRAN: include header, not C file --- openair2/ENB_APP/flexran_agent_task_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_task_manager.c b/openair2/ENB_APP/flexran_agent_task_manager.c index 4a0fee1f5b..f20e6c8969 100644 --- a/openair2/ENB_APP/flexran_agent_task_manager.c +++ b/openair2/ENB_APP/flexran_agent_task_manager.c @@ -33,7 +33,7 @@ #include #include "flexran_agent_task_manager.h" -#include "flexran_agent_common.c" +#include "flexran_agent_common.h" /* Util macros */ From b6d466d772d21eb87472b2ea99741a5e48471eb4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 21 Oct 2019 11:57:33 +0200 Subject: [PATCH 158/343] FlexRAN: reimplement timers without ITTI The timer code used to trigger periodic statistics message sending used ITTI. Together with a high frequency reporting (e.g. 1ms), this resulted in high CPU usage. This commit reimplements this: * using a thread that is synchronized to the RU (if there is no MAC, we assume there is no RU generating a tick so we create the tick source ourselves) * no RB trees but plain arrays * smaller interface for users * slight user interface changes * remove stopped timer state: such timer might be simply removed * remove one-shot timers --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 6 +- .../MAC/flexran_agent_mac_defs.h | 7 +- openair2/ENB_APP/flexran_agent.c | 50 +-- openair2/ENB_APP/flexran_agent_common.h | 9 +- openair2/ENB_APP/flexran_agent_defs.h | 30 -- openair2/ENB_APP/flexran_agent_handler.c | 59 +-- openair2/ENB_APP/flexran_agent_timer.c | 367 +++++++++++------- openair2/ENB_APP/flexran_agent_timer.h | 89 +---- openair2/LAYER2/MAC/eNB_scheduler.c | 2 + 9 files changed, 281 insertions(+), 338 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index d64c1d3ea7..04563b960e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1562,11 +1562,10 @@ int flexran_agent_register_mac_xface(mid_t mod_id) return -1; } - //xface->agent_ctxt = &shared_ctxt[mod_id]; xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; - //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; + xface->flexran_agent_notify_tick = flexran_agent_timer_signal; xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; @@ -1689,11 +1688,10 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) return -1; } AGENT_MAC_xface *xface = agent_mac_xface[mod_id]; - //xface->agent_ctxt = NULL; xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; - //xface->flexran_agent_send_update_mac_stats = NULL; xface->flexran_agent_get_pending_dl_mac_config = NULL; + xface->flexran_agent_notify_tick = NULL; xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 5c1fc1379c..dfde583387 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -54,10 +54,9 @@ typedef struct { void (*flexran_agent_get_pending_dl_mac_config)(mid_t mod_id, Protocol__FlexranMessage **msg); - /// Notify the controller for a state change of a particular UE, by sending the proper - /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) - // int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, - // uint8_t state_change); + /// Notify the controller of another (RU) tick, i.e. new subframe. Used to + /// synchronize the eNB and the agent. + void (*flexran_agent_notify_tick)(mid_t mod_id); void *dl_scheduler_loaded_lib; diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index e6ecf4250d..a8ee9b98e8 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -33,27 +33,14 @@ #include #include -void *receive_thread(void *args); -Protocol__FlexranMessage *flexran_agent_timeout(void* args); - - int agent_task_created = 0; /* * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller * and can interact with other itti tasks */ void *flexran_agent_task(void *args){ - - //flexran_agent_info_t *d = (flexran_agent_info_t *) args; - Protocol__FlexranMessage *msg; - void *data; - int size; - err_code_t err_code=0; - int priority = 0; - - MessageDef *msg_p = NULL; - int result; - struct flexran_agent_timer_element_s * elem = NULL; + MessageDef *msg_p = NULL; + int result; itti_mark_task_ready(TASK_FLEXRAN_AGENT); @@ -71,20 +58,6 @@ void *flexran_agent_task(void *args){ case MESSAGE_TEST: LOG_I(FLEXRAN_AGENT, "Received %s\n", ITTI_MSG_NAME(msg_p)); break; - - case TIMER_HAS_EXPIRED: - msg = flexran_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, msg_p->ittiMsg.timer_has_expired.arg); - if (msg != NULL){ - data=flexran_agent_pack_message(msg,&size); - elem = get_timer_entry(msg_p->ittiMsg.timer_has_expired.timer_id); - if (flexran_agent_msg_send(elem->agent_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; - goto error; - } - - LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); - } - break; default: LOG_E(FLEXRAN_AGENT, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); @@ -93,10 +66,6 @@ void *flexran_agent_task(void *args){ result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - continue; - error: - if (err_code != 0) - LOG_E(FLEXRAN_AGENT,"flexran_agent_task: error %d occured\n",err_code); } while (1); return NULL; @@ -245,7 +214,7 @@ int flexran_agent_start(mid_t mod_id) * initilize a timer */ - flexran_agent_init_timer(); + flexran_agent_timer_init(mod_id); /* * start the enb agent task for tx and interaction with the underlying network function @@ -286,16 +255,3 @@ error: return 1; } - -Protocol__FlexranMessage *flexran_agent_timeout(void* args){ - - // flexran_agent_timer_args_t *timer_args = calloc(1, sizeof(*timer_args)); - //memcpy (timer_args, args, sizeof(*timer_args)); - flexran_agent_timer_args_t *timer_args = (flexran_agent_timer_args_t *) args; - - LOG_UI(FLEXRAN_AGENT, "flexran_agent %d timeout\n", timer_args->mod_id); - //LOG_I(FLEXRAN_AGENT, "eNB action %d ENB flags %d \n", timer_args->cc_actions,timer_args->cc_report_flags); - //LOG_I(FLEXRAN_AGENT, "UE action %d UE flags %d \n", timer_args->ue_actions,timer_args->ue_report_flags); - - return NULL; -} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index fcca7d4212..fe7b49107c 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -150,10 +150,15 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, uint32_t size); /* Function to be used to send a message to a dispatcher once the appropriate event is triggered. */ -Protocol__FlexranMessage *flexran_agent_handle_timed_task(void *args); +Protocol__FlexranMessage *flexran_agent_handle_timed_task( + mid_t mod_id, + Protocol__FlexranMessage *msg); /*Top level Statistics hanlder*/ -Protocol__FlexranMessage *flexran_agent_send_stats_reply(void *args); +Protocol__FlexranMessage *flexran_agent_send_stats_reply( + mid_t mod_id, + const Protocol__FlexranMessage *msg); + int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); /* Function to be used to handle reply message . */ diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 1b6102590b..20aac5f56e 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -107,36 +107,6 @@ typedef uint8_t lcid_t; typedef int32_t err_code_t; -/*---------Timer Enums --------- */ - -typedef enum { - /* oneshot timer: */ - FLEXRAN_AGENT_TIMER_TYPE_ONESHOT = 0, - - /* periodic timer */ - FLEXRAN_AGENT_TIMER_TYPE_PERIODIC = 1, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_TYPE_EVENT_DRIVEN = 2, - - /* Max number of states available */ - FLEXRAN_AGENT_TIMER_TYPE_MAX, -} flexran_agent_timer_type_t; - - -typedef enum { - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_INACTIVE = 0x0, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_ACTIVE = 0x1, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_STOPPED = 0x2, - - /* Max number of states available */ - FLEXRAN_AGENT_TIMER_STATE_MAX, -} flexran_agent_timer_state_t; #define FLEXRAN_CAP_LOPHY(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)) > 0) #define FLEXRAN_CAP_HIPHY(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)) > 0) diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index c3e9286441..1bae0776a3 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -154,39 +154,20 @@ void * flexran_agent_pack_message(Protocol__FlexranMessage *msg, return NULL; } -Protocol__FlexranMessage *flexran_agent_handle_timed_task(void *args) { +Protocol__FlexranMessage *flexran_agent_handle_timed_task( + mid_t mod_id, + Protocol__FlexranMessage *msg) { err_code_t err_code; - flexran_agent_timer_args_t *timer_args = (flexran_agent_timer_args_t *) args; - Protocol__FlexranMessage *timed_task, *reply_message; - timed_task = timer_args->msg; - err_code = ((*agent_messages_callback[timed_task->msg_case-1][timed_task->msg_dir-1])(timer_args->mod_id, (void *) timed_task, &reply_message)); - if ( err_code < 0 ){ - goto error; + Protocol__FlexranMessage *reply_message; + err_code = ((*agent_messages_callback[msg->msg_case-1][msg->msg_dir-1])( + mod_id, msg, &reply_message)); + if (err_code < 0) { + LOG_E(FLEXRAN_AGENT, "could not handle message: errno %d occured\n", err_code); + return NULL; } return reply_message; - - error: - LOG_E(FLEXRAN_AGENT,"errno %d occured\n",err_code); - return NULL; -} - -Protocol__FlexranMessage* flexran_agent_process_timeout(long timer_id, void* timer_args){ - - struct flexran_agent_timer_element_s *found = get_timer_entry(timer_id); - - if (found == NULL ) goto error; - LOG_D(FLEXRAN_AGENT, "Found the entry (%p): timer_id is 0x%lx 0x%lx\n", found, timer_id, found->timer_id); - - if (timer_args == NULL) - LOG_W(FLEXRAN_AGENT,"null timer args\n"); - - return found->cb(timer_args); - - error: - LOG_E(FLEXRAN_AGENT, "can't get the timer element\n"); - return NULL; } err_code_t flexran_agent_destroy_flexran_message(Protocol__FlexranMessage *msg) { @@ -209,24 +190,21 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr return -1; } Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; - flexran_agent_timer_args_t *timer_args = NULL; switch (comp_req->report_frequency) { case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF: - flexran_agent_destroy_timer_by_task_id(xid); + flexran_agent_destroy_timer(mod_id, xid); return 0; case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE: LOG_E(FLEXRAN_AGENT, "one-shot timer not implemented yet\n"); return -1; case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL: /* Create a one off flexran message as an argument for the periodical task */ - timer_args = calloc(1, sizeof(flexran_agent_timer_args_t)); - AssertFatal(timer_args, "cannot allocate memory for timer\n"); - timer_args->mod_id = mod_id; - timer_args->msg = input; + LOG_I(FLEXRAN_AGENT, "periodical timer xid %d cell_flags %d ue_flags %d\n", + xid, comp_req->cell_report_flags, comp_req->ue_report_flags); flexran_agent_create_timer(mod_id, comp_req->sf, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, - flexran_agent_send_stats_reply, timer_args); + flexran_agent_send_stats_reply, input); /* return 1: do not dispose comp_req message we received, we still need it */ return 1; case PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS: @@ -241,15 +219,14 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr /* Top level reply */ -Protocol__FlexranMessage *flexran_agent_send_stats_reply(void *args) { - const flexran_agent_timer_args_t *timer_args = args; - const mid_t enb_id = timer_args->mod_id; - const Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)timer_args->msg; - const Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; +Protocol__FlexranMessage *flexran_agent_send_stats_reply( + mid_t mod_id, + const Protocol__FlexranMessage *msg) { + const Protocol__FlexStatsRequest *stats_req = msg->stats_request_msg; const xid_t xid = stats_req->header->xid; Protocol__FlexranMessage *reply = NULL; - err_code_t rc = flexran_agent_stats_reply(enb_id, xid, stats_req, &reply); + err_code_t rc = flexran_agent_stats_reply(mod_id, xid, stats_req, &reply); if (rc < 0) { LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured, cannot send stats_reply\n", __func__, rc); diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index e4ce1b82d4..ffbac39983 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -21,175 +21,266 @@ /*! \file flexran_agent_timer.c * \brief FlexRAN Timer - * \author shahab SHARIAT BAGHERI - * \date 2017 - * \version 0.1 - */ - -/* - * timer primitives + * \author Robert Schmidt + * \date 2019 + * \version 0.2 */ #include "flexran_agent_timer.h" +#include "flexran_agent_extern.h" +#include +#include -//struct flexran_agent_map agent_map; -flexran_agent_timer_instance_t timer_instance; -int agent_timer_init = 0; -err_code_t flexran_agent_init_timer(void) { - LOG_I(FLEXRAN_AGENT, "init RB tree\n"); +#define MAX_NUM_TIMERS 10 - if (!agent_timer_init) { - RB_INIT(&timer_instance.flexran_agent_head); - agent_timer_init = 1; +typedef struct flexran_agent_timer_element_s { + mid_t mod_id; + xid_t xid; /* The id of the task as received by the controller message*/ + uint32_t sf; + uint64_t next; + flexran_agent_timer_callback_t cb; + Protocol__FlexranMessage *msg; +} flexran_agent_timer_element_t; + +typedef struct flexran_agent_timer_extern_source_s { + pthread_mutex_t mutex_sync; + pthread_cond_t cond; + int wait; +} flexran_agent_timer_extern_source_t; + +struct timesync { + void *param_sync; + void (*fsync)(void *); + pthread_t thread; + + uint64_t current; + uint64_t next; + + int timer_num; + flexran_agent_timer_element_t *timer[MAX_NUM_TIMERS]; + pthread_mutex_t mutex_timer; + + int exit; +}; +struct timesync timesync[NUM_MAX_ENB]; + +int flexran_agent_timer_signal_init(struct timesync *sync); +int flexran_agent_timer_source_setup(struct timesync *sync); +void *flexran_agent_timer_thread(void *args); +void flexran_agent_timer_remove_internal(struct timesync *sync, int index); +void flexran_agent_timer_process(flexran_agent_timer_element_t *t); + + +err_code_t flexran_agent_timer_init(mid_t mod_id) { + struct timesync *sync = ×ync[mod_id]; + sync->current = 0; + sync->next = 0; + sync->timer_num = 0; + for (int i = 0; i < MAX_NUM_TIMERS; ++i) + sync->timer[i] = NULL; + pthread_mutex_init(&sync->mutex_timer, NULL); + sync->exit = 0; + + /* if there is a MAC, we assume we can have a tick from the MAC interface + * (external tick source). Otherwise, generate a tick internally via the + * timerfd linux library. The init functions set everything up and the thread + * will use whatever is available. */ + int (*init)(struct timesync *) = flexran_agent_get_mac_xface(mod_id) ? + flexran_agent_timer_signal_init : flexran_agent_timer_source_setup; + if (init(timesync) < 0 + || pthread_create(&sync->thread, NULL, flexran_agent_timer_thread, sync) != 0) { + sync->thread = 0; + if (sync->param_sync) + free(sync->param_sync); + LOG_E(FLEXRAN_AGENT, "could not start timer thread\n"); + return TIMER_SETUP_FAILED; } - return PROTOCOL__FLEXRAN_ERR__NO_ERR; } -RB_GENERATE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); +void flexran_agent_timer_exit(mid_t mod_id) { + timesync[mod_id].exit = 1; +} -/* The timer_id might not be the best choice for the comparison */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b) { - if (a->timer_id < b->timer_id) return -1; +void flexran_agent_timer_source_sync(void *sync) { + int fd = *(int *)sync; + uint64_t occ; + int rc __attribute__((unused)) = read(fd, &occ, sizeof(occ)); +} - if (a->timer_id > b->timer_id) return 1; +int flexran_agent_timer_source_setup(struct timesync *sync) { + sync->param_sync = malloc(sizeof(int)); + if (!sync->param_sync) + return -1; + int fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd < 0) + return fd; - // equal timers + const uint64_t period_ns = 1000000; // 1ms + struct itimerspec t; + t.it_interval.tv_sec = period_ns / 1000000000; + t.it_interval.tv_nsec = period_ns % 1000000000; + t.it_value.tv_sec = period_ns / 1000000000; + t.it_value.tv_nsec = period_ns % 1000000000; + int rc = timerfd_settime(fd, 0, &t, NULL); + if (rc != 0) + return -1; + *(int *)sync->param_sync = fd; + sync->fsync = flexran_agent_timer_source_sync; return 0; } +void flexran_agent_timer_signal_sync(void *param_sync) { + flexran_agent_timer_extern_source_t *sync = param_sync; + pthread_mutex_lock(&sync->mutex_sync); + while (sync->wait) { + pthread_cond_wait(&sync->cond, &sync->mutex_sync); + } + sync->wait = 1; + pthread_mutex_unlock(&sync->mutex_sync); +} + +int flexran_agent_timer_signal_init(struct timesync *sync) { + flexran_agent_timer_extern_source_t *s = malloc(sizeof(flexran_agent_timer_extern_source_t)); + if (!s) + return TIMER_SETUP_FAILED; + if (pthread_mutex_init(&s->mutex_sync, NULL) < 0) + return TIMER_SETUP_FAILED; + if (pthread_cond_init(&s->cond, NULL) < 0) + return TIMER_SETUP_FAILED; + s->wait = 1; + sync->param_sync = s; + sync->fsync = flexran_agent_timer_signal_sync; + return 0; +} + +void flexran_agent_timer_signal(mid_t mod_id) { + flexran_agent_timer_extern_source_t *sync = timesync[mod_id].param_sync; + pthread_mutex_lock(&sync->mutex_sync); + sync->wait = 0; + pthread_mutex_unlock(&sync->mutex_sync); + pthread_cond_signal(&sync->cond); +} + +void *flexran_agent_timer_thread(void *args) { + struct timesync *sync = args; + while (1) { + sync->fsync(sync->param_sync); + if (sync->exit) + break; + + pthread_mutex_lock(&sync->mutex_timer); + sync->current++; + + if (sync->current < sync->next) { + pthread_mutex_unlock(&sync->mutex_timer); + continue; + } + + for (int i = 0; i < sync->timer_num; ++i) { + flexran_agent_timer_element_t *t = sync->timer[i]; + if (sync->current == t->next) { + flexran_agent_timer_process(t); + t->next += t->sf; + } + if (sync->next == sync->current || t->next < sync->next) + sync->next = t->next; + } + pthread_mutex_unlock(&sync->mutex_timer); + } + LOG_W(FLEXRAN_AGENT, "terminated timer thread\n"); + return NULL; +} + +void flexran_agent_timer_process(flexran_agent_timer_element_t *t) { + Protocol__FlexranMessage *msg = t->cb(t->mod_id, t->msg); + if (!msg) + return; + + int size = 0; + void *data = flexran_agent_pack_message(msg, &size); + if (flexran_agent_msg_send(t->mod_id, FLEXRAN_AGENT_DEFAULT, data, size, 0) < 0) + LOG_E(FLEXRAN_AGENT, "error while sending message for timer xid %d\n", t->xid); +} + + err_code_t flexran_agent_create_timer(mid_t mod_id, uint32_t sf, - uint32_t timer_type, + flexran_agent_timer_type_t timer_type, xid_t xid, flexran_agent_timer_callback_t cb, - void *timer_args) { - int ret=-1; - - if (sf <= 0) + Protocol__FlexranMessage *msg) { + if (sf == 0) return TIMER_NULL; + if (cb == NULL) + return TIMER_SETUP_FAILED; + AssertFatal(timer_type != FLEXRAN_AGENT_TIMER_TYPE_ONESHOT, + "one shot timer not yet implemented\n"); - if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) - return TIMER_TYPE_INVALIDE; - - uint32_t interval_usec = sf * 1000; - uint32_t interval_sec = 0; - if (interval_usec >= 1000 * 1000) { - interval_sec = interval_usec / (1000 * 1000); - interval_usec = interval_usec % (1000 * 1000); - } - struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); - DevAssert(e != NULL); - long timer_id = 0; - AssertFatal(e, "cannot allocate memory for FlexRAN timer!\n"); - if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT) { - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - mod_id, - TIMER_ONE_SHOT, - timer_args, - &timer_id); - - e->type = TIMER_ONE_SHOT; - } else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ) { - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - mod_id, - TIMER_PERIODIC, - timer_args, - &timer_id); - e->type = TIMER_PERIODIC; - } - - if (ret < 0 ) { - free(e); + flexran_agent_timer_element_t *t = malloc(sizeof(flexran_agent_timer_element_t)); + if (!t) { + LOG_E(FLEXRAN_AGENT, "no memory for new timer %d\n", xid); return TIMER_SETUP_FAILED; } + t->mod_id = mod_id; + t->xid = xid; + t->sf = sf; + t->cb = cb; + t->msg = msg; - e->agent_id = mod_id; - e->instance = mod_id; - e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; - e->timer_id = timer_id; - e->xid = xid; - e->timer_args = timer_args; - e->cb = cb; - /*element should be a real pointer*/ - RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); - LOG_I(FLEXRAN_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", - e->timer_id, e->agent_id, e->instance); - return 0; -} - -err_code_t flexran_agent_destroy_timer(long timer_id) { - struct flexran_agent_timer_element_s *e = get_timer_entry(timer_id); - - if (e != NULL ) { - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); + struct timesync *sync = ×ync[mod_id]; + pthread_mutex_lock(&sync->mutex_timer); + if (sync->timer_num >= MAX_NUM_TIMERS) { + pthread_mutex_unlock(&sync->mutex_timer); + LOG_E(FLEXRAN_AGENT, "maximum number of timers (%d) reached while adding timer %d\n", + sync->timer_num, xid); + free(t); + return TIMER_SETUP_FAILED; } - - if (timer_remove(timer_id) < 0 ) - goto error; - + /* TODO check that xid does not exist? */ + t->next = sync->current + 1; + if (sync->next <= sync->current || t->next < sync->next) + sync->next = t->next; + sync->timer[sync->timer_num] = t; + sync->timer_num++; + pthread_mutex_unlock(&sync->mutex_timer); + LOG_D(FLEXRAN_AGENT, "added new timer xid %d for agent %d\n", xid, mod_id); return 0; -error: - LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); - return TIMER_REMOVED_FAILED ; } -err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid) { - struct flexran_agent_timer_element_s *e = NULL; - long timer_id; - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { - if (e->xid == xid) { - timer_id = e->timer_id; - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); +err_code_t flexran_agent_destroy_timers(mid_t mod_id) { + struct timesync *sync = ×ync[mod_id]; + pthread_mutex_lock(&sync->mutex_timer); + for (int i = sync->timer_num - 1; i < 0; --i) { + flexran_agent_timer_remove_internal(sync, i); + } + pthread_mutex_unlock(&sync->mutex_timer); + return 0; +} - if (timer_remove(timer_id) < 0 ) { - goto error; - } +err_code_t flexran_agent_destroy_timer(mid_t mod_id, xid_t xid) { + struct timesync *sync = ×ync[mod_id]; + pthread_mutex_lock(&sync->mutex_timer); + for (int i = 0; i < sync->timer_num; ++i) { + if (sync->timer[i]->xid == xid) { + flexran_agent_timer_remove_internal(sync, i); + pthread_mutex_unlock(&sync->mutex_timer); + return 0; } } - return 0; -error: - LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); - return TIMER_REMOVED_FAILED ; + pthread_mutex_unlock(&sync->mutex_timer); + LOG_E(FLEXRAN_AGENT, "could not find timer %d\n", xid); + return TIMER_ELEMENT_NOT_FOUND; } -err_code_t flexran_agent_destroy_timers(void) { - struct flexran_agent_timer_element_s *e = NULL; - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - timer_remove(e->timer_id); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); - } - return 0; -} - -err_code_t flexran_agent_stop_timer(long timer_id) { - struct flexran_agent_timer_element_s *e=NULL; - struct flexran_agent_timer_element_s search; - memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); - search.timer_id = timer_id; - e = RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); - - if (e != NULL ) { - e->state = FLEXRAN_AGENT_TIMER_STATE_STOPPED; - } - - timer_remove(timer_id); - return 0; -} - -struct flexran_agent_timer_element_s *get_timer_entry(long timer_id) { - struct flexran_agent_timer_element_s search; - memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); - search.timer_id = timer_id; - return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); +/* this function assumes that the timer lock is held */ +void flexran_agent_timer_remove_internal(struct timesync *sync, int index) { + LOG_I(FLEXRAN_AGENT, "remove timer xid %d (index %d) for agent %d\n", + sync->timer[index]->xid, index, sync->timer[index]->mod_id); + flexran_agent_destroy_flexran_message(sync->timer[index]->msg); + free(sync->timer[index]); + for (int i = index + 1; i < sync->timer_num; ++i) + sync->timer[i - 1] = sync->timer[i]; + sync->timer_num--; + sync->timer[sync->timer_num] = NULL; } diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index 4fbf44a7e2..b1cf8df51f 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -26,100 +26,45 @@ * \version 0.1 */ -#include -#include +#ifndef _FLEXRAN_AGENT_TIMER_ +#define _FLEXRAN_AGENT_TIMER_ #include "flexran_agent_common.h" -#include "flexran_agent_common_internal.h" -#include "flexran_agent_extern.h" #include "flexran_agent_defs.h" - -# include "tree.h" -# include "intertask_interface.h" - - - -/******************* - * timer primitves - *******************/ - #define TIMER_NULL -1 #define TIMER_TYPE_INVALIDE -2 #define TIMER_SETUP_FAILED -3 #define TIMER_REMOVED_FAILED -4 #define TIMER_ELEMENT_NOT_FOUND -5 +typedef enum { + FLEXRAN_AGENT_TIMER_TYPE_ONESHOT, + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, +} flexran_agent_timer_type_t; /* Type of the callback executed when the timer expired */ -typedef Protocol__FlexranMessage *(*flexran_agent_timer_callback_t)(void*); +typedef Protocol__FlexranMessage *(*flexran_agent_timer_callback_t)( + mid_t mod_id, const Protocol__FlexranMessage *msg); +err_code_t flexran_agent_timer_init(mid_t mod_id); +void flexran_agent_timer_exit(mid_t mod_id); -typedef struct flexran_agent_timer_args_s{ - mid_t mod_id; - Protocol__FlexranMessage *msg; -} flexran_agent_timer_args_t; - - -typedef struct flexran_agent_timer_element_s{ - RB_ENTRY(flexran_agent_timer_element_s) entry; - - agent_id_t agent_id; - instance_t instance; - - flexran_agent_timer_type_t type; - flexran_agent_timer_state_t state; - - uint32_t interval_sec; - uint32_t interval_usec; - - long timer_id; /* Timer id returned by the timer API*/ - xid_t xid; /*The id of the task as received by the controller - message*/ - - flexran_agent_timer_callback_t cb; - flexran_agent_timer_args_t *timer_args; - -} flexran_agent_timer_element_t; - -typedef struct flexran_agent_timer_instance_s{ - RB_HEAD(flexran_agent_map, flexran_agent_timer_element_s) flexran_agent_head; -}flexran_agent_timer_instance_t; - - -err_code_t flexran_agent_init_timer(void); +/* Signals next subframe for FlexRAN timers */ +void flexran_agent_timer_signal(mid_t mod_id); /* Create a timer for some agent related event with id xid. */ err_code_t flexran_agent_create_timer(mid_t mod_id, uint32_t sf, - uint32_t timer_type, + flexran_agent_timer_type_t timer_type, xid_t xid, flexran_agent_timer_callback_t cb, - void *timer_args); + Protocol__FlexranMessage *msg); /* Destroy all existing timers */ -err_code_t flexran_agent_destroy_timers(void); - -/* Destroy the timer with the given timer_id */ -err_code_t flexran_agent_destroy_timer(long timer_id); +err_code_t flexran_agent_destroy_timers(mid_t mod_id); /* Destroy the timer for task with id xid */ -err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid); +err_code_t flexran_agent_destroy_timer(mid_t mod_id, xid_t xid); -/* Stop a timer */ -err_code_t flexran_agent_stop_timer(long timer_id); - -/* Restart the given timer */ -err_code_t flexran_agent_restart_timer(long *timer_id); - -/* Find the timer with the given timer_id */ -struct flexran_agent_timer_element_s * get_timer_entry(long timer_id); - -/* Obtain the protocol message stored in the given expired timer */ -Protocol__FlexranMessage * flexran_agent_process_timeout(long timer_id, void* timer_args); - -/* Comparator function comparing two timers. Decides the ordering of the timers */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b); - -/* RB_PROTOTYPE is for .h files */ -RB_PROTOTYPE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); +#endif /* _FLEXRAN_AGENT_TIMER_ */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 3659933378..ae3f57bd8a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -988,6 +988,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (flexran_agent_get_mac_xface(module_idP) && subframeP == 9) { flexran_agent_slice_update(module_idP); } + if (flexran_agent_get_mac_xface(module_idP)) + flexran_agent_get_mac_xface(module_idP)->flexran_agent_notify_tick(module_idP); stop_meas(&(eNB->eNB_scheduler)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_OUT); From f87c1cbb92489a8eed6a1b3b74afcc2edf70e7e1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 8 Nov 2019 09:22:52 +0100 Subject: [PATCH 159/343] FlexRAN refactor+format MAC stats function --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 1214 ++++++++--------- .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 17 +- openair2/ENB_APP/flexran_agent_handler.c | 5 +- 3 files changed, 565 insertions(+), 671 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 04563b960e..1a8c2cefa8 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -62,676 +62,528 @@ int n_ue_slice_assoc_updates = 0; pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER; -int flexran_agent_mac_stats_reply(mid_t mod_id, - Protocol__FlexUeStatsReport **ue_report, - int n_ue, - uint32_t ue_flags, - Protocol__FlexCellStatsReport **cell_report, - int n_cc, - uint32_t cc_flags) { - - - // Protocol__FlexHeader *header; - int i, j, k; - int UE_id; - int cc_id = 0; - int enb_id = mod_id; - - /* Allocate memory for list of UE reports */ - if (n_ue > 0) { - - - for (i = 0; i < n_ue; i++) { - - const rnti_t rnti = ue_report[i]->rnti; - UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti); - - /* Check flag for creation of buffer status report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { - //TODO should be automated - ue_report[i]->n_bsr = 4; - uint32_t *elem; - elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); - if (elem == NULL) - goto error; - for (j = 0; j < ue_report[i]->n_bsr; j++) { - // NN: we need to know the cc_id here, consider the first one - elem[j] = flexran_get_ue_bsr_ul_buffer_info (enb_id, i, j); - } - - ue_report[i]->bsr = elem; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR; - } - - /* Check flag for creation of PHR report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { - ue_report[i]->phr = flexran_get_ue_phr (enb_id, UE_id); // eNB_UE_list->UE_template[UE_PCCID(enb_id,UE_id)][UE_id].phr_info; - ue_report[i]->has_phr = 1; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR; - - } - - /* Check flag for creation of RLC buffer status report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { - ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs - Protocol__FlexRlcBsr ** rlc_reports; - rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); - if (rlc_reports == NULL) - goto error; - - // NN: see LAYER2/openair2_proc.c for rlc status - for (j = 0; j < ue_report[i]->n_rlc_report; j++) { - - rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr)); - if (rlc_reports[j] == NULL){ - for (k = 0; k < j; k++){ - free(rlc_reports[k]); - } - free(rlc_reports); - goto error; - } - protocol__flex_rlc_bsr__init(rlc_reports[j]); - rlc_reports[j]->lc_id = j+1; - rlc_reports[j]->has_lc_id = 1; - rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, UE_id, j + 1); - rlc_reports[j]->has_tx_queue_size = 1; - - //TODO:Set tx queue head of line delay in ms - rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, UE_id, j + 1); - rlc_reports[j]->has_tx_queue_hol_delay = 1; - //TODO:Set retransmission queue size in bytes - rlc_reports[j]->retransmission_queue_size = 10; - rlc_reports[j]->has_retransmission_queue_size = 0; - //TODO:Set retransmission queue head of line delay in ms - rlc_reports[j]->retransmission_queue_hol_delay = 100; - rlc_reports[j]->has_retransmission_queue_hol_delay = 0; - //TODO DONE:Set current size of the pending message in bytes - rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(enb_id, UE_id, j + 1); - rlc_reports[j]->has_status_pdu_size = 1; - - } - // Add RLC buffer status reports to the full report - if (ue_report[i]->n_rlc_report > 0) - ue_report[i]->rlc_report = rlc_reports; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS; - - } - - /* Check flag for creation of MAC CE buffer status report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { - // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id, UE_id, 0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; - // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the - // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values - // found in stats_common.pb-c.h. See - // flex_ce_type in FlexRAN specification - ue_report[i]->has_pending_mac_ces = 1; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS; - } - - /* Check flag for creation of DL CQI report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { - // TODO: Fill in the actual DL CQI report for the UE based on its configuration - Protocol__FlexDlCqiReport * dl_report; - dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); - if (dl_report == NULL) - goto error; - protocol__flex_dl_cqi_report__init(dl_report); - - dl_report->sfn_sn = flexran_get_sfn_sf(enb_id); - dl_report->has_sfn_sn = 1; - //Set the number of DL CQI reports for this UE. One for each CC - dl_report->n_csi_report = flexran_get_active_CC(enb_id, UE_id); - dl_report->n_csi_report = 1 ; - //Create the actual CSI reports. - Protocol__FlexDlCsi **csi_reports; - csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); - if (csi_reports == NULL) { - free(dl_report); - goto error; - } - for (j = 0; j < dl_report->n_csi_report; j++) { - - csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); - if (csi_reports[j] == NULL) { - for (k = 0; k < j; k++) { - free(csi_reports[k]); - } - free(csi_reports); - csi_reports = NULL; - goto error; - } - protocol__flex_dl_csi__init(csi_reports[j]); - //The servCellIndex for this report - csi_reports[j]->serv_cell_index = j; - csi_reports[j]->has_serv_cell_index = 1; - //The rank indicator value for this cc - csi_reports[j]->ri = flexran_get_current_RI(enb_id, UE_id, j); - csi_reports[j]->has_ri = 1; - //TODO: the type of CSI report based on the configuration of the UE - //For now we only support type P10, which only needs a wideband value - //The full set of types can be found in stats_common.pb-c.h and - //in the FlexRAN specifications - csi_reports[j]->type = PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10; - csi_reports[j]->has_type = 1; - csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI; - - if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI){ - - Protocol__FlexCsiP10 *csi10; - csi10 = malloc(sizeof(Protocol__FlexCsiP10)); - if (csi10 == NULL) { - for (k = 0; k <= j; k++) { - free(csi_reports[k]); - } - free(csi_reports); - csi_reports = NULL; - goto error; - } - protocol__flex_csi_p10__init(csi10); - //TODO: set the wideband value - // NN: this is also depends on cc_id - csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,UE_id)][UE_id].dl_cqi; - csi10->has_wb_cqi = 1; - //Add the type of measurements to the csi report in the proper union type - csi_reports[j]->p10csi = csi10; - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI){ - - - Protocol__FlexCsiP11 *csi11; - csi11 = malloc(sizeof(Protocol__FlexCsiP11)); - if (csi11 == NULL) { - for (k = 0; k <= j; k++) { - free(csi_reports[k]); - } - free(csi_reports); - csi_reports = NULL; - goto error; - } - protocol__flex_csi_p11__init(csi11); - - csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); - csi11->n_wb_cqi = 1; - csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, UE_id); - // According To spec 36.213 - - if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { - // TODO PMI - csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); - csi11->has_wb_pmi = 1; - - } - - else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ - // TODO PMI - csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); - csi11->has_wb_pmi = 1; - - } - - else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){ - // TODO PMI - csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); - csi11->has_wb_pmi = 1; - - - } - - csi11->has_wb_pmi = 0; - - csi_reports[j]->p11csi = csi11; - - } - - - - - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ - - Protocol__FlexCsiP20 *csi20; - csi20 = malloc(sizeof(Protocol__FlexCsiP20)); - if (csi20 == NULL) { - for (k = 0; k <= j; k++) { - free(csi_reports[k]); - } - free(csi_reports); - csi_reports = NULL; - goto error; - } - protocol__flex_csi_p20__init(csi20); - - csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); - csi20->has_wb_cqi = 1; - - - csi20->bandwidth_part_index = 1 ;//TODO - csi20->has_bandwidth_part_index = 1; - - csi20->sb_index = 1 ;//TODO - csi20->has_sb_index = 1 ; - - - csi_reports[j]->p20csi = csi20; - - - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){ - - // Protocol__FlexCsiP21 *csi21; - // csi21 = malloc(sizeof(Protocol__FlexCsiP21)); - // if (csi21 == NULL) - // goto error; - // protocol__flex_csi_p21__init(csi21); - - // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); - - - // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside - // csi21->has_wb_pmi = 1; - - // csi21->sb_cqi = 1; // TODO - - // csi21->bandwidth_part_index = 1 ; //TDO inside - // csi21->has_bandwidth_part_index = 1 ; - - // csi21->sb_index = 1 ;//TODO - // csi21->has_sb_index = 1 ; - - - // csi_reports[j]->p20csi = csi21; - - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){ - - - // Protocol__FlexCsiA12 *csi12; - // csi12 = malloc(sizeof(Protocol__FlexCsiA12)); - // if (csi12 == NULL) - // goto error; - // protocol__flex_csi_a12__init(csi12); - - // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); - - // csi12->sb_pmi = 1 ; //TODO inside - - // TODO continou - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){ - - // Protocol__FlexCsiA22 *csi22; - // csi22 = malloc(sizeof(Protocol__FlexCsiA22)); - // if (csi22 == NULL) - // goto error; - // protocol__flex_csi_a22__init(csi22); - - // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); - - // csi22->sb_cqi = 1 ; //TODO inside - - // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, UE_id); - // csi22->has_wb_pmi = 1; - - // csi22->sb_pmi = 1 ; //TODO inside - // csi22->has_wb_pmi = 1; - - // csi22->sb_list = flexran_get_ue_wcqi (enb_id, UE_id); - - - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI){ - - // Protocol__FlexCsiA20 *csi20; - // csi20 = malloc(sizeof(Protocol__FlexCsiA20)); - // if (csi20 == NULL) - // goto error; - // protocol__flex_csi_a20__init(csi20); - - // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); - // csi20->has_wb_cqi = 1; - - // csi20>sb_cqi = 1 ; //TODO inside - // csi20>has_sb_cqi = 1 ; - - // csi20->sb_list = 1; // TODO inside - - - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI){ - - } - - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI){ - - } - - } - //Add the csi reports to the full DL CQI report - dl_report->csi_report = csi_reports; - //Add the DL CQI report to the stats report - ue_report[i]->dl_cqi_report = dl_report; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI; - } - - /* Check flag for creation of paging buffer status report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { - //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI - //set in the report must be a P-RNTI - Protocol__FlexPagingBufferReport *paging_report; - paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport)); - if (paging_report == NULL) - goto error; - protocol__flex_paging_buffer_report__init(paging_report); - //Set the number of pending paging messages - paging_report->n_paging_info = 1; - //Provide a report for each pending paging message - Protocol__FlexPagingInfo **p_info; - p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info); - if (p_info == NULL){ - free(paging_report); - goto error; - } - - for (j = 0; j < paging_report->n_paging_info; j++) { - - p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo)); - if (p_info[j] == NULL) { - for (k = 0; k < j; k++) { - free(p_info[k]); - } - free(p_info); - p_info = NULL; - free(paging_report); - goto error; - } - protocol__flex_paging_info__init(p_info[j]); - //TODO: Set paging index. This index is the same that will be used for the scheduling of the - //paging message by the controller - p_info[j]->paging_index = 10; - p_info[j]->has_paging_index = 1; - //TODO:Set the paging message size - p_info[j]->paging_message_size = 100; - p_info[j]->has_paging_message_size = 1; - //TODO: Set the paging subframe - p_info[j]->paging_subframe = 10; - p_info[j]->has_paging_subframe = 1; - //TODO: Set the carrier index for the pending paging message - p_info[j]->carrier_index = 0; - p_info[j]->has_carrier_index = 1; - - } - //Add all paging info to the paging buffer rerport - paging_report->paging_info = p_info; - //Add the paging report to the UE report - ue_report[i]->pbr = paging_report; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS; - } - - /* Check flag for creation of UL CQI report */ - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { - - //Fill in the full UL CQI report of the UE - Protocol__FlexUlCqiReport *full_ul_report; - full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport)); - if(full_ul_report == NULL) - goto error; - protocol__flex_ul_cqi_report__init(full_ul_report); - //TODO:Set the SFN and SF of the generated report - full_ul_report->sfn_sn = flexran_get_sfn_sf(enb_id); - full_ul_report->has_sfn_sn = 1; - //TODO:Set the number of UL measurement reports based on the types of measurements - //configured for this UE and on the servCellIndex - full_ul_report->n_cqi_meas = 1; - Protocol__FlexUlCqi **ul_report; - ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas); - if(ul_report == NULL) { - free(full_ul_report); - goto error; - } - //Fill each UL report of the UE for each of the configured report types - for(j = 0; j < full_ul_report->n_cqi_meas; j++) { - - ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi)); - if(ul_report[j] == NULL) { - for (k = 0; k < j; k++) { - free(ul_report[k]); - } - free(ul_report); - free(full_ul_report); - goto error; - } - protocol__flex_ul_cqi__init(ul_report[j]); - //TODO: Set the type of the UL report. As an example set it to SRS UL report - // See enum flex_ul_cqi_type in FlexRAN specification for more details - ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS; - ul_report[j]->has_type = 1; - //TODO:Set the number of SINR measurements based on the report type - //See struct flex_ul_cqi in FlexRAN specification for more details - ul_report[j]->n_sinr = 0; - uint32_t *sinr_meas; - sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr); - if (sinr_meas == NULL) { - for (k = 0; k < j; k++) { - free(ul_report[k]); - } - free(ul_report); - free(full_ul_report); - goto error; - } - //TODO:Set the SINR measurements for the specified type - for (k = 0; k < ul_report[j]->n_sinr; k++) { - sinr_meas[k] = 10; - } - ul_report[j]->sinr = sinr_meas; - //TODO: Set the servCellIndex for this report - ul_report[j]->serv_cell_index = 0; - ul_report[j]->has_serv_cell_index = 1; - - //Set the list of UL reports of this UE to the full UL report - full_ul_report->cqi_meas = ul_report; - - full_ul_report->n_pucch_dbm = MAX_NUM_CCs; - full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm); - - for (j = 0; j < MAX_NUM_CCs; j++) { - - full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm)); - protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]); - full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; - full_ul_report->pucch_dbm[j]->serv_cell_index = j; - - if(flexran_get_p0_pucch_dbm(enb_id, UE_id, j) != -1){ - full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id, UE_id, j); - full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1; - } - } - - - } - // Add full UL CQI report to the UE report - ue_report[i]->ul_cqi_report = full_ul_report; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI; - - } - if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { - - Protocol__FlexMacStats *macstats; - macstats = malloc(sizeof(Protocol__FlexMacStats)); - if (macstats == NULL) - goto error; - protocol__flex_mac_stats__init(macstats); - - - macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, UE_id, cc_id); - macstats->has_total_bytes_sdus_dl = 1; - - macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, UE_id, cc_id); - macstats->has_total_bytes_sdus_ul = 1; - - macstats->tbs_dl = flexran_get_TBS_dl(mod_id, UE_id, cc_id); - macstats->has_tbs_dl = 1; - - macstats->tbs_ul = flexran_get_TBS_ul(mod_id, UE_id, cc_id); - macstats->has_tbs_ul = 1; - - macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, UE_id, cc_id); - macstats->has_prb_retx_dl = 1; - - macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, UE_id, cc_id); - macstats->has_prb_retx_ul = 1; - - macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, UE_id, cc_id); - macstats->has_prb_dl = 1; - - macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, UE_id, cc_id); - macstats->has_prb_ul = 1; - - macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, UE_id, cc_id); - macstats->has_mcs1_dl = 1; - - macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, UE_id, cc_id); - macstats->has_mcs2_dl = 1; - - macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, UE_id, cc_id); - macstats->has_mcs1_ul = 1; - - macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, UE_id, cc_id); - macstats->has_mcs2_ul = 1; - - macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, UE_id, cc_id); - macstats->has_total_prb_dl = 1; - - macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, UE_id, cc_id); - macstats->has_total_prb_ul = 1; - - macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, UE_id, cc_id); - macstats->has_total_pdu_dl = 1; - - macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, UE_id, cc_id); - macstats->has_total_pdu_ul = 1; - - macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, UE_id, cc_id); - macstats->has_total_tbs_dl = 1; - - macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, UE_id, cc_id); - macstats->has_total_tbs_ul = 1; - - macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, UE_id); - macstats->has_harq_round = 1; - - Protocol__FlexMacSdusDl ** mac_sdus; - mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id)); - if (mac_sdus == NULL) { - free(macstats); - goto error; - } - - macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id); - - for (j = 0; j < macstats->n_mac_sdus_dl; j++){ - - - mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); - protocol__flex_mac_sdus_dl__init(mac_sdus[j]); - - mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, UE_id, cc_id, j); - mac_sdus[j]->has_lcid = 1; - - mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, UE_id, cc_id, mac_sdus[j]->lcid); - mac_sdus[j]->has_sdu_length = 1; - - - } - - - macstats->mac_sdus_dl = mac_sdus; - - - ue_report[i]->mac_stats = macstats; - ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS; - } - - - - - } - - - - - } - - /* Allocate memory for list of cell reports */ - if (n_cc > 0) { - - - // Fill in the Cell reports - for (i = 0; i < n_cc; i++) { - - - /* Check flag for creation of noise and interference report */ - if(cc_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { - // TODO: Fill in the actual noise and interference report for this cell - Protocol__FlexNoiseInterferenceReport *ni_report; - ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); - if(ni_report == NULL) - goto error; - protocol__flex_noise_interference_report__init(ni_report); - // Current frame and subframe number - ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); - ni_report->has_sfn_sf = 1; - //TODO:Received interference power in dbm - ni_report->rip = 0; - ni_report->has_rip = 1; - //TODO:Thermal noise power in dbm - ni_report->tnp = 0; - ni_report->has_tnp = 1; - - ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); - ni_report->has_p0_nominal_pucch = 1; - cell_report[i]->noise_inter_report = ni_report; - cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE; - } +int flexran_agent_mac_stats_reply_ue(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags) { + const int cc_id = 0; // TODO: make for multiple CCs + + for (int i = 0; i < n_ue; i++) { + const rnti_t rnti = ue_report[i]->rnti; + const int UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti); + + /* buffer status report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { + ue_report[i]->n_bsr = 4; //TODO should be automated + uint32_t *elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); + if (elem == NULL) + goto error; + for (int j = 0; j < ue_report[i]->n_bsr; j++) { + elem[j] = flexran_get_ue_bsr_ul_buffer_info (mod_id, i, j); + } + ue_report[i]->bsr = elem; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR; + } + + /* power headroom report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { + ue_report[i]->phr = flexran_get_ue_phr (mod_id, UE_id); + ue_report[i]->has_phr = 1; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR; + } + + /* Check flag for creation of RLC buffer status report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { + ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs + Protocol__FlexRlcBsr ** rlc_reports; + rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); + if (rlc_reports == NULL) + goto error; + + for (int j = 0; j < ue_report[i]->n_rlc_report; j++) { + rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr)); + if (rlc_reports[j] == NULL) { + for (int k = 0; k < j; k++) { + free(rlc_reports[k]); + } + free(rlc_reports); + goto error; + } + protocol__flex_rlc_bsr__init(rlc_reports[j]); + rlc_reports[j]->lc_id = j+1; + rlc_reports[j]->has_lc_id = 1; + rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(mod_id, UE_id, j + 1); + rlc_reports[j]->has_tx_queue_size = 1; + + rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(mod_id, UE_id, j + 1); + rlc_reports[j]->has_tx_queue_hol_delay = 1; + //TODO:Set retransmission queue size in bytes + rlc_reports[j]->retransmission_queue_size = 10; + rlc_reports[j]->has_retransmission_queue_size = 0; + //TODO:Set retransmission queue head of line delay in ms + rlc_reports[j]->retransmission_queue_hol_delay = 100; + rlc_reports[j]->has_retransmission_queue_hol_delay = 0; + rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(mod_id, UE_id, j + 1); + rlc_reports[j]->has_status_pdu_size = 1; + + } + if (ue_report[i]->n_rlc_report > 0) + ue_report[i]->rlc_report = rlc_reports; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS; + } + + /* MAC CE buffer status report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { + // TODO: Fill in the actual MAC CE buffer status report + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(mod_id, UE_id, 0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + // Use as bitmap. Set one or more of the; + // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values + // found in stats_common.pb-c.h. See + // flex_ce_type in FlexRAN specification + ue_report[i]->has_pending_mac_ces = 1; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS; + } + + /* DL CQI report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { + // TODO: Fill in the actual DL CQI report for the UE based on its configuration + Protocol__FlexDlCqiReport * dl_report; + dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); + if (dl_report == NULL) + goto error; + protocol__flex_dl_cqi_report__init(dl_report); + + dl_report->sfn_sn = flexran_get_sfn_sf(mod_id); + dl_report->has_sfn_sn = 1; + dl_report->n_csi_report = flexran_get_active_CC(mod_id, UE_id); + dl_report->n_csi_report = 1 ; + //Create the actual CSI reports. + Protocol__FlexDlCsi **csi_reports; + csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); + if (csi_reports == NULL) { + free(dl_report); + goto error; + } + for (int j = 0; j < dl_report->n_csi_report; j++) { + csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); + if (csi_reports[j] == NULL) { + for (int k = 0; k < j; k++) { + free(csi_reports[k]); + } + free(csi_reports); + csi_reports = NULL; + goto error; + } + protocol__flex_dl_csi__init(csi_reports[j]); + csi_reports[j]->serv_cell_index = j; + csi_reports[j]->has_serv_cell_index = 1; + csi_reports[j]->ri = flexran_get_current_RI(mod_id, UE_id, j); + csi_reports[j]->has_ri = 1; + //TODO: the type of CSI report based on the configuration of the UE + //For now we only support type P10, which only needs a wideband value + csi_reports[j]->type = PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10; + csi_reports[j]->has_type = 1; + csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI; + + if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI) { + Protocol__FlexCsiP10 *csi10; + csi10 = malloc(sizeof(Protocol__FlexCsiP10)); + if (csi10 == NULL) { + for (int k = 0; k <= j; k++) { + free(csi_reports[k]); } + free(csi_reports); + csi_reports = NULL; + goto error; + } + protocol__flex_csi_p10__init(csi10); + csi10->wb_cqi = flexran_get_ue_wcqi(mod_id, UE_id); + csi10->has_wb_cqi = 1; + csi_reports[j]->p10csi = csi10; + } + + /* + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI) { + Protocol__FlexCsiP11 *csi11; + csi11 = malloc(sizeof(Protocol__FlexCsiP11)); + if (csi11 == NULL) { + for (int k = 0; k <= j; k++) { + free(csi_reports[k]); + } + free(csi_reports); + csi_reports = NULL; + goto error; + } + protocol__flex_csi_p11__init(csi11); + + csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); + csi11->n_wb_cqi = 1; + csi11->wb_cqi[0] = flexran_get_ue_wcqi (mod_id, UE_id); + // According To spec 36.213 + + if (flexran_get_antenna_ports(mod_id, j) == 2 && csi_reports[j]->ri == 1) { + // TODO PMI + csi11->wb_pmi = flexran_get_ue_wpmi(mod_id, UE_id, 0); + csi11->has_wb_pmi = 1; + + } + + else if (flexran_get_antenna_ports(mod_id, j) == 2 && csi_reports[j]->ri == 2) { + // TODO PMI + csi11->wb_pmi = flexran_get_ue_wpmi(mod_id, UE_id, 0); + csi11->has_wb_pmi = 1; + + } + + else if (flexran_get_antenna_ports(mod_id, j) == 4 && csi_reports[j]->ri == 2) { + // TODO PMI + csi11->wb_pmi = flexran_get_ue_wpmi(mod_id, UE_id, 0); + csi11->has_wb_pmi = 1; + } + + csi11->has_wb_pmi = 0; + csi_reports[j]->p11csi = csi11; + } + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI) { + + Protocol__FlexCsiP20 *csi20; + csi20 = malloc(sizeof(Protocol__FlexCsiP20)); + if (csi20 == NULL) { + for (int k = 0; k <= j; k++) { + free(csi_reports[k]); + } + free(csi_reports); + csi_reports = NULL; + goto error; + } + protocol__flex_csi_p20__init(csi20); + + csi20->wb_cqi = flexran_get_ue_wcqi (mod_id, UE_id); + csi20->has_wb_cqi = 1; + csi20->bandwidth_part_index = 1 ; //TODO + csi20->has_bandwidth_part_index = 0; + csi20->sb_index = 1; //TODO + csi20->has_sb_index = 1; + csi_reports[j]->p20csi = csi20; + } + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI) { + + // Protocol__FlexCsiP21 *csi21; + // csi21 = malloc(sizeof(Protocol__FlexCsiP21)); + // if (csi21 == NULL) + // goto error; + // protocol__flex_csi_p21__init(csi21); + + // csi21->wb_cqi = flexran_get_ue_wcqi (mod_id, UE_id); + + + // csi21->wb_pmi = flexran_get_ue_pmi(mod_id); //TDO inside + // csi21->has_wb_pmi = 1; + + // csi21->sb_cqi = 1; // TODO + + // csi21->bandwidth_part_index = 1 ; //TDO inside + // csi21->has_bandwidth_part_index = 1 ; + + // csi21->sb_index = 1 ;//TODO + // csi21->has_sb_index = 1 ; + + + // csi_reports[j]->p20csi = csi21; + + } + + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI) { + + + // Protocol__FlexCsiA12 *csi12; + // csi12 = malloc(sizeof(Protocol__FlexCsiA12)); + // if (csi12 == NULL) + // goto error; + // protocol__flex_csi_a12__init(csi12); + + // csi12->wb_cqi = flexran_get_ue_wcqi (mod_id, UE_id); + + // csi12->sb_pmi = 1 ; //TODO inside + + // TODO continou + } + + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI) { + + // Protocol__FlexCsiA22 *csi22; + // csi22 = malloc(sizeof(Protocol__FlexCsiA22)); + // if (csi22 == NULL) + // goto error; + // protocol__flex_csi_a22__init(csi22); + + // csi22->wb_cqi = flexran_get_ue_wcqi (mod_id, UE_id); + + // csi22->sb_cqi = 1 ; //TODO inside + + // csi22->wb_pmi = flexran_get_ue_wcqi (mod_id, UE_id); + // csi22->has_wb_pmi = 1; + + // csi22->sb_pmi = 1 ; //TODO inside + // csi22->has_wb_pmi = 1; + + // csi22->sb_list = flexran_get_ue_wcqi (mod_id, UE_id); + + + } + + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI) { + + // Protocol__FlexCsiA20 *csi20; + // csi20 = malloc(sizeof(Protocol__FlexCsiA20)); + // if (csi20 == NULL) + // goto error; + // protocol__flex_csi_a20__init(csi20); + + // csi20->wb_cqi = flexran_get_ue_wcqi (mod_id, UE_id); + // csi20->has_wb_cqi = 1; + + // csi20>sb_cqi = 1 ; //TODO inside + // csi20>has_sb_cqi = 1 ; + + // csi20->sb_list = 1; // TODO inside + + + } + + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI) { + + } + + else if (csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI) { + + } + */ + + } + dl_report->csi_report = csi_reports; + ue_report[i]->dl_cqi_report = dl_report; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI; + } + + /* paging buffer status report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { + //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI + //set in the report must be a P-RNTI + Protocol__FlexPagingBufferReport *paging_report; + paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport)); + if (paging_report == NULL) + goto error; + protocol__flex_paging_buffer_report__init(paging_report); + paging_report->n_paging_info = 1; + Protocol__FlexPagingInfo **p_info; + p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info); + if (p_info == NULL) { + free(paging_report); + goto error; + } + + for (int j = 0; j < paging_report->n_paging_info; j++) { + + p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo)); + if (p_info[j] == NULL) { + for (int k = 0; k < j; k++) { + free(p_info[k]); + } + free(p_info); + p_info = NULL; + free(paging_report); + goto error; + } + protocol__flex_paging_info__init(p_info[j]); + //TODO: Set paging index. This index is the same that will be used for the scheduling of the + //paging message by the controller + p_info[j]->paging_index = 10; + p_info[j]->has_paging_index = 0; + //TODO:Set the paging message size + p_info[j]->paging_message_size = 100; + p_info[j]->has_paging_message_size = 0; + //TODO: Set the paging subframe + p_info[j]->paging_subframe = 10; + p_info[j]->has_paging_subframe = 0; + //TODO: Set the carrier index for the pending paging message + p_info[j]->carrier_index = 0; + p_info[j]->has_carrier_index = 0; + + } + //Add all paging info to the paging buffer rerport + paging_report->paging_info = p_info; + //Add the paging report to the UE report + ue_report[i]->pbr = paging_report; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS; + } + + /* Check flag for creation of UL CQI report */ + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { + + //Fill in the full UL CQI report of the UE + Protocol__FlexUlCqiReport *full_ul_report; + full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport)); + if (full_ul_report == NULL) + goto error; + protocol__flex_ul_cqi_report__init(full_ul_report); + full_ul_report->sfn_sn = flexran_get_sfn_sf(mod_id); + full_ul_report->has_sfn_sn = 1; + //TODO:Set the number of UL measurement reports based on the types of measurements + //configured for this UE and on the servCellIndex + full_ul_report->n_cqi_meas = 1; + Protocol__FlexUlCqi **ul_report; + ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas); + if (ul_report == NULL) { + free(full_ul_report); + goto error; + } + //Fill each UL report of the UE for each of the configured report types + for (int j = 0; j < full_ul_report->n_cqi_meas; j++) { + + ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi)); + if (ul_report[j] == NULL) { + for (int k = 0; k < j; k++) { + free(ul_report[k]); + } + free(ul_report); + free(full_ul_report); + goto error; + } + protocol__flex_ul_cqi__init(ul_report[j]); + //TODO: Set the type of the UL report. As an example set it to SRS UL report + ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS; + ul_report[j]->has_type = 1; + //TODO:Set the number of SINR measurements based on the report type + ul_report[j]->n_sinr = 0; + uint32_t *sinr_meas; + sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr); + if (sinr_meas == NULL) { + for (int k = 0; k < j; k++) { + free(ul_report[k]); + } + free(ul_report); + free(full_ul_report); + goto error; + } + //TODO:Set the SINR measurements for the specified type + for (int k = 0; k < ul_report[j]->n_sinr; k++) { + sinr_meas[k] = 10; + } + ul_report[j]->sinr = sinr_meas; + //TODO: Set the servCellIndex for this report + ul_report[j]->serv_cell_index = 0; + ul_report[j]->has_serv_cell_index = 1; + + //Set the list of UL reports of this UE to the full UL report + full_ul_report->cqi_meas = ul_report; + + full_ul_report->n_pucch_dbm = MAX_NUM_CCs; + full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm); + + for (int j = 0; j < MAX_NUM_CCs; j++) { + + full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm)); + protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]); + full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; + full_ul_report->pucch_dbm[j]->serv_cell_index = j; + + if (flexran_get_p0_pucch_dbm(mod_id, UE_id, j) != -1) { + full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(mod_id, UE_id, j); + full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1; + } + } + + + } + // Add full UL CQI report to the UE report + ue_report[i]->ul_cqi_report = full_ul_report; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI; + + } + if (ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { + + Protocol__FlexMacStats *macstats; + macstats = malloc(sizeof(Protocol__FlexMacStats)); + if (macstats == NULL) + goto error; + protocol__flex_mac_stats__init(macstats); + macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, UE_id, cc_id); + macstats->has_total_bytes_sdus_dl = 1; + macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, UE_id, cc_id); + macstats->has_total_bytes_sdus_ul = 1; + macstats->tbs_dl = flexran_get_TBS_dl(mod_id, UE_id, cc_id); + macstats->has_tbs_dl = 1; + macstats->tbs_ul = flexran_get_TBS_ul(mod_id, UE_id, cc_id); + macstats->has_tbs_ul = 1; + macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, UE_id, cc_id); + macstats->has_prb_retx_dl = 1; + macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, UE_id, cc_id); + macstats->has_prb_retx_ul = 1; + macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, UE_id, cc_id); + macstats->has_prb_dl = 1; + macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, UE_id, cc_id); + macstats->has_prb_ul = 1; + macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, UE_id, cc_id); + macstats->has_mcs1_dl = 1; + macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, UE_id, cc_id); + macstats->has_mcs2_dl = 1; + macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, UE_id, cc_id); + macstats->has_mcs1_ul = 1; + macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, UE_id, cc_id); + macstats->has_mcs2_ul = 1; + macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, UE_id, cc_id); + macstats->has_total_prb_dl = 1; + macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, UE_id, cc_id); + macstats->has_total_prb_ul = 1; + macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, UE_id, cc_id); + macstats->has_total_pdu_dl = 1; + macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, UE_id, cc_id); + macstats->has_total_pdu_ul = 1; + macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, UE_id, cc_id); + macstats->has_total_tbs_dl = 1; + macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, UE_id, cc_id); + macstats->has_total_tbs_ul = 1; + macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, UE_id); + macstats->has_harq_round = 1; + + Protocol__FlexMacSdusDl ** mac_sdus; + mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id)); + if (mac_sdus == NULL) { + free(macstats); + goto error; + } + + macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id); + for (int j = 0; j < macstats->n_mac_sdus_dl; j++) { + mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); + protocol__flex_mac_sdus_dl__init(mac_sdus[j]); + mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, UE_id, cc_id, j); + mac_sdus[j]->has_lcid = 1; + mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, UE_id, cc_id, mac_sdus[j]->lcid); + mac_sdus[j]->has_sdu_length = 1; + } + macstats->mac_sdus_dl = mac_sdus; + ue_report[i]->mac_stats = macstats; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS; + } } - return 0; - error: - - if (cell_report != NULL) { - if (n_cc > 0) { - for (i = 0; i < n_cc; i++) { - if (cell_report[i]->noise_inter_report != NULL) { - free(cell_report[i]->noise_inter_report); - cell_report[i]->noise_inter_report = NULL; - } - } - } - free(cell_report); - cell_report = NULL; - } - +error: if (ue_report != NULL) { if (n_ue > 0) { - for (i = 0; i < n_ue; i++) { + for (int i = 0; i < n_ue; i++) { if (ue_report[i]->bsr != NULL) { free(ue_report[i]->bsr); ue_report[i]->bsr = NULL; } if (ue_report[i]->rlc_report != NULL) { - for (j = 0; j < ue_report[i]->n_rlc_report; j++) { + for (int j = 0; j < ue_report[i]->n_rlc_report; j++) { if (ue_report[i]->rlc_report[j] != NULL) { free(ue_report[i]->rlc_report[j]); ue_report[i]->rlc_report[j] = NULL; @@ -742,7 +594,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } if (ue_report[i]->dl_cqi_report != NULL) { if (ue_report[i]->dl_cqi_report->csi_report != NULL) { - for (j = 0; j < ue_report[i]->dl_cqi_report->n_csi_report; j++) { + for (int j = 0; j < ue_report[i]->dl_cqi_report->n_csi_report; j++) { if (ue_report[i]->dl_cqi_report->csi_report[j] != NULL) { if (ue_report[i]->dl_cqi_report->csi_report[j]->p10csi != NULL) { free(ue_report[i]->dl_cqi_report->csi_report[j]->p10csi); @@ -772,7 +624,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } if (ue_report[i]->pbr != NULL) { if (ue_report[i]->pbr->paging_info != NULL) { - for (j = 0; j < ue_report[i]->pbr->n_paging_info; j++) { + for (int j = 0; j < ue_report[i]->pbr->n_paging_info; j++) { free(ue_report[i]->pbr->paging_info[j]); ue_report[i]->pbr->paging_info[j] = NULL; } @@ -784,7 +636,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } if (ue_report[i]->ul_cqi_report != NULL) { if (ue_report[i]->ul_cqi_report->cqi_meas != NULL) { - for (j = 0; j < ue_report[i]->ul_cqi_report->n_cqi_meas; j++) { + for (int j = 0; j < ue_report[i]->ul_cqi_report->n_cqi_meas; j++) { if (ue_report[i]->ul_cqi_report->cqi_meas[j] != NULL) { if (ue_report[i]->ul_cqi_report->cqi_meas[j]->sinr != NULL) { free(ue_report[i]->ul_cqi_report->cqi_meas[j]->sinr); @@ -798,7 +650,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, ue_report[i]->ul_cqi_report->cqi_meas = NULL; } if (ue_report[i]->ul_cqi_report->pucch_dbm != NULL) { - for (j = 0; j < MAX_NUM_CCs; j++) { + for (int j = 0; j < MAX_NUM_CCs; j++) { if (ue_report[i]->ul_cqi_report->pucch_dbm[j] != NULL) { free(ue_report[i]->ul_cqi_report->pucch_dbm[j]); ue_report[i]->ul_cqi_report->pucch_dbm[j] = NULL; @@ -812,7 +664,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } if (ue_report[i]->mac_stats != NULL) { if (ue_report[i]->mac_stats->mac_sdus_dl != NULL) { - for (j = 0; j < ue_report[i]->mac_stats->n_mac_sdus_dl; j++) { + for (int j = 0; j < ue_report[i]->mac_stats->n_mac_sdus_dl; j++) { if (ue_report[i]->mac_stats->mac_sdus_dl[j] != NULL) { free(ue_report[i]->mac_stats->mac_sdus_dl[j]); ue_report[i]->mac_stats->mac_sdus_dl[j] = NULL; @@ -828,7 +680,49 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } free(ue_report); } + return -1; +} +int flexran_agent_mac_stats_reply_cell(mid_t mod_id, + Protocol__FlexCellStatsReport **cell_report, + int n_cc, + uint32_t cc_flags) { + for (int i = 0; i < n_cc; i++) { + /* noise and interference report */ + if(cc_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + // TODO: Fill in the actual noise and interference report for this cell + Protocol__FlexNoiseInterferenceReport *ni_report; + ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); + if(ni_report == NULL) + goto error; + protocol__flex_noise_interference_report__init(ni_report); + ni_report->sfn_sf = flexran_get_sfn_sf(mod_id); + ni_report->has_sfn_sf = 1; + ni_report->rip = 0; //TODO: Received interference power in dbm + ni_report->has_rip = 0; + ni_report->tnp = 0; //TODO: Thermal noise power in dbm + ni_report->has_tnp = 0; + ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(mod_id, 0); + ni_report->has_p0_nominal_pucch = 1; + cell_report[i]->noise_inter_report = ni_report; + cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE; + } + } + return 0; + + error: + if (cell_report != NULL) { + if (n_cc > 0) { + for (int i = 0; i < n_cc; i++) { + if (cell_report[i]->noise_inter_report != NULL) { + free(cell_report[i]->noise_inter_report); + cell_report[i]->noise_inter_report = NULL; + } + } + } + free(cell_report); + cell_report = NULL; + } return -1; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 68a572e2b2..2f9f99c740 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -51,14 +51,15 @@ int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg); int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg); -/* Statistics reply protocol message constructor and destructor */ -int flexran_agent_mac_stats_reply(mid_t mod_id, - Protocol__FlexUeStatsReport **ue_report, - int n_ue, - uint32_t ue_flags, - Protocol__FlexCellStatsReport **cell_report, - int n_cc, - uint32_t cc_flags); +/* Statistics reply protocol message constructors (for UE and cell stats) and destructor */ +int flexran_agent_mac_stats_reply_ue(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags); +int flexran_agent_mac_stats_reply_cell(mid_t mod_id, + Protocol__FlexCellStatsReport **cell_report, + int n_cc, + uint32_t cc_flags); int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* DL MAC scheduling decision protocol message constructor (empty command) and destructor */ diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 1bae0776a3..7c251e9172 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -297,9 +297,8 @@ int flexran_agent_stats_reply(mid_t enb_id, /* MAC reply split */ if (flexran_agent_get_mac_xface(enb_id) - && flexran_agent_mac_stats_reply(enb_id, - ue_report, n_ue, ue_flags, - cell_report, n_cc, cell_flags) < 0) { + && (flexran_agent_mac_stats_reply_ue(enb_id, ue_report, n_ue, ue_flags) < 0 + || flexran_agent_mac_stats_reply_cell(enb_id, cell_report, n_cc, cell_flags) < 0)) { err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; goto error; } From a8b4a62b824c959b598b39b23c7cb1f2b6ce1a72 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Sep 2019 19:34:00 +0200 Subject: [PATCH 160/343] Read RU config before FlexRAN to allow split identification --- openair2/ENB_APP/enb_config.c | 2 ++ targets/RT/USER/lte-ru.c | 8 +------- targets/RT/USER/lte-softmodem.c | 20 +++++++++++++++----- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index ef4c328691..c1918d4fee 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -3104,4 +3104,6 @@ void read_config_and_init(void) { memset((void *)RC.rrc[enb_id], 0, sizeof(eNB_RRC_INST)); RCconfig_RRC(enb_id, RC.rrc[enb_id],macrlc_has_f1[enb_id]); } + + RCconfig_flexran(); } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 459732a30c..f88d98536d 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2683,13 +2683,9 @@ void init_RU(char *rf_config_file, clock_source_t clock_source, clock_source_t t PHY_VARS_eNB *eNB0 = (PHY_VARS_eNB *)NULL; LTE_DL_FRAME_PARMS *fp = (LTE_DL_FRAME_PARMS *)NULL; // create status mask - RC.ru_mask = 0; + RC.ru_mask= (1 << RC.nb_RU) - 1; pthread_mutex_init(&RC.ru_mutex,NULL); pthread_cond_init(&RC.ru_cond,NULL); - // read in configuration file) - printf("configuring RU from file\n"); - RCconfig_RU(); - LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs()); if (RC.nb_CC != 0) for (i=0; i 0) { RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *)); - RC.ru_mask=(1< 0) { read_config_and_init(); - /* Start the agent. If it is turned off in the configuration, it won't start */ - RCconfig_flexran(); + } else { + printf("RC.nb_inst = 0, Initializing L1\n"); + RCconfig_L1(); + } + /* We need to read RU configuration before FlexRAN starts so it knows what + * splits to report. Actual RU start comes later. */ + if (RC.nb_RU > 0 && NFAPI_MODE != NFAPI_MODE_VNF) { + RCconfig_RU(); + LOG_I(PHY, + "number of L1 instances %d, number of RU %d, number of CPU cores %d\n", + RC.nb_L1_inst, RC.nb_RU, get_nprocs()); + } + + if (RC.nb_inst > 0) { + /* Start the agent. If it is turned off in the configuration, it won't start */ for (i = 0; i < RC.nb_inst; i++) { flexran_agent_start(i); } @@ -607,9 +620,6 @@ int main ( int argc, char **argv ) itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); } node_type = RC.rrc[0]->node_type; - } else { - printf("RC.nb_inst = 0, Initializing L1\n"); - RCconfig_L1(); } if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) { From d2b1e6aa9ae5a6f62bb5f3beeec17247647da026 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Sep 2019 17:57:27 +0200 Subject: [PATCH 161/343] FlexRAN: report employed splits to controller --- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 9 +++++++ openair2/ENB_APP/flexran_agent_common.c | 2 ++ openair2/ENB_APP/flexran_agent_ran_api.c | 28 ++++++++++++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 6 +++++ 4 files changed, 45 insertions(+) diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 86f2e9329f..1d87a52b97 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -77,10 +77,19 @@ enum flex_bs_capability { RRC = 7; } +enum flex_bs_split { + F1 = 0; + nFAPI = 1; + IF4 = 2; + IF4p5 = 3; + IF5 = 4; +} + message flex_hello { optional flex_header header = 1; optional uint64 bs_id = 2; // Unique id to distinguish the eNB repeated flex_bs_capability capabilities = 3; + repeated flex_bs_split splits = 4; } message flex_echo_request { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 552c58555b..fe65315fe9 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -128,6 +128,7 @@ int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessa hello_msg->bs_id = flexran_get_bs_id(mod_id); hello_msg->has_bs_id = 1; hello_msg->n_capabilities = flexran_get_capabilities(mod_id, &hello_msg->capabilities); + hello_msg->n_splits = flexran_get_splits(mod_id, &hello_msg->splits); *msg = malloc(sizeof(Protocol__FlexranMessage)); if(*msg == NULL) @@ -161,6 +162,7 @@ int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) { free(msg->hello_msg->header); free(msg->hello_msg->capabilities); + free(msg->hello_msg->splits); free(msg->hello_msg); free(msg); return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index dfac1ae7a0..f479198895 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3570,3 +3570,31 @@ uint16_t flexran_get_capabilities_mask(mid_t mod_id) { return mask; } + +size_t flexran_get_splits(mid_t mod_id, Protocol__FlexBsSplit **splits) { + size_t n_splits = 0; + *splits = NULL; + if (rrc_is_present(mod_id) && !NODE_IS_MONOLITHIC(RC.rrc[mod_id]->node_type)) + n_splits++; + if (NFAPI_MODE != NFAPI_MONOLITHIC) + n_splits++; + if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south != LOCAL_RF) + n_splits++; + if (n_splits == 0) + return 0; + + AssertFatal(n_splits < 3, "illegal number of splits (%lu)\n", n_splits); + *splits = calloc(n_splits, sizeof(Protocol__FlexBsSplit)); + AssertFatal(*splits, "could not allocate Protocol__FlexBsSplit array\n"); + int n = 0; + if (rrc_is_present(mod_id) && !NODE_IS_MONOLITHIC(RC.rrc[mod_id]->node_type)) + (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__F1; + if (NFAPI_MODE != NFAPI_MONOLITHIC) + (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__nFAPI; + if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south == REMOTE_IF4p5) + (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__IF4p5; + if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south == REMOTE_IF5) + (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__IF5; + DevAssert(n == n_splits); + return n_splits; +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index f9d0d97405..6aef1c406b 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -44,6 +44,7 @@ #include "RRC/LTE/rrc_eNB_UE_context.h" #include "PHY/phy_extern.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" /**************************** * get generic info from RAN @@ -815,3 +816,8 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) /* get the capabilities supported by the underlying network function as a bit * mask. */ uint16_t flexran_get_capabilities_mask(mid_t mod_id); + +/* get the splits used by the underlying network function, + * return the number and stores list of this length in splits. If there are + * zero capabilities, splits will be NULL */ +size_t flexran_get_splits(mid_t mod_id, Protocol__FlexBsSplit **splits); From 6a581d903bd156c344370887e7360fe53e0535b0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 24 Mar 2019 14:17:23 +0100 Subject: [PATCH 162/343] Add FlexRAN protobuf definition for S1AP --- .../ENB_APP/MESSAGES/V2/config_common.proto | 32 +++++++++++++++++++ .../ENB_APP/MESSAGES/V2/config_messages.proto | 12 +++++-- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 1 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index 4958cdb27b..c87e589d89 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -336,3 +336,35 @@ message flex_a5_event { optional int64 time_to_trigger = 4; optional int64 max_report_cells = 5; } + +// +// S1AP cell configuration +// +message flex_gummei { + optional flex_plmn plmn = 1; + optional uint32 mme_group_id = 2; + optional uint32 mme_code = 3; +} + +message flex_s1ap_mme { + optional string s1_ip = 1; // S1-MME IP of MME + optional string name = 2; // S1-MME name of MME + optional flex_mme_state state = 3; // State of the MME + repeated flex_gummei served_gummeis = 4; // GUMMEIs served by the MME + repeated flex_plmn requested_plmns = 5; // PLMNs communicated to MME + optional uint32 rel_capacity = 6; // Relative MME capacity, TS23.401 +} + +message flex_s1ap_ue { + optional string mme_s1_ip = 1; // IP of MME to which UE is connected + optional uint32 enb_ue_s1ap_id = 2; // S1AP ID on eNodeB side for UE + optional uint32 mme_ue_s1ap_id = 3; // S1AP ID on MME side for UE + optional flex_plmn selected_plmn = 4; // UE-selected PLMN in RRC Conn Setup Cplt +} + +enum flex_mme_state { + FLMMES_DISCONNECTED = 0; + FLMMES_WAITING = 1; + FLMMES_CONNECTED = 2; + FLMMES_OVERLOAD = 3; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 6d24e5a0ac..4d8c628c4f 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -100,6 +100,7 @@ message flex_ue_config { optional uint32 ul_slice_id = 32; // Configuration about RRC measurements optional flex_measurement_info info = 33; + optional uint32 enb_ue_s1ap_id = 34; // S1AP ID on eNodeB side } message flex_lc_ue_config { @@ -107,6 +108,11 @@ message flex_lc_ue_config { repeated flex_lc_config lc_config = 2; // A list of LC configurations for the given UE } - - - +message flex_s1ap_config { + optional uint32 pending = 1; // number of pending (to be connected) MMEs + optional uint32 connected = 2; // number of connected MMEs + optional string enb_s1_ip = 3; // S1-MME IP of eNodeB + optional string enb_name = 4; // S1-MME name of eNodeB + repeated flex_s1ap_mme mme = 5; + repeated flex_s1ap_ue ue = 6; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 1d87a52b97..24a219a564 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -156,6 +156,7 @@ message flex_enb_config_reply { optional flex_header header = 1; repeated flex_cell_config cell_config = 3; optional uint32 device_spec = 4; + optional flex_s1ap_config s1ap = 5; } message flex_ue_config_request { From 44fdb23f153543e6a5422f0c5cb19ea48972d1df Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 24 Mar 2019 14:34:04 +0100 Subject: [PATCH 163/343] FlexRAN: fix RRC protobuf definition --- openair2/ENB_APP/MESSAGES/V2/stats_common.proto | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index b56ad8eea1..20f0f60a9f 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -1,6 +1,8 @@ syntax = "proto2"; package protocol; +import "config_common.proto"; // for flex_plmn + // // UE related statistics // @@ -218,25 +220,16 @@ message flex_eutra_cgi_measurements { // Tracking area code of the neighbor cell. optional uint32 tracking_area_code = 2; // Public land mobile network identifiers of neighbor cell. - repeated flex_plmn_identity plmn_id = 3; + repeated flex_plmn plmn = 3; } message flex_cell_global_eutra_id { // Public land mobile network identifier of neighbor cell. - optional flex_plmn_identity plmn_id = 1; + optional flex_plmn plmn = 1; // Cell identifier of neighbor cell. optional uint32 cell_id = 2; } -message flex_plmn_identity { - // Mobile Network Code (MNC). - repeated uint32 mnc = 1; - // Mobile Country Code (MCC). - repeated uint32 mcc = 2; - // tracking area code - repeated uint32 tac = 3; -} - message flex_eutra_ref_signal_meas { // Neighboring Cell RSRP optional int32 rsrp = 1; From ef0a45325b2d36763badfa7d2a0b10b7cc4bfcf8 Mon Sep 17 00:00:00 2001 From: cig Date: Fri, 17 Jan 2020 16:41:50 +0100 Subject: [PATCH 164/343] Split configure_fapi_dl_tx function into two functions: - configure_fapi_dl_pdu is handling the nfapi_nr_dl_config_request_pdu - while configure_fapi_dl_Tx is now handling the nfapi_tx_request_pdu this was necessary because the computation of the TBS size is needed in the phytest scheduler before even knowing if there is any data to transmit. The tx_request_pdu must be handled instead only when there is data to transmit. --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 54 +++++++++++-------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 15 +++--- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 59cf43cc06..4856079e4a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -156,16 +156,13 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } -int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, - nfapi_tx_request_pdu_t *TX_req, - nfapi_nr_config_request_t *cfg, - nfapi_nr_coreset_t *coreset, - nfapi_nr_search_space_t *search_space, - int16_t pdu_index, - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config) { +int configure_fapi_dl_pdu(nfapi_nr_dl_config_request_body_t *dl_req, + nfapi_nr_config_request_t *cfg, + nfapi_nr_coreset_t *coreset, + nfapi_nr_search_space_t *search_space, + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config){ nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; - int TBS; uint16_t rnti = 0x1234; int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; @@ -242,9 +239,20 @@ int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, params_rel15->rb_offset, params_rel15->first_symbol, params_rel15->search_space_type); + nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); - TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size; - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", + + return dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size/8; +} + +void configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, + nfapi_tx_request_pdu_t *tx_req, + int tbs_bytes, + int16_t pdu_index){ + nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu + 1]; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; + + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS (bytes): %d\n", dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, dlsch_pdu_rel15->start_symbol, @@ -252,14 +260,18 @@ int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, dlsch_pdu_rel15->nb_layers, dlsch_pdu_rel15->nb_codewords, dlsch_pdu_rel15->mcs_idx, - TBS); + tbs_bytes); + dl_req->number_dci++; dl_req->number_pdsch_rnti++; dl_req->number_pdu+=2; - TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size/8; - TX_req->pdu_index = pdu_index++; - TX_req->num_segments = 1; - return TBS/8; //Return TBS in bytes + + tx_req->pdu_length = tbs_bytes; + tx_req->pdu_index = pdu_index++; + tx_req->num_segments = 1; + //tx_req->segments[0].segment_length = 8; + tx_req->segments[0].segment_length = tbs_bytes + 2; + tx_req->segments[0].segment_data = mac_pdu; } void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, @@ -269,7 +281,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; nfapi_nr_dl_config_request_body_t *dl_req; - nfapi_tx_request_pdu_t *TX_req; + nfapi_tx_request_pdu_t *tx_req; mac_rlc_status_resp_t rlc_status; nfapi_nr_config_request_t *cfg = &gNB_mac->config[0]; @@ -290,10 +302,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, LOG_D(MAC, "Scheduling UE specific search space DCI type 1 for UE_id %d CC_id %d frame %d slot %d\n", UE_id, CC_id, frameP, slotP); dl_req = &gNB_mac->DL_req[CC_id].dl_config_request_body; - TX_req = &gNB_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; + tx_req = &gNB_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; ta_len = gNB_mac->ta_len; - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], gNB_mac->pdu_index[CC_id], dlsch_config); + TBS_bytes = configure_fapi_dl_pdu(dl_req, cfg, &gNB_mac->coreset[CC_id][1], &gNB_mac->search_space[CC_id][1], dlsch_config); //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving //through the LTE stack @@ -310,7 +322,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, }*/ for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { @@ -409,9 +421,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, mac_pdu[offset + j] = 0; } - //TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_length = TBS_bytes + 2; - TX_req->segments[0].segment_data = mac_pdu; + configure_fapi_dl_Tx(dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]); gNB_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; gNB_mac->TX_req[CC_id].sfn_sf = sfn_sf; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 8047c72801..ec41042972 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -89,14 +89,17 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); -int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, - nfapi_tx_request_pdu_t *TX_req, - nfapi_nr_config_request_t *cfg, - nfapi_nr_coreset_t* coreset, - nfapi_nr_search_space_t* search_space, - int16_t pdu_index, +int configure_fapi_dl_pdu(nfapi_nr_dl_config_request_body_t *dl_req, + nfapi_nr_config_request_t *cfg, + nfapi_nr_coreset_t* coreset, + nfapi_nr_search_space_t* search_space, nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config); +void configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, + nfapi_tx_request_pdu_t *tx_req, + int tbs_bytes, + int16_t pdu_index); + void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, From a87220d376123138761731f1825f7a4a3b4f2dfa Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 24 Mar 2019 15:15:57 +0100 Subject: [PATCH 165/343] Add S1AP control module for FlexRAN with status monitoring support --- cmake_targets/CMakeLists.txt | 2 + .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.c | 161 +++++++++++++ .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.h | 69 ++++++ .../S1AP/flexran_agent_s1ap_defs.h | 32 +++ .../ENB_APP/MESSAGES/V2/config_common.proto | 7 - .../ENB_APP/MESSAGES/V2/config_messages.proto | 12 +- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 1 + .../ENB_APP/MESSAGES/V2/stats_common.proto | 12 + .../ENB_APP/MESSAGES/V2/stats_messages.proto | 2 + openair2/ENB_APP/flexran_agent.c | 12 +- openair2/ENB_APP/flexran_agent.h | 1 + openair2/ENB_APP/flexran_agent_common.c | 11 +- openair2/ENB_APP/flexran_agent_defs.h | 1 + openair2/ENB_APP/flexran_agent_extern.h | 4 + openair2/ENB_APP/flexran_agent_handler.c | 11 + openair2/ENB_APP/flexran_agent_ran_api.c | 219 +++++++++++++++++- openair2/ENB_APP/flexran_agent_ran_api.h | 30 ++- openair3/S1AP/s1ap_eNB.c | 8 +- openair3/S1AP/s1ap_eNB_defs.h | 6 + openair3/S1AP/s1ap_eNB_nas_procedures.c | 2 +- 20 files changed, 573 insertions(+), 30 deletions(-) create mode 100644 openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c create mode 100644 openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h create mode 100644 openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap_defs.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f5392acf5d..315510519c 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -923,6 +923,7 @@ include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP") +include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/S1AP") include_directories("${OPENAIR2_DIR}/UTIL/OSA") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc") @@ -1016,6 +1017,7 @@ add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_internal.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c new file mode 100644 index 0000000000..04a47406e1 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c @@ -0,0 +1,161 @@ +/* + * 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 flexran_agent_s1ap.c + * \brief FlexRAN agent Control Module S1AP + * \author Navid Nikaein + * \date 2019 + * \version 0.1 + */ + +#include "flexran_agent_s1ap.h" + + +/*Array containing the Agent-S1AP interfaces*/ +AGENT_S1AP_xface *agent_s1ap_xface[NUM_MAX_ENB]; + +void flexran_agent_fill_s1ap_cell_config(mid_t mod_id, + Protocol__FlexS1apConfig **s1ap_config) { + *s1ap_config = malloc(sizeof(Protocol__FlexS1apConfig)); + if (!*s1ap_config) return; + protocol__flex_s1ap_config__init(*s1ap_config); + LOG_D(FLEXRAN_AGENT, "flexran_agent_fill_s1ap_cell_config %d\n", mod_id); + + // S1AP status + (*s1ap_config)->has_pending = 1; + (*s1ap_config)->pending = flexran_get_s1ap_mme_pending(mod_id); + + (*s1ap_config)->has_connected = 1; + (*s1ap_config)->connected = flexran_get_s1ap_mme_connected(mod_id); + + (*s1ap_config)->enb_s1_ip = flexran_get_s1ap_enb_s1_ip(mod_id); + if (!(*s1ap_config)->enb_s1_ip) + (*s1ap_config)->enb_s1_ip = ""; + + (*s1ap_config)->enb_name = flexran_get_s1ap_enb_name(mod_id); + + (*s1ap_config)->mme = NULL; + (*s1ap_config)->n_mme = flexran_get_s1ap_nb_mme(mod_id); + if ((*s1ap_config)->n_mme > 0) { + Protocol__FlexS1apMme **mme_conf = calloc((*s1ap_config)->n_mme, + sizeof(Protocol__FlexS1apMme *)); + AssertFatal(mme_conf, "%s(): MME malloc failed\n", __func__); + for(int i = 0; i < (*s1ap_config)->n_mme; i++){ + mme_conf[i] = malloc(sizeof(Protocol__FlexS1apMme)); + AssertFatal(mme_conf[i], "%s(): MME malloc failed\n", __func__); + protocol__flex_s1ap_mme__init(mme_conf[i]); + if (flexran_get_s1ap_mme_conf(mod_id, i, mme_conf[i]) < 0) { + LOG_E(FLEXRAN_AGENT, + "error in flexran_get_s1ap_mme_conf(): cannot retrieve MME state\n"); + (*s1ap_config)->n_mme = 0; + break; + } + } + (*s1ap_config)->mme = mme_conf; + } +} + +int flexran_agent_s1ap_stats_reply(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags) { + if (n_ue <= 0) + return 0; + if (!(ue_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_S1AP_STATS)) + return 0; + + for (int i = 0; i < n_ue; i++) { + const rnti_t rnti = ue_report[i]->rnti; + Protocol__FlexS1apUe *ue = malloc(sizeof(Protocol__FlexS1apUe)); + AssertFatal(ue, "%s(): MME malloc failed\n", __func__); + protocol__flex_s1ap_ue__init(ue); + if (flexran_get_s1ap_ue(mod_id, rnti, ue) < 0) { + LOG_E(FLEXRAN_AGENT, "error in %s(): cannot retrieve UE conf\n", __func__); + break; + } + ue_report[i]->s1ap_stats = ue; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_S1AP_STATS; + } + return 0; +} + +void flexran_agent_free_s1ap_cell_config(Protocol__FlexS1apConfig **s1ap) { + for (int i = 0; i < (*s1ap)->n_mme; i++) { + /* following structures allocated in the RAN API */ + for(int j = 0; j < (*s1ap)->mme[i]->n_served_gummeis; j++) { + free((*s1ap)->mme[i]->served_gummeis[j]->plmn); + free((*s1ap)->mme[i]->served_gummeis[j]); + } + free((*s1ap)->mme[i]->served_gummeis); + for (int j = 0; j < (*s1ap)->mme[i]->n_requested_plmns; j++) + free((*s1ap)->mme[i]->requested_plmns[j]); + free((*s1ap)->mme[i]->requested_plmns); + free((*s1ap)->mme[i]); + } + free((*s1ap)->mme); + free(*s1ap); + *s1ap = NULL; +} + +void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply) { + for (int i = 0; i < reply->n_ue_report; ++i) { + if (!reply->ue_report[i]->s1ap_stats) + continue; + free(reply->ue_report[i]->s1ap_stats->selected_plmn); + free(reply->ue_report[i]->s1ap_stats); + reply->ue_report[i]->s1ap_stats = NULL; + } +} + +int flexran_agent_register_s1ap_xface(mid_t mod_id) { + if (agent_s1ap_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id); + return -1; + } + + AGENT_S1AP_xface *xface = malloc(sizeof(AGENT_S1AP_xface)); + if (!xface) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for S1AP agent xface %d\n", mod_id); + return -1; + } + + // not implemented yet + xface->flexran_s1ap_notify_release_request=NULL; + + agent_s1ap_xface[mod_id] = xface; + + return 0; +} + +int flexran_agent_unregister_s1ap_xface(mid_t mod_id) { + if (!agent_s1ap_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "S1AP agent for eNB %d is not registered\n", mod_id); + return -1; + } + agent_s1ap_xface[mod_id]->flexran_s1ap_notify_release_request=NULL; + free(agent_s1ap_xface[mod_id]); + agent_s1ap_xface[mod_id] = NULL; + return 0; +} + +AGENT_S1AP_xface *flexran_agent_get_s1ap_xface(mid_t mod_id) { + return agent_s1ap_xface[mod_id]; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h new file mode 100644 index 0000000000..1cca6ac9c1 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h @@ -0,0 +1,69 @@ +/* + * 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 flexran_agent_s1ap.h + * \brief FlexRAN agent S1AP Control Module + * \author navid nikaein + * \date 2017 + * \version 0.1 + */ + +#ifndef FLEXRAN_AGENT_S1AP_H_ +#define FLEXRAN_AGENT_S1AP_H_ + +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "stats_messages.pb-c.h" +#include "stats_common.pb-c.h" + + +#include "flexran_agent_common.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_s1ap_defs.h" +#include "flexran_agent_ran_api.h" + +/*************************************** + * FlexRAN agent - technology S1AP API * + ***************************************/ + +/* Send to the controller all the S1AP configs */ +void flexran_agent_fill_s1ap_cell_config(mid_t mod_id, + Protocol__FlexS1apConfig **s1ap_config); + +/* Free allocated S1AP cell configs */ +void flexran_agent_free_s1ap_cell_config(Protocol__FlexS1apConfig **s1ap); + +/* Fill the stats message for S1AP */ +int flexran_agent_s1ap_stats_reply(mid_t mod_id, + Protocol__FlexUeStatsReport **ue_report, + int n_ue, + uint32_t ue_flags); + +/* Free allocated S1AP stats message */ +void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply); + +/* Register technology specific interface callbacks */ +int flexran_agent_register_s1ap_xface(mid_t mod_id); + +/* Unregister technology specific callbacks */ +int flexran_agent_unregister_s1ap_xface(mid_t mod_id); + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap_defs.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap_defs.h new file mode 100644 index 0000000000..bbbc75160d --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap_defs.h @@ -0,0 +1,32 @@ +/* + * 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 __FLEXRAN_AGENT_S1AP_PRIMITIVES_H__ +#define __FLEXRAN_AGENT_S1AP_PRIMITIVES_H__ + +#include "flexran_agent_defs.h" + +/* FLEXRAN AGENT-S1AP Interface */ +typedef struct { + // S1AP statistics + void (*flexran_s1ap_notify_release_request)(mid_t mod_id); +} AGENT_S1AP_xface; + +#endif diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index c87e589d89..733d883c92 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -355,13 +355,6 @@ message flex_s1ap_mme { optional uint32 rel_capacity = 6; // Relative MME capacity, TS23.401 } -message flex_s1ap_ue { - optional string mme_s1_ip = 1; // IP of MME to which UE is connected - optional uint32 enb_ue_s1ap_id = 2; // S1AP ID on eNodeB side for UE - optional uint32 mme_ue_s1ap_id = 3; // S1AP ID on MME side for UE - optional flex_plmn selected_plmn = 4; // UE-selected PLMN in RRC Conn Setup Cplt -} - enum flex_mme_state { FLMMES_DISCONNECTED = 0; FLMMES_WAITING = 1; diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 4d8c628c4f..324153613d 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -100,7 +100,6 @@ message flex_ue_config { optional uint32 ul_slice_id = 32; // Configuration about RRC measurements optional flex_measurement_info info = 33; - optional uint32 enb_ue_s1ap_id = 34; // S1AP ID on eNodeB side } message flex_lc_ue_config { @@ -109,10 +108,9 @@ message flex_lc_ue_config { } message flex_s1ap_config { - optional uint32 pending = 1; // number of pending (to be connected) MMEs - optional uint32 connected = 2; // number of connected MMEs - optional string enb_s1_ip = 3; // S1-MME IP of eNodeB - optional string enb_name = 4; // S1-MME name of eNodeB - repeated flex_s1ap_mme mme = 5; - repeated flex_s1ap_ue ue = 6; + optional uint32 pending = 1; // number of pending (to be connected) MMEs + optional uint32 connected = 2; // number of connected MMEs + optional string enb_s1_ip = 3; // S1-MME IP of eNodeB + optional string enb_name = 4; // S1-MME name of eNodeB + repeated flex_s1ap_mme mme = 5; } diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 24a219a564..e2ced1dac7 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -75,6 +75,7 @@ enum flex_bs_capability { PDCP = 5; SDAP = 6; RRC = 7; + S1AP = 8; } enum flex_bs_split { diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index 20f0f60a9f..62bd06d707 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -310,3 +310,15 @@ message flex_gtp_stats { optional uint32 teid_sgw = 4; optional string addr_sgw = 5; } + +// +// S1AP stats +// + +message flex_s1ap_ue { + optional string mme_s1_ip = 1; // IP of MME to which UE is connected + optional uint32 enb_ue_s1ap_id = 2; // S1AP ID on eNodeB side for UE + optional uint32 mme_ue_s1ap_id = 3; // S1AP ID on MME side for UE + optional flex_plmn selected_plmn = 4; // UE-selected PLMN in RRC Conn Setup Cplt +} + diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index 7cceb04a01..6f67648d82 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -51,6 +51,7 @@ message flex_ue_stats_report { optional flex_pdcp_stats pdcp_stats = 11; optional flex_mac_stats mac_stats = 12; repeated flex_gtp_stats gtp_stats = 13; + optional flex_s1ap_ue s1ap_stats = 14; } // @@ -91,6 +92,7 @@ enum flex_ue_stats_type { FLUST_PDCP_STATS = 1024; FLUST_GTP_STATS = 2048; + FLUST_S1AP_STATS = 4096; FLUST_RRC_MEASUREMENTS = 65536; // To be extended with more types of stats diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index a8ee9b98e8..519d2bef4b 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -177,8 +177,8 @@ int flexran_agent_start(mid_t mod_id) /* Register and initialize the control modules depending on capabilities. * After registering, calling flexran_agent_get_*_xface() tells whether a * control module is operational */ - uint16_t caps = flexran_get_capabilities_mask(mod_id); - LOG_I(FLEXRAN_AGENT, "Agent handles BS ID %ld, capabilities=0x%x => handling%s%s%s%s%s%s%s%s\n", + uint32_t caps = flexran_get_capabilities_mask(mod_id); + LOG_I(FLEXRAN_AGENT, "Agent handles BS ID %ld, capabilities=0x%x => handling%s%s%s%s%s%s%s%s%s\n", flexran_get_bs_id(mod_id), caps, FLEXRAN_CAP_LOPHY(caps) ? " LOPHY" : "", FLEXRAN_CAP_HIPHY(caps) ? " HIPHY" : "", @@ -187,7 +187,8 @@ int flexran_agent_start(mid_t mod_id) FLEXRAN_CAP_RLC(caps) ? " RLC" : "", FLEXRAN_CAP_PDCP(caps) ? " PDCP" : "", FLEXRAN_CAP_SDAP(caps) ? " SDAP" : "", - FLEXRAN_CAP_RRC(caps) ? " RRC" : ""); + FLEXRAN_CAP_RRC(caps) ? " RRC" : "", + FLEXRAN_CAP_S1AP(caps) ? " S1AP" : ""); if (FLEXRAN_CAP_LOPHY(caps) || FLEXRAN_CAP_HIPHY(caps)) { flexran_agent_register_phy_xface(mod_id); @@ -210,6 +211,11 @@ int flexran_agent_start(mid_t mod_id) LOG_I(FLEXRAN_AGENT, "registered PDCP interface/CM for eNB %d\n", mod_id); } + if (FLEXRAN_CAP_S1AP(caps)) { + flexran_agent_register_s1ap_xface(mod_id); + LOG_I(FLEXRAN_AGENT, "registered S1AP interface/CM for eNB %d\n", mod_id); + } + /* * initilize a timer */ diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index e50a2be4f6..42295fc111 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -40,6 +40,7 @@ #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" #include "flexran_agent_pdcp.h" +#include "flexran_agent_s1ap.h" #include "common/utils/LOG/log.h" #include "assertions.h" diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index fe65315fe9..ef428b7be5 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -21,7 +21,7 @@ /*! \file flexran_agent_common.c * \brief common primitives for all agents - * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI + * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein * \date 2017 * \version 0.1 */ @@ -38,6 +38,7 @@ #include "flexran_agent_phy.h" #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" +#include "flexran_agent_s1ap.h" //#include "PHY/extern.h" #include "common/utils/LOG/log.h" #include "flexran_agent_mac_internal.h" @@ -339,6 +340,9 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { free(reply->cell_config[i]); } + + if (reply->s1ap) + flexran_agent_free_s1ap_cell_config(&reply->s1ap); free(reply->cell_config); free(reply); @@ -757,9 +761,12 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->carrier_index = i; cell_conf[i]->has_carrier_index = 1; } - + enb_config_reply_msg->cell_config=cell_conf; } + + if (flexran_agent_get_s1ap_xface(mod_id)) + flexran_agent_fill_s1ap_cell_config(mod_id, &enb_config_reply_msg->s1ap); *msg = malloc(sizeof(Protocol__FlexranMessage)); diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 20aac5f56e..bc1976abd9 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -116,6 +116,7 @@ typedef int32_t err_code_t; #define FLEXRAN_CAP_PDCP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)) > 0) #define FLEXRAN_CAP_SDAP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)) > 0) #define FLEXRAN_CAP_RRC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC)) > 0) +#define FLEXRAN_CAP_S1AP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP)) > 0) typedef enum { ENB_NORMAL_OPERATION = 0x0, diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index e1dec8506c..119bc3d44c 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -35,6 +35,7 @@ #include "flexran_agent_mac_defs.h" #include "flexran_agent_rrc_defs.h" #include "flexran_agent_pdcp_defs.h" +#include "flexran_agent_s1ap_defs.h" /* Control module interface for the communication of the PHY control module with the agent */ AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id); @@ -48,6 +49,9 @@ AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id); /* Control module interface for the communication of the RRC Control Module with the agent */ AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id); +/* Control module interface for the communication of the S1AP Control Module with the agent */ +AGENT_S1AP_xface *flexran_agent_get_s1ap_xface(mid_t mod_id); + /* Requried to know which UEs had a harq updated over some subframe */ extern int harq_pid_updated[NUM_MAX_UE][8]; extern int harq_pid_round[NUM_MAX_UE][8]; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 7c251e9172..d991078cf7 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -31,6 +31,7 @@ #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" #include "flexran_agent_pdcp.h" +#include "flexran_agent_s1ap.h" #include "flexran_agent_timer.h" #include "flexran_agent_ran_api.h" #include "common/utils/LOG/log.h" @@ -324,6 +325,14 @@ int flexran_agent_stats_reply(mid_t enb_id, goto error; } + /* S1AP statistics, depends on RRC to find S1AP ID */ + if (flexran_agent_get_rrc_xface(enb_id) + && flexran_agent_get_s1ap_xface(enb_id) + && flexran_agent_s1ap_stats_reply(enb_id, ue_report, n_ue, ue_flags) < 0) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) { goto error; } @@ -523,6 +532,8 @@ int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg) flexran_agent_mac_destroy_stats_reply(msg->stats_reply_msg); flexran_agent_rrc_destroy_stats_reply(msg->stats_reply_msg); flexran_agent_pdcp_destroy_stats_reply(msg->stats_reply_msg); + flexran_agent_rrc_gtp_destroy_stats_reply(msg->stats_reply_msg); + flexran_agent_s1ap_destroy_stats_reply(msg->stats_reply_msg); for (int i = 0; i < msg->stats_reply_msg->n_cell_report; ++i) free(msg->stats_reply_msg->cell_report[i]); for (int i = 0; i < msg->stats_reply_msg->n_ue_report; ++i) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index f479198895..a66081d99f 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -28,6 +28,8 @@ #include #include "flexran_agent_ran_api.h" +#include "s1ap_eNB_ue_context.h" +#include "s1ap_eNB_management_procedures.h" static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) { return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id]; @@ -3002,6 +3004,14 @@ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index) { return ue_context_p->ue_context.e_rab[index].param.gtp_teid; } +uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti) +{ + if (!rrc_is_present(mod_id)) return 0; + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + if (!ue_context_p) return -1; + return ue_context_p->ue_context.eNB_ue_s1ap_id; +} + /**************************** SLICING ****************************/ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; @@ -3470,6 +3480,195 @@ int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; } +/************************** S1AP **************************/ +int flexran_get_s1ap_mme_pending(mid_t mod_id){ + if (!rrc_is_present(mod_id)) return -1; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + return s1ap->s1ap_mme_pending_nb; +} + +int flexran_get_s1ap_mme_connected(mid_t mod_id){ + if (!rrc_is_present(mod_id)) return -1; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + return s1ap->s1ap_mme_associated_nb; +} + +char* flexran_get_s1ap_enb_s1_ip(mid_t mod_id){ + if (!rrc_is_present(mod_id)) return NULL; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return NULL; + if (s1ap->eNB_s1_ip.ipv4) + return &s1ap->eNB_s1_ip.ipv4_address[0]; + if (s1ap->eNB_s1_ip.ipv6) + return &s1ap->eNB_s1_ip.ipv6_address[0]; + return NULL; +} + +char* flexran_get_s1ap_enb_name(mid_t mod_id){ + if (!rrc_is_present(mod_id)) return NULL; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return NULL; + return s1ap->eNB_name; +} + +int flexran_get_s1ap_nb_mme(mid_t mod_id) { + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return 0; + struct s1ap_eNB_mme_data_s *mme = NULL; + int count = 0; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + count++; + } + return count; +} + +int flexran_get_s1ap_nb_ue(mid_t mod_id) { + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return 0; + struct s1ap_eNB_ue_context_s *ue = NULL; + int count = 0; + RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head) { + count++; + } + return count; +} + +int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apMme * mme_conf){ + if (!rrc_is_present(mod_id)) return -1; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + + struct served_gummei_s *gummei_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + struct served_group_id_s *group_id_p = NULL; + struct mme_code_s *mme_code_p = NULL; + int i = 0; + Protocol__FlexGummei **served_gummeis; + Protocol__FlexPlmn **requested_plmns; + + struct s1ap_eNB_mme_data_s *mme = NULL; + + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head){ + if (mme_index == 0) break; + mme_index--; + } + if (mme_index > 0) return -1; + + if (mme->mme_s1_ip.ipv4) { + mme_conf->s1_ip = (char*) &mme->mme_s1_ip.ipv4_address[0]; + } else if (mme->mme_s1_ip.ipv6) { + mme_conf->s1_ip = (char*) &mme->mme_s1_ip.ipv6_address[0]; + } + mme_conf->name = mme->mme_name; + mme_conf->has_state = 1; + mme_conf->state = mme->state; + + mme_conf->n_served_gummeis = 0; + STAILQ_FOREACH(gummei_p, &mme->served_gummei, next) { + mme_conf->n_served_gummeis++; + } + if (mme_conf->n_served_gummeis > 0) { + served_gummeis = calloc(mme_conf->n_served_gummeis, sizeof(Protocol__FlexGummei*)); + if(served_gummeis == NULL) return -1; + + STAILQ_FOREACH(gummei_p, &mme->served_gummei, next) { + served_plmn_p = STAILQ_FIRST(&gummei_p->served_plmns); + group_id_p = STAILQ_FIRST(&gummei_p->served_group_ids); + mme_code_p = STAILQ_FIRST(&gummei_p->mme_codes); + + served_gummeis[i] = malloc(sizeof(Protocol__FlexGummei)); + if (!served_gummeis[i]) return -1; + protocol__flex_gummei__init(served_gummeis[i]); + served_gummeis[i]->plmn = malloc(sizeof(Protocol__FlexPlmn)); + if (!served_gummeis[i]->plmn) return -1; + protocol__flex_plmn__init(served_gummeis[i]->plmn); + + if (served_plmn_p) { + served_gummeis[i]->plmn->has_mcc = 1; + served_gummeis[i]->plmn->mcc = served_plmn_p->mcc; + served_gummeis[i]->plmn->has_mnc = 1; + served_gummeis[i]->plmn->mnc = served_plmn_p->mnc; + served_gummeis[i]->plmn->has_mnc_length = 1; + served_gummeis[i]->plmn->mnc_length = served_plmn_p-> mnc_digit_length; + STAILQ_NEXT(served_plmn_p, next); + } + if (group_id_p) { + served_gummeis[i]->has_mme_group_id = 1; + served_gummeis[i]->mme_group_id = group_id_p->mme_group_id; + STAILQ_NEXT(group_id_p, next); + } + if (mme_code_p){ + served_gummeis[i]->has_mme_code = 1; + served_gummeis[i]->mme_code = mme_code_p->mme_code; + STAILQ_NEXT(mme_code_p, next); + } + i++; + } + + mme_conf->served_gummeis = served_gummeis; + } + + // requested PLMNS + mme_conf->n_requested_plmns = mme->broadcast_plmn_num; + if (mme_conf->n_requested_plmns > 0){ + requested_plmns = calloc(mme_conf->n_requested_plmns, sizeof(Protocol__FlexPlmn*)); + if(requested_plmns == NULL) return -1; + for(int i = 0; i < mme_conf->n_requested_plmns; i++) { + requested_plmns[i] = malloc(sizeof(Protocol__FlexPlmn)); + if (!requested_plmns[i]) return -1; + protocol__flex_plmn__init(requested_plmns[i]); + requested_plmns[i]->mcc = s1ap->mcc[mme->broadcast_plmn_index[i]]; + requested_plmns[i]->has_mcc = 1; + requested_plmns[i]->mnc = s1ap->mnc[mme->broadcast_plmn_index[i]]; + requested_plmns[i]->has_mnc = 1; + requested_plmns[i]->mnc_length = s1ap->mnc_digit_length[mme->broadcast_plmn_index[i]]; + requested_plmns[i]->has_mnc_length = 1; + } + mme_conf->requested_plmns = requested_plmns; + } + + mme_conf->has_rel_capacity = 1; + mme_conf->rel_capacity = mme->relative_mme_capacity; + return 0; +} + +int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){ + if (!rrc_is_present(mod_id)) return -1; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + + uint32_t enb_ue_s1ap_id = flexran_get_rrc_enb_ue_s1ap_id(mod_id, rnti); + struct s1ap_eNB_ue_context_s *ue = NULL; + RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){ + if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break; + } + if (ue == NULL) return -1; + + if (ue->mme_ref->mme_s1_ip.ipv4) + ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0]; + else if (ue->mme_ref->mme_s1_ip.ipv6) + ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv6_address[0]; + + ue_conf->has_enb_ue_s1ap_id = 1; + ue_conf->enb_ue_s1ap_id = ue->eNB_ue_s1ap_id; + ue_conf->has_mme_ue_s1ap_id = 1; + ue_conf->mme_ue_s1ap_id = ue->mme_ue_s1ap_id; + + ue_conf->selected_plmn = malloc(sizeof(Protocol__FlexPlmn)); + if (!ue_conf->selected_plmn) return -1; + protocol__flex_plmn__init(ue_conf->selected_plmn); + + ue_conf->selected_plmn->has_mcc = 1; + ue_conf->selected_plmn->mcc = s1ap->mcc[ue->selected_plmn_identity]; + ue_conf->selected_plmn->has_mnc = 1; + ue_conf->selected_plmn->mnc = s1ap->mnc[ue->selected_plmn_identity]; + ue_conf->selected_plmn->has_mnc_length = 1; + ue_conf->selected_plmn->mnc_length = s1ap->mnc_digit_length[ue->selected_plmn_identity]; + return 0; +} + /**************************** General BS info ****************************/ uint64_t flexran_get_bs_id(mid_t mod_id) { if (!rrc_is_present(mod_id)) return 0; @@ -3488,13 +3687,14 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) case ngran_eNB_CU: case ngran_ng_eNB_CU: case ngran_gNB_CU: - n_caps = 3; + n_caps = 4; *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", n_caps * sizeof(Protocol__FlexBsCapability)); (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP; (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; + (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__S1AP; break; case ngran_eNB_DU: case ngran_gNB_DU: @@ -3511,7 +3711,7 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) case ngran_eNB: case ngran_ng_eNB: case ngran_gNB: - n_caps = 8; + n_caps = 9; *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", n_caps * sizeof(Protocol__FlexBsCapability)); @@ -3523,26 +3723,27 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) (*caps)[5] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP; (*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; (*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; + (*caps)[8] = PROTOCOL__FLEX_BS_CAPABILITY__S1AP; break; case ngran_eNB_MBMS_STA: + AssertFatal(0, "MBMS STA not supported by FlexRAN!\n"); break; } return n_caps; } -uint16_t flexran_get_capabilities_mask(mid_t mod_id) { +uint32_t flexran_get_capabilities_mask(mid_t mod_id) { if (!rrc_is_present(mod_id)) return 0; - - uint16_t mask = 0; - + uint32_t mask = 0; switch (RC.rrc[mod_id]->node_type) { case ngran_eNB_CU: case ngran_ng_eNB_CU: case ngran_gNB_CU: mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP) | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC); + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP); break; case ngran_eNB_DU: case ngran_gNB_DU: @@ -3562,9 +3763,11 @@ uint16_t flexran_get_capabilities_mask(mid_t mod_id) { | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC) | (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP) | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC); + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP); break; case ngran_eNB_MBMS_STA: + AssertFatal(0, "MBMS STA not supported by FlexRAN!\n"); break; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 6aef1c406b..ce32883852 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -652,6 +652,9 @@ int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index); /* Get the TEID at the SGW for UE */ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index); +/* gets the UEs S1AP ID at eNodeB, stored in RRC */ +uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti); + /************************** Slice configuration **************************/ /* Get the DL slice ID for a UE */ @@ -804,6 +807,31 @@ char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx); /* Set the scheduler name for a slice in UL */ int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name); +/************************** S1AP **************************/ +/* Get the number of MMEs to be connected */ +int flexran_get_s1ap_mme_pending(mid_t mod_id); + +/* Get the number of connected MMEs */ +int flexran_get_s1ap_mme_connected(mid_t mod_id); + +/* Get the eNB S1AP IP address */ +char* flexran_get_s1ap_enb_s1_ip(mid_t mod_id); + +/* Get the name of the eNB */ +char* flexran_get_s1ap_enb_name(mid_t mod_id); + +/* Get the number of connected MMEs to this eNB */ +int flexran_get_s1ap_nb_mme(mid_t mod_id); + +/* Get the number of connected UEs to this eNB */ +int flexran_get_s1ap_nb_ue(mid_t mod_id); + +/* Get the S1AP MME conf */ +int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apMme * mme_conf); + +/* Get the S1AP UE conf */ +int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf); + /********************* general information *****************/ /* get an ID for this BS (or part of a BS) */ uint64_t flexran_get_bs_id(mid_t mod_id); @@ -815,7 +843,7 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) /* get the capabilities supported by the underlying network function as a bit * mask. */ -uint16_t flexran_get_capabilities_mask(mid_t mod_id); +uint32_t flexran_get_capabilities_mask(mid_t mod_id); /* get the splits used by the underlying network function, * return the number and stores list of this length in splits. If there are diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 03e6273d1b..3592cf80a1 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -124,7 +124,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; s1ap_mme_data_p->assoc_id = -1; s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num; - + memcpy(&s1ap_mme_data_p->mme_s1_ip, + mme_ip_address, + sizeof(*mme_ip_address)); for (int i = 0; i < broadcast_plmn_num; ++i) s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; @@ -193,6 +195,10 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->eNB_id = s1ap_register_eNB->eNB_id; new_instance->cell_type = s1ap_register_eNB->cell_type; new_instance->tac = s1ap_register_eNB->tac; + + memcpy(&new_instance->eNB_s1_ip, + &s1ap_register_eNB->enb_ip_address, + sizeof(s1ap_register_eNB->enb_ip_address)); for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) { new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index 5bffa0df0c..d4bc6cfc0f 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -124,6 +124,9 @@ typedef struct s1ap_eNB_mme_data_s { /* This is the optional name provided by the MME */ char *mme_name; + /* MME S1AP IP address */ + net_ip_address_t mme_s1_ip; + /* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max * number of 8 RATs but in our case only one is used. The LTE related pool * configuration is included on the first place in the list. @@ -200,6 +203,9 @@ typedef struct s1ap_eNB_instance_s { /* Tracking area code */ uint16_t tac; + /* eNB S1AP IP address */ + net_ip_address_t eNB_s1_ip; + /* Mobile Country Code * Mobile Network Code */ diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index b87bd7144a..d271ddf6ba 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -1468,7 +1468,7 @@ int s1ap_eNB_path_switch_req(instance_t instance, break; } } while(1); - + ue_context_p->mme_ue_s1ap_id = path_switch_req_p->mme_ue_s1ap_id; /* Prepare the S1AP message to encode */ From c6e389ed4cb4a8b9db8ed6ead401ef798aa31823 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Dec 2019 10:13:16 +0100 Subject: [PATCH 166/343] FlexRAN: assert if out of memory --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 1a8c2cefa8..c489f10dae 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -693,8 +693,7 @@ int flexran_agent_mac_stats_reply_cell(mid_t mod_id, // TODO: Fill in the actual noise and interference report for this cell Protocol__FlexNoiseInterferenceReport *ni_report; ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); - if(ni_report == NULL) - goto error; + AssertFatal(ni_report, "cannot malloc() ni_report\n"); protocol__flex_noise_interference_report__init(ni_report); ni_report->sfn_sf = flexran_get_sfn_sf(mod_id); ni_report->has_sfn_sf = 1; @@ -709,21 +708,6 @@ int flexran_agent_mac_stats_reply_cell(mid_t mod_id, } } return 0; - - error: - if (cell_report != NULL) { - if (n_cc > 0) { - for (int i = 0; i < n_cc; i++) { - if (cell_report[i]->noise_inter_report != NULL) { - free(cell_report[i]->noise_inter_report); - cell_report[i]->noise_inter_report = NULL; - } - } - } - free(cell_report); - cell_report = NULL; - } - return -1; } int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply) { From e33be3ccd3ec44b0cb20c6209fbc3bdb43e69b3c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 18 Dec 2019 16:37:54 +0100 Subject: [PATCH 167/343] FlexRAN: Re-enable the soft-restart, it works --- openair2/ENB_APP/flexran_agent_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index ef428b7be5..50900d451d 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -905,8 +905,11 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); - //} else { - // initiate_soft_restart(mod_id, enb_config->cell_config[0]); + } else if (enb_config->cell_config[0]->has_eutra_band + && enb_config->cell_config[0]->has_dl_freq + && enb_config->cell_config[0]->has_ul_freq + && enb_config->cell_config[0]->has_dl_bandwidth) { + initiate_soft_restart(mod_id, enb_config->cell_config[0]); } if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->has_x2_ho_net_control) { From 1c8c839f65adfd12ecd53d25d34f64c56a1d7440 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Dec 2019 11:34:25 +0100 Subject: [PATCH 168/343] FlexRAN: Reformat code for X2 HO NetControl activation --- openair2/ENB_APP/flexran_agent_common.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 50900d451d..dc320ef974 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -910,12 +910,14 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot && enb_config->cell_config[0]->has_ul_freq && enb_config->cell_config[0]->has_dl_bandwidth) { initiate_soft_restart(mod_id, enb_config->cell_config[0]); - } - - if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->has_x2_ho_net_control) { - if (flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control) < 0) { + } else if (flexran_agent_get_rrc_xface(mod_id) + && enb_config->cell_config[0]->has_x2_ho_net_control) { + LOG_I(FLEXRAN_AGENT, + "setting X2 HO NetControl to %d\n", + enb_config->cell_config[0]->x2_ho_net_control); + const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control); + if (rc < 0) LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); - } } *msg = NULL; From dabe2ae7ab5e4939620a7dff15eb2dd102437b79 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 20 Jan 2020 14:02:55 +0100 Subject: [PATCH 169/343] FlexRAN: remove unused import in protocol def --- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index e2ced1dac7..3b47ff263b 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -6,7 +6,6 @@ import "header.proto"; import "time_common.proto"; import "config_messages.proto"; import "controller_commands.proto"; -import "control_delegation.proto"; import "config_common.proto"; message flexran_message { From 5b5a25a93274c5f5cd54f0385eff5cc9f61ca157 Mon Sep 17 00:00:00 2001 From: matzakos Date: Mon, 20 Jan 2020 17:55:16 +0100 Subject: [PATCH 170/343] nr-ip noS1 uplink integration (testing with RFSIMULATOR only): Uplink IP packets received at the gNB and reaching at pdcp layer. Asserion error at pdcp_fifo_flush_sdus when trying to write on the nas socket --- executables/nr-uesoftmodem.c | 1 + openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 15 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 3 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 58 +- openair1/SCHED_NR/fapi_nr_l1.h | 2 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 71 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 10 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 1 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 620 ++++++++++++++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 208 ++++++ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 11 + openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 1 + openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 6 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 6 +- 15 files changed, 975 insertions(+), 42 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 7e2ffebb35..0438e4df21 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -124,6 +124,7 @@ int threequarter_fs=0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +//int32_t uplink_counter = 0; extern int16_t nr_dlsch_demod_shift; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index db0c601b25..1d3e62714b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -593,16 +593,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, p_procTime); if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - #ifdef PRINT_CRC_CHECK + //#ifdef PRINT_CRC_CHECK //if (prnt_crc_cnt % 10 == 0) LOG_I(PHY, "Segment %d CRC OK\n",r); - #endif + //#endif ret = no_iteration_ldpc; } else { - #ifdef PRINT_CRC_CHECK + //#ifdef PRINT_CRC_CHECK //if (prnt_crc_cnt%10 == 0) LOG_I(PHY, "CRC NOK\n"); - #endif + //#endif ret = ulsch->max_ldpc_iterations + 1; } @@ -719,6 +719,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } + LOG_I(PHY, "output encoder: \n"); + for (i = 0; i < harq_process->TBS / 8; i++) { + //harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + printf("0x%02x",harq_process->b[i]); + } + ulsch->last_iteration_cnt = ret; return(ret); 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..513ce6cc20 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1076,8 +1076,9 @@ void nr_pusch_codeword_scrambling(uint8_t *in, - transform precoding */ -void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, +uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned char harq_pid, + uint8_t frame, uint8_t slot, uint8_t thread_id, int gNB_id); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index d2dbd6fef2..a5c747bbba 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -41,10 +41,13 @@ #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" #include "PHY/defs_nr_common.h" #include "PHY/TOOLS/tools_defs.h" +#include "executables/nr-softmodem.h" //#define DEBUG_SCFDMA //#define DEBUG_PUSCH_MAPPING +//extern int32_t uplink_counter; + void nr_pusch_codeword_scrambling(uint8_t *in, uint32_t size, uint32_t Nid, @@ -84,8 +87,9 @@ void nr_pusch_codeword_scrambling(uint8_t *in, } -void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, +uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned char harq_pid, + uint8_t frame, uint8_t slot, uint8_t thread_id, int gNB_id) { @@ -104,11 +108,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int ap, start_symbol, Nid_cell, i; int sample_offsetF, N_RE_prime, N_PRB_oh; uint16_t n_rnti; + uint8_t data_existing =0; NR_UE_ULSCH_t *ulsch_ue; NR_UL_UE_HARQ_t *harq_process_ul_ue; NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; + uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; num_of_codewords = 1; // tmp assumption length_dmrs = 1; @@ -141,17 +147,41 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, 0, harq_process_ul_ue->Nl); + uint8_t access_mode = SCHEDULED_ACCESS; + //-----------------------------------------------------// // to be removed later when MAC is ready if (harq_process_ul_ue != NULL){ - for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { - harq_process_ul_ue->a[i] = (unsigned char) rand(); - //printf("input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - } + + if (IS_SOFTMODEM_NOS1){ + data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame, + slot, 0, ulsch_input_buffer, harq_process_ul_ue->TBS/8, &access_mode); + if(data_existing){ + //harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char)); + memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8); + LOG_I(PHY, "input encoder: \n"); + for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { + //harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + //printf("0x%02x",harq_process_ul_ue->a[i]); + printf("0x%02x",harq_process_ul_ue->b[i]); + } + } + } + //else if(uplink_counter == 0){ //if(!IS_SOFTMODEM_NOS1){ + else{ + LOG_E(PHY, "Random data to be tranmsitted: \n"); + for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { + harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } + data_existing = 1; + //uplink_counter++; + } } else { LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); - return; + return 0; } //-----------------------------------------------------// @@ -159,6 +189,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH coding///////////////////////// /////////// + + //if(data_existing){ nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid); /////////// @@ -203,8 +235,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, //////////////////////////////////////////////////////////////////////// + //} } + //if(data_existing){ start_symbol = 14 - harq_process_ul_ue->number_of_symbols; /////////////////////////DMRS Modulation///////////////////////// @@ -335,10 +369,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } } + //} + /////////// //////////////////////////////////////////////////////////////////////// - return; + LOG_I(PHY, "Is data existing ?: %d \n", data_existing); + return data_existing; } @@ -369,6 +406,13 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, if (tx_offset < 0) tx_offset += frame_parms->samples_per_frame; + // clear the transmit data array for the current subframe + /*for (int aa=0; aaframe_parms.nb_antennas_tx; aa++) { + memset(&UE->common_vars.txdata[aa][tx_offset],0,UE->frame_parms.samples_per_slot*sizeof(int32_t)); + //memset(&UE->common_vars.txdataF[aa][tx_offset],0,UE->frame_parms.samples_per_slot*sizeof(int32_t)); + }*/ + + txdata = UE->common_vars.txdata; txdataF = UE->common_vars.txdataF; diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index 51169660bf..4a4aeb796b 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -46,3 +46,5 @@ void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, uint8_t *sdu); void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid); + +void nr_fill_crc_indication (PHY_VARS_gNB *gNB, int UE_id, int frame, int slot_rx, uint8_t crc_flag); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a665a14112..a849e3c2d9 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -260,8 +260,12 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id if (ret > gNB->ulsch[UE_id][0]->max_ldpc_iterations) LOG_I(PHY, "ULSCH in error\n"); - else - LOG_I(PHY, "ULSCH received ok\n"); + //gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b + else if(gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b!=NULL){ + LOG_I(PHY, "ULSCH received ok, number of iterations: %d \n", ret); + nr_fill_crc_indication (gNB, UE_id, frame_rx, slot_rx, 0); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); + } } @@ -272,25 +276,28 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // [hna] TO BE CLEANED // -------------------- - // nfapi_rx_indication_pdu_t *pdu; + nfapi_rx_indication_pdu_t *pdu; int timing_advance_update; int sync_pos; - // pthread_mutex_lock(&gNB->UL_INFO_mutex); + NR_gNB_ULSCH_t *ulsch = gNB->ulsch[UE_id][0]; + NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; - // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; - // gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + pthread_mutex_lock(&gNB->UL_INFO_mutex); - // pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; + gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; + gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; - // pdu->rx_ue_information.handle = gNB->ulsch[UE_id+1][0]->handle; - // pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - // pdu->rx_ue_information.rnti = gNB->ulsch[UE_id+1][0]->rnti; - // pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; - // pdu->rx_indication_rel8.length = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->TBS>>3; - // pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - // pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; + pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; + + //pdu->rx_ue_information.handle = gNB->ulsch[UE_id+1][0]->handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = gNB->ulsch[UE_id][0]->rnti; + pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; + pdu->rx_indication_rel8.length = gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->TBS>>3; + pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation + pdu->data = harq_process->b;//gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; // estimate timing advance for MAC sync_pos = nr_est_timing_advance_pusch(gNB, UE_id); timing_advance_update = sync_pos; // - gNB->frame_parms.nb_prefix_samples/4; //to check @@ -314,23 +321,40 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, if (timing_advance_update < 0) timing_advance_update = 0; if (timing_advance_update > 63) timing_advance_update = 63; - // pdu->rx_indication_rel8.timing_advance = timing_advance_update; + pdu->rx_indication_rel8.timing_advance = timing_advance_update; // estimate UL_CQI for MAC (from antenna port 0 only) - // int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]); + int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]); - // if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0; - // else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255; - // else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5; + if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0; + else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255; + else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5; // LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n", // harq_pid,frame,slot_rx,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, // timing_advance_update); - // gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; - // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | slot_rx; + gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; + gNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | slot_rx; - // pthread_mutex_unlock(&gNB->UL_INFO_mutex); + pthread_mutex_unlock(&gNB->UL_INFO_mutex); +} + +void nr_fill_crc_indication (PHY_VARS_gNB *gNB, int UE_id, int frame, int slot_rx, uint8_t crc_flag) { + pthread_mutex_lock(&gNB->UL_INFO_mutex); + nfapi_crc_indication_pdu_t *pdu = &gNB->UL_INFO. crc_ind.crc_indication_body.crc_pdu_list[gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; + gNB->UL_INFO.crc_ind.sfn_sf = frame<<4 | slot_rx; + gNB->UL_INFO.crc_ind.header.message_id = NFAPI_CRC_INDICATION; + gNB->UL_INFO.crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdu->rx_ue_information.rnti = gNB->ulsch[UE_id][0]->rnti; + pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; + pdu->crc_indication_rel8.crc_flag = crc_flag; + gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs++; + //LOG_D(PHY, "%s() rnti:%04x crcs:%d crc_flag:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, crc_flag); + pthread_mutex_unlock(&gNB->UL_INFO_mutex); } @@ -382,7 +406,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[UE_id]->rxdataF_comp[0],6900,1,1); //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[UE_id]->rxdataF_ext[0],6900,1,1); nr_ulsch_procedures(gNB, frame_rx, slot_rx, UE_id, harq_pid); - nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); // indicate SDU to MAC + /*nr_fill_crc_indication (gNB, UE_id, frame_rx, slot_rx, 1); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); // indicate SDU to MAC*/ } } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 60378d81fc..96c4e837ab 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2481,9 +2481,11 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, #endif uint8_t harq_pid = 0; //temporary implementation + uint8_t data_existing = 0; - nr_ue_ulsch_procedures(ue, + data_existing = nr_ue_ulsch_procedures(ue, harq_pid, + frame_tx, slot_tx, thread_id, gNB_id); @@ -2498,13 +2500,15 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } // UE_mode==PUSCH */ - - nr_ue_pusch_common_procedures(ue, + //if(data_existing){ + LOG_I(PHY, "Sending data \n"); + nr_ue_pusch_common_procedures(ue, harq_pid, slot_tx, thread_id, gNB_id, &ue->frame_parms); + //} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index e3b74d388c..af7aa43fcc 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -945,6 +945,7 @@ rx_sdu(const module_id_t enb_mod_idP, stop_meas(&mac->rx_ulsch_sdu); } + //----------------------------------------------------------------------------- /* * Return the BSR table index corresponding to the number of bytes in input diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 98389ddcfd..c33d624469 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -136,5 +136,9 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, void nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP, uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index); +uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode); + #endif /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index ef94d5db7e..c0c8a9ec24 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -37,6 +37,8 @@ #include "PHY/defs_nr_UE.h" #include "common/utils/LOG/log.h" #include "openair2/LAYER2/MAC/mac.h" +#include "openair2/LAYER2/RLC/rlc.h" +#include "SIMULATION/TOOLS/sim.h" // for taus #include #include @@ -2317,7 +2319,287 @@ unsigned char *parse_header(unsigned char *mac_header, return (mac_header_ptr); } +unsigned char +generate_ulsch_header(uint8_t *mac_header, + uint8_t num_sdus, + uint8_t short_padding, + uint16_t *sdu_lengths, + uint8_t *sdu_lcids, + POWER_HEADROOM_CMD *power_headroom, + uint16_t *crnti, + BSR_SHORT *truncated_bsr, + BSR_SHORT *short_bsr, + BSR_LONG *long_bsr, unsigned short post_padding) { + SCH_SUBHEADER_FIXED *mac_header_ptr = + (SCH_SUBHEADER_FIXED *) mac_header; + unsigned char first_element = 0, last_size = 0, i; + unsigned char mac_header_control_elements[16], *ce_ptr; + LOG_D(MAC, "[UE] Generate ULSCH : num_sdus %d\n", num_sdus); +#ifdef DEBUG_HEADER_PARSING + for (i = 0; i < num_sdus; i++) { + LOG_T(MAC, "[UE] sdu %d : lcid %d length %d", i, sdu_lcids[i], + sdu_lengths[i]); + } + + LOG_T(MAC, "\n"); +#endif + ce_ptr = &mac_header_control_elements[0]; + + if ((short_padding == 1) || (short_padding == 2)) { + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + first_element = 1; + last_size = 1; + } + + if (short_padding == 2) { + mac_header_ptr->E = 1; + mac_header_ptr++; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + last_size = 1; + } + + if (power_headroom) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; + } + + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = POWER_HEADROOM; + last_size = 1; + *((POWER_HEADROOM_CMD *) ce_ptr) = (*power_headroom); + ce_ptr += sizeof(POWER_HEADROOM_CMD); + LOG_D(MAC, "phr header size %zu\n", sizeof(POWER_HEADROOM_CMD)); + } + + if (crnti) { +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] CRNTI : %x (first_element %d)\n", *crnti, + first_element); +#endif + + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; + } + + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = CRNTI; + last_size = 1; + *((uint16_t *) ce_ptr) = (*crnti); + ce_ptr += sizeof(uint16_t); + // printf("offset %d\n",ce_ptr-mac_header_control_elements); + } + + if (truncated_bsr) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; + } + +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] Scheduler Truncated BSR Header\n"); +#endif + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = TRUNCATED_BSR; + last_size = 1; + *((BSR_TRUNCATED *) ce_ptr) = (*truncated_bsr); + ce_ptr += sizeof(BSR_TRUNCATED); + // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } else if (short_bsr) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; + } + +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] Scheduler SHORT BSR Header\n"); +#endif + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_BSR; + last_size = 1; + *((BSR_SHORT *) ce_ptr) = (*short_bsr); + ce_ptr += sizeof(BSR_SHORT); + // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } else if (long_bsr) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; + } + +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] Scheduler Long BSR Header\n"); +#endif + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = LONG_BSR; + last_size = 1; + *(ce_ptr) = + (long_bsr-> + Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4); + *(ce_ptr + 1) = + ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr-> + Buffer_size2 & 0x3C) + >> 2); + *(ce_ptr + 2) = + ((long_bsr-> + Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F); + ce_ptr += BSR_LONG_SIZE; + // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } + + // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + + for (i = 0; i < num_sdus; i++) { +#ifdef DEBUG_HEADER_PARSING + LOG_T(MAC, "[UE] sdu subheader %d (lcid %d, %d bytes)\n", i, + sdu_lcids[i], sdu_lengths[i]); +#endif + + if ((i == (num_sdus - 1)) + && ((short_padding) || (post_padding == 0))) { + if (first_element > 0) { + mac_header_ptr->E = 1; +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", + *(unsigned char *) mac_header_ptr, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); +#endif + mac_header_ptr += last_size; + } + + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = sdu_lcids[i]; + } else { + if ((first_element > 0)) { + mac_header_ptr->E = 1; +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", + *(unsigned char *) mac_header_ptr, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); +#endif + mac_header_ptr += last_size; + // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + } else { + first_element = 1; + } + + if (sdu_lengths[i] < 128) { + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; // 3 + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = + sdu_lcids[i]; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = + (unsigned char) sdu_lengths[i]; + last_size = 2; +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] short sdu\n"); + LOG_T(MAC, + "[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n", + ((uint16_t *) mac_header_ptr)[0], + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L); +#endif + } else { + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = + sdu_lcids[i]; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = + ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = + (unsigned short) sdu_lengths[i] & 0xff; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; + last_size = 3; +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] long sdu\n"); +#endif + } + } + } + + if (post_padding > 0) { // we have lots of padding at the end of the packet + mac_header_ptr->E = 1; + mac_header_ptr += last_size; + // add a padding element + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + mac_header_ptr++; + } else { // no end of packet padding + // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) + mac_header_ptr++; + //mac_header_ptr=last_size; // FIXME: should be ++ + } + + if ((ce_ptr - mac_header_control_elements) > 0) { + memcpy((void *) mac_header_ptr, mac_header_control_elements, + ce_ptr - mac_header_control_elements); + mac_header_ptr += + (unsigned char) (ce_ptr - mac_header_control_elements); + } + +#ifdef DEBUG_HEADER_PARSING + LOG_T(MAC, " [UE] header : "); + + for (i = 0; i < ((unsigned char *) mac_header_ptr - mac_header); i++) { + LOG_T(MAC, "%2x.", mac_header[i]); + } + + LOG_T(MAC, "\n"); +#endif + return ((unsigned char *) mac_header_ptr - mac_header); +} + + +/* LTE based function to be substituted once NR version is ready */ //------------------------------------------------------------------------------ void nr_ue_send_sdu(module_id_t module_idP, @@ -2413,5 +2695,343 @@ nr_ue_send_sdu(module_id_t module_idP, } +/* LTE based function to be substituted once NR version is ready */ +uint8_t +nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) + +{ + uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; + uint16_t buflen_remain = 0; + uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; + uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; + uint8_t lcid = 0, lcid_rlc_pdu_count = 0; + boolean_t is_lcid_processed = FALSE; + boolean_t is_all_lcid_processed = FALSE; + uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t payload_offset = 0, num_sdus = 0; + uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; + uint16_t sdu_length_total = 0; + BSR_SHORT bsr_short, bsr_truncated; + BSR_LONG bsr_long; + BSR_SHORT *bsr_s = &bsr_short; + BSR_LONG *bsr_l = &bsr_long; + BSR_SHORT *bsr_t = &bsr_truncated; + POWER_HEADROOM_CMD phr; + POWER_HEADROOM_CMD *phr_p = &phr; + unsigned short short_padding = 0, post_padding = 0, padding_len = 0; + int j; // used for padding + // Compute header length + int lcg_id = 0; + int lcg_id_bsr_trunc = 0; + int highest_priority = 16; + int num_lcg_id_with_data = 0; + rlc_buffer_occupancy_t lcid_buffer_occupancy_old = + 0, lcid_buffer_occupancy_new = 0; + + NR_UE_MAC_INST_t *nr_ue_mac_inst = get_mac_inst(0); + + + LOG_D(MAC, + "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", + module_idP, frameP, subframe, buflen); + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + + bsr_header_len = 0; + phr_header_len = 0; // 1; //sizeof(SCH_SUBHEADER_FIXED); + + rlc_buffer_occupancy_t buffer_occupancy = mac_rlc_get_buffer_occupancy_ind( module_idP, 0x1234, eNB_index, frameP, subframe,ENB_FLAG_NO,DTCH); + + // Check for DCCH first + // TO DO: Multiplex in the order defined by the logical channel prioritization + for (lcid = DTCH; + (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE); lcid++) { + lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind( module_idP, 0x1234, eNB_index, frameP, subframe,ENB_FLAG_NO,lcid); + if (lcid_buffer_occupancy_old > 0) { + lcid_rlc_pdu_count = 0; + is_lcid_processed = FALSE; + + lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; + + + //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data + //Adjust at the end of the loop + while ((!is_lcid_processed) && (lcid_buffer_occupancy_new) + && (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) { + + buflen_remain = + buflen - (bsr_len + phr_len + + total_rlc_pdu_header_len + sdu_length_total + + 1); + LOG_I(MAC, + "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " + "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", + module_idP, frameP, lcid, lcid_buffer_occupancy_new, + buflen, bsr_len, phr_len, sdu_length_total, + total_rlc_pdu_header_len); + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + 0x1234, eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + lcid, + buflen_remain, + (char *)&ulsch_buff[sdu_length_total],0, + 0 + ); + AssertFatal(buflen_remain >= sdu_lengths[num_sdus], + "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", + lcid, sdu_lengths[num_sdus], buflen_remain); + + 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); + + if (buflen == + (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1)) { + //No more remaining TBS after this PDU + //exit the function + rlc_pdu_header_len_last = 1; + is_lcid_processed = TRUE; + is_all_lcid_processed = TRUE; + } else { + rlc_pdu_header_len_last = + (sdu_lengths[num_sdus] > 128) ? 3 : 2; + + //Change to 1 byte if it does not fit in the TBS, ie last PDU + if (buflen <= + (bsr_len + phr_len + total_rlc_pdu_header_len + + rlc_pdu_header_len_last + sdu_length_total)) { + rlc_pdu_header_len_last = 1; + is_lcid_processed = TRUE; + is_all_lcid_processed = TRUE; + } + } + + //Update number of SDU + num_sdus++; + //Update total MAC Header size for RLC PDUs and save last one + total_rlc_pdu_header_len += rlc_pdu_header_len_last; + lcid_rlc_pdu_count++; + } else { + /* avoid infinite loop ... */ + is_lcid_processed = TRUE; + } + + /* Get updated BO after multiplexing this PDU */ + lcid_buffer_occupancy_new = + mac_rlc_get_buffer_occupancy_ind( module_idP, + 0x1234, + eNB_index, + frameP, + subframe, + ENB_FLAG_NO, + lcid); + is_lcid_processed = (is_lcid_processed) + || (lcid_buffer_occupancy_new <= 0); + } + + //Update Buffer remain and BSR bytes after transmission + AssertFatal(lcid_buffer_occupancy_new <= + lcid_buffer_occupancy_old, + "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n", + lcid_buffer_occupancy_new, + lcid_buffer_occupancy_old, lcid, + lcid_rlc_pdu_count, frameP, subframe); + } + } + + + // build PHR and update the timers + /*if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + //Substitute with a static value for the MAC layer abstraction (phy_stub mode) + phr_p->PH = 40; + } else { + phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); + } + + phr_p->R = 0; + LOG_D(MAC, + "[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", + module_idP, frameP, get_PHR(module_idP, CC_id, eNB_index), + phr_p->PH, POWER_HEADROOM); + update_phr(module_idP, CC_id); + } else { + phr_p = NULL; + }*/ + + + // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order + // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 + /* For Padding BSR: + - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader: + - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission; + - else report Short BSR. + - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. + */ + if (sdu_length_total) { + padding_len = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - + rlc_pdu_header_len_last + sdu_length_total + 1); + } else { + padding_len = buflen - (bsr_len + phr_len); + } + + /* if ((padding_len) && (bsr_len == 0)) { + // if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR + if (padding_len >= (1 + BSR_LONG_SIZE)) { + bsr_ce_len = BSR_LONG_SIZE; + bsr_header_len = 1; + // Trigger BSR Padding + UE_mac_inst[module_idP].BSR_reporting_active |= + BSR_TRIGGER_PADDING; + } else if (padding_len >= (1 + sizeof(BSR_SHORT))) { + bsr_ce_len = sizeof(BSR_SHORT); + bsr_header_len = 1; + + if (num_lcg_id_with_data > 1) { + // REPORT TRUNCATED BSR + //Get LCGID of highest priority LCID with data + for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { + if (UE_mac_inst[module_idP]. + logicalChannelConfig[lcid] != NULL) { + lcg_id = + UE_mac_inst[module_idP].scheduling_info. + LCGID[lcid]; + + if ((lcg_id < MAX_NUM_LCGID) + && (UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[lcg_id]) + && + (UE_mac_inst[module_idP].logicalChannelConfig + [lcid]->ul_SpecificParameters->priority <= + highest_priority)) { + highest_priority = + UE_mac_inst[module_idP]. + logicalChannelConfig[lcid]-> + ul_SpecificParameters->priority; + lcg_id_bsr_trunc = lcg_id; + } + } + } + } else { + //Report SHORT BSR, clear bsr_t + bsr_t = NULL; + } + + // Trigger BSR Padding + UE_mac_inst[module_idP].BSR_reporting_active |= + BSR_TRIGGER_PADDING; + } + + bsr_len = bsr_header_len + bsr_ce_len; + }*/ + + //Fill BSR Infos + if (bsr_ce_len == 0) { + bsr_s = NULL; + bsr_l = NULL; + bsr_t = NULL; + } + else { + LOG_W(MAC, "BSR not null \n"); + } + + // 1-bit padding or 2-bit padding special padding subheader + // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 + if (sdu_length_total) { + padding_len = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - + rlc_pdu_header_len_last + sdu_length_total + 1); + } else { + padding_len = buflen - (bsr_len + phr_len); + } + + if (padding_len <= 2) { + short_padding = padding_len; + // only add padding header + post_padding = 0; + + //update total MAC Hdr size for RLC data + if (sdu_length_total) { + total_rlc_pdu_header_len = + total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1; + rlc_pdu_header_len_last = 1; + } + } else if (sdu_length_total) { + post_padding = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1); + + // If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding + if (post_padding == 0) { + total_rlc_pdu_header_len -= rlc_pdu_header_len_last; + padding_len = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1); + short_padding = padding_len; + total_rlc_pdu_header_len++; + } + } else { + if (padding_len == buflen) { // nona mac pdu + *access_mode = CANCELED_ACCESS; + } + + short_padding = 0; + post_padding = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1); + } + + // Generate header + // if (num_sdus>0) { + + payload_offset = generate_ulsch_header(ulsch_buffer, // mac header + num_sdus, // num sdus + short_padding, // short pading + sdu_lengths, // sdu length + sdu_lcids, // sdu lcid + phr_p, // power headroom + NULL, // crnti + bsr_t, // truncated bsr + bsr_s, // short bsr + bsr_l, post_padding); // long_bsr + LOG_D(MAC, + "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n", + module_idP, buflen, sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], payload_offset, total_rlc_pdu_header_len, + short_padding, post_padding, bsr_len, phr_len, + buflen - sdu_length_total - payload_offset); + + // cycle through SDUs and place in ulsch_buffer + if (sdu_length_total) { + memcpy(&ulsch_buffer[payload_offset], ulsch_buff, + sdu_length_total); + } + else + return 0; + + // fill remainder of DLSCH with random data + if (post_padding) { + for (j = 0; j < (buflen - sdu_length_total - payload_offset); j++) { + ulsch_buffer[payload_offset + sdu_length_total + j] = + (char) (taus() & 0xff); + } + } + return 1; + +} + + diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index ea3ee86db1..f0a8545141 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -548,3 +548,211 @@ void nr_schedule_uss_ulsch_phytest(nfapi_nr_ul_tti_request_t *UL_tti_req, //pusch_pdu->beamforming; //not used for now } } + +void +nr_rx_sdu(const module_id_t enb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP, + uint8_t *sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, + const uint8_t ul_cqi) +//----------------------------------------------------------------------------- +{ + int current_rnti = 0; + int UE_id = -1; + int RA_id = 0; + int old_rnti = -1; + int old_UE_id = -1; + int crnti_rx = 0; + //int harq_pid = 0; + int first_rb = 0; + unsigned char num_ce = 0; + unsigned char num_sdu = 0; + unsigned char *payload_ptr = NULL; + unsigned char rx_ces[MAX_NUM_CE]; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + uint8_t lcgid = 0; + int lcgid_updated[4] = {0, 0, 0, 0}; + //eNB_MAC_INST *mac = NULL; + UE_list_t *UE_list = NULL; + 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 = 0; //find_UE_id(enb_mod_idP, current_rnti); + //mac = RC.mac[enb_mod_idP]; + //harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + //UE_list = &mac->UE_list; + memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char)); + memset(rx_lcids, 0, NB_RB_MAX * sizeof(unsigned char)); + memset(rx_lengths, 0, NB_RB_MAX * sizeof(unsigned short)); + //start_meas(&mac->rx_ulsch_sdu); + + payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); + + if (payload_ptr == NULL) { + LOG_E(MAC,"[eNB %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", + enb_mod_idP, + CC_idP, + current_rnti, + UE_id); + return; + } + + /* Control element */ + for (int i = 0; i < num_ce; i++) { + + switch (rx_ces[i]) { // implement and process PHR + CRNTI + BSR + case POWER_HEADROOM: + + break; + + case CRNTI: + break; + + case TRUNCATED_BSR: + case SHORT_BSR: + + break; + + case LONG_BSR: + + break; + + default: + LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + enb_mod_idP, + CC_idP, + rx_ces[i]); + break; + } // end switch on control element + } // end for loop on control element + + for (int i = 0; i < num_sdu; i++) { + LOG_I(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", + i, + rx_lcids[i], + rx_lengths[i]); + T(T_ENB_MAC_UE_UL_SDU, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(rx_lcids[i]), + T_INT(rx_lengths[i])); + T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(rx_lcids[i]), + T_INT(rx_lengths[i]), + T_BUFFER(payload_ptr, rx_lengths[i])); + + switch (rx_lcids[i]) { + case CCCH: + + break; + + case DCCH: + case DCCH1: + + break; + + // all the DRBS + case DTCH: + default: +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + + for (int j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + + LOG_T(MAC, "\n"); +#endif + + if (rx_lcids[i] < NB_RB_MAX) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + UE_id, + rx_lcids[i]); + + if (UE_id != -1) { + /* Adjust buffer occupancy of the correponding logical channel group */ + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d \n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + UE_id, + rx_lcids[i]); + + + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + 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); + } else { /* rx_length[i] Max size */ + UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + enb_mod_idP, + CC_idP, + frameP, + rx_lcids[i], + UE_id); + } + } else { // end if (UE_id != -1) + LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + enb_mod_idP, + CC_idP, + frameP, + rx_lcids[i], + UE_id); + } + } + + break; + } + + payload_ptr += rx_lengths[i]; + } + + /* Program ACK for PHICH */ + + /*LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", + 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]; + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;*/ + + /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ + +} + diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d56d5d28c1..95abba549a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -145,4 +145,15 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); +void +nr_rx_sdu(const module_id_t enb_mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP, + uint8_t *sduP, + const uint16_t sdu_lenP, + const uint16_t timing_advance, + const uint8_t ul_cqi); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 9e873379b1..260e7c3ba3 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -128,6 +128,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); } else if (ENB_NAS_USE_TUN) { ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + LOG_I(PDCP, "ENB_NAS_USE_TUN is enabled, ret: %d, ctxt_pP->module_id:%d, sizeToWrite:%d, header size:%d \n", ctxt_pP->module_id, ret, sizeToWrite, sizeof (pdcp_data_ind_header_t)); } else if (PDCP_USE_NETLINK) { memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite); nas_nlh_tx->nlmsg_len = sizeToWrite; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 2d51e5c7f0..35b2980d41 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -65,6 +65,9 @@ void mac_rlc_data_ind ( nr_rlc_manager_lock(nr_rlc_ue_manager); ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + if(ue == NULL) + LOG_I(RLC, "RLC instance for the given UE was not found \n"); + switch (channel_idP) { case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; @@ -72,12 +75,13 @@ void mac_rlc_data_ind ( } if (rb != NULL) { + LOG_W(RLC, "RB found! (channel ID %d) \n", channel_idP); rb->set_time(rb, nr_rlc_current_time); rb->recv_pdu(rb, buffer_pP, tb_sizeP); } else { LOG_E(RLC, "%s:%d:%s: fatal: no RB found (channel ID %d)\n", __FILE__, __LINE__, __FUNCTION__, channel_idP); - exit(1); + //exit(1); } nr_rlc_manager_unlock(nr_rlc_ue_manager); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 4c9804bdc0..94aa458b96 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -182,7 +182,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot); - rx_sdu(UL_info->module_id, + nr_rx_sdu(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot, @@ -192,8 +192,8 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } else { - LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); - rx_sdu(UL_info->module_id, + LOG_I(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); + nr_rx_sdu(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot, From 61f6af80ad20eaf811a38559eb79569ef2389992 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 20 Jan 2020 19:06:15 +0100 Subject: [PATCH 171/343] build improvements: allow build mode selection (-g -G options) allow all exec build in one pass, remove remaining USE_MME macros in nr code --- cmake_targets/CMakeLists.txt | 21 ++--- cmake_targets/build_oai | 136 ++++++++++++++++++------------- executables/nr-gnb.c | 11 +-- executables/nr-ru.c | 12 +-- executables/nr-softmodem.c | 4 +- executables/nr-ue.c | 2 +- openair2/GNB_APP/gnb_app.c | 46 +++-------- openair2/GNB_APP/gnb_config.c | 29 +++---- openair2/RRC/LTE/rrc_UE.c | 11 +-- targets/COMMON/create_nr_tasks.c | 20 ++--- 10 files changed, 136 insertions(+), 156 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f5392acf5d..36feb99d2f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -127,7 +127,7 @@ endfunction() #set(CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "RelWithDebInfo") + set(CMAKE_BUILD_TYPE "Release") endif() message("CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}") add_list_string_option(CMAKE_BUILD_TYPE "RelWithDebInfo" "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." Debug Release RelWithDebInfo MinSizeRel) @@ -184,9 +184,9 @@ 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_DEBUG "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") - +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3") set(GIT_BRANCH "UNKNOWN") set(GIT_COMMIT_HASH "UNKNOWN") @@ -244,14 +244,10 @@ add_boolean_option(TEST_OMG False "???") add_boolean_option(DEBUG_OMG False "???") add_boolean_option(PRINT_STATS False "This adds the possibility to see the status") add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" ) -add_boolean_option(ENABLE_VCD True "always true now, time measurements of proc calls and var displays") add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs") add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") -add_boolean_option(DISABLE_LOG_X False "Deactivate all LOG_* macros") add_boolean_option(USRP_REC_PLAY False "Enable USRP record playback mode") -add_boolean_option(UE_NAS_USE_TUN False "Enable UE NAS TUN device instead of ue_ip.ko") -add_boolean_option(NOS1 False "Allows to run without a EPC") add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the basic simulator, False otherwise") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") @@ -341,7 +337,6 @@ add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source} add_dependencies(NR_RRC_LIB nr_rrc_flag) include_directories ("${NR_RRC_FULL_DIR}") - # S1AP # Same limitation as described in RRC: unknown generated file list # so we generate it at cmake time @@ -635,10 +630,8 @@ add_library(F1AP add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") -add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU") -if (NOT ${RF_BOARD} STREQUAL "None") - add_definitions(-DMANAGED_RF=1) -endif() +add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "OAI_LMSSDR" "OAI_SIMU") + add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET") @@ -655,7 +648,6 @@ set (CONFIG_LIBCONFIG_SOURCES ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c ) add_library(CONFIG_LIB ${CONFIG_SOURCES}) -set(CONFIG_LIBRARIES CONFIG_LIB) add_library(params_libconfig MODULE ${CONFIG_LIBCONFIG_SOURCES} ) target_link_libraries(params_libconfig config) # shared library loader @@ -737,7 +729,7 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}") ############################################################## # ???!!! TO BE DOCUMENTED OPTIONS !!!??? ############################################################## -add_boolean_option(ENABLE_USE_MME True "eNB connected to MME (INTERFACE S1-C), not standalone eNB") + add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO") add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "set the RLC mode to AM for the default bearer") @@ -747,7 +739,6 @@ add_boolean_option(CPU_AFFINITY False "Enable CPU Affinity of threads (only vali add_boolean_option(NAS_NETLINK False "useless ??? Must be True to compile nasmesh driver without rtai ????") add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????") -add_boolean_option(USE_MME False "this flag is used only one time in lte-softmodem.c") add_boolean_option(MESSAGE_CHART_GENERATOR False "For generating sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchanges in sequence diagrams") diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index e450a40da5..fb6dc78b90 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -88,8 +88,11 @@ Options -i | --install-system-files Install OpenAirInterface required files in Linux system This option will require root password --g | --run-with-gdb - Add debugging symbols to compilation directives. It also disables any compiler optimization. Only for debugging. Do not use in normal operation! +-g | --run-with-gdb $cmake_file echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file @@ -561,29 +589,30 @@ function main() { echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$build_dir/build eval $CMAKE_CMD - fi - if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" ] ; then - echo_info "Compiling $exec" - compilations \ - $build_dir $exec \ - $exec $dbin/$exec.$REL - -# if --eNB --UE are both provided together as build options - if [ "$eNB" = "1" -a "$UE" = "1" ] ; then - echo_info "Compiling lte-uesoftmodem" - compilations \ - $build_dir lte-uesoftmodem \ - lte-uesoftmodem $dbin/lte-uesoftmodem.$REL - fi - -# if --gNB --nrUE are both provided together as build options - if [ "$gNB" = "1" -a "$nrUE" = "1" ] ; then - echo_info "Compiling nr-uesoftmodem" - compilations \ - $build_dir nr-uesoftmodem \ - nr-uesoftmodem $dbin/nr-uesoftmodem.$REL - fi + execlist="" + if [ "$eNB" = "1" ] ; then + execlist="$execlist lte-softmodem" + fi + if [ "$gNB" = "1" ] ; then + execlist="$execlist nr-softmodem" + fi + if [ "$UE" = 1 ] ; then + execlist="$execlist lte-uesoftmodem" + fi + if [ "$nrUE" = 1 ] ; then + execlist="$execlist nr-uesoftmodem" + fi + + for f in $execlist ; do + echo_info "Compiling $f..." + compilations \ + $build_dir $f \ + $f $dbin/$f.$REL + done + + + # mandatory shared libraries common to UE and (e/g)NB @@ -603,10 +632,9 @@ function main() { $build_dir rb_tool \ rb_tool $dbin/rb_tool cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin - fi - + if [ "$UE" = 1 ] ; then - # ue_ip driver compilation + echo_info "Compiling UE specific part" compilations \ $build_dir ue_ip \ @@ -645,15 +673,12 @@ function main() { echo_warning "not generated UE NAS files: binaries not found" fi fi +fi + if [ "$SIMUS_PHY" = "1" -o "$SIMUS_CORE" = "1" ] ; then - cd $OPENAIR_DIR/cmake_targets/phy_simulators - [ "$CLEAN" = "1" ] && rm -rf build - mkdir -p build - cd build - rm -f *sim + cd $DIR/$build_dir/build eval $CMAKE_CMD - fi ################## # PHY simulators # @@ -674,7 +699,7 @@ function main() { # lte-simulators $config_libconfig_shlib \ # lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so fi - + fi ################### # Core simulators # ################### @@ -781,7 +806,6 @@ function main() { # Build RF device and transport protocol libraries # #################################################### if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then - # build RF device libraries if [ "$HW" != "None" ] ; then rm -f liboai_device.so diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 062cec07ab..b2dcc7f397 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -80,14 +80,9 @@ #include "UTIL/OTG/otg_extern.h" #endif -#if defined(ENABLE_ITTI) - #if defined(ENABLE_USE_MME) - #include "s1ap_eNB.h" - #ifdef PDCP_USE_NETLINK - #include "SIMULATION/ETH_TRANSPORT/proto.h" - #endif - #endif -#endif +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" + #include "T.h" diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 37e6b71d85..d0d1d10758 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -104,14 +104,10 @@ static int DEFBFW[] = {0x00007fff}; #include "UTIL/OTG/otg_extern.h" #endif -#if defined(ENABLE_ITTI) - #if defined(ENABLE_USE_MME) - #include "s1ap_eNB.h" - #ifdef PDCP_USE_NETLINK - #include "SIMULATION/ETH_TRANSPORT/proto.h" - #endif - #endif -#endif +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" + + #include "T.h" #include "nfapi_interface.h" diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index dac2fa6d19..5ff9618bf1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -428,7 +428,7 @@ int create_gNB_tasks(uint32_t gnb_nb) { } /* - # if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { if (gnb_nb > 0) { if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); @@ -452,7 +452,7 @@ int create_gNB_tasks(uint32_t gnb_nb) { } } - # endif + } */ if (gnb_nb > 0) { diff --git a/executables/nr-ue.c b/executables/nr-ue.c index af5f503f2b..aa50c42263 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -18,7 +18,7 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - +#include "executables/thread-common.h" #include "executables/nr-uesoftmodem.h" #include "LAYER2/NR_MAC_UE/mac.h" diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 5f30f69ee2..e6f84a8d13 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -37,27 +37,19 @@ #include "common/utils/LOG/log.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -# include "sctp_eNB_task.h" -# include "gtpv1u_eNB_task.h" -# endif - -# include "PHY/INIT/phy_init.h" +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" +#include "gtpv1u_eNB_task.h" +#include "PHY/INIT/phy_init.h" extern unsigned char NB_gNB_INST; -#endif + extern RAN_CONTEXT_t RC; -#if defined(ENABLE_ITTI) +#define GNB_REGISTER_RETRY_DELAY 10 -/*------------------------------------------------------------------------------*/ -# if defined(ENABLE_USE_MME) -# define GNB_REGISTER_RETRY_DELAY 10 -# endif /*------------------------------------------------------------------------------*/ @@ -82,7 +74,6 @@ static void configure_nr_rrc(uint32_t gnb_id) /*------------------------------------------------------------------------------*/ /* -# if defined(ENABLE_USE_MME) static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties) { uint32_t gnb_id; @@ -113,23 +104,15 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, return register_gnb_pending; } -# endif */ -#endif /*------------------------------------------------------------------------------*/ void *gNB_app_task(void *args_p) { -#if defined(ENABLE_ITTI) uint32_t gnb_nb = RC.nb_nr_inst; uint32_t gnb_id_start = 0; uint32_t gnb_id_end = gnb_id_start + gnb_nb; -# if defined(ENABLE_USE_MME) - //uint32_t register_gnb_pending; - //uint32_t registered_gnb; - //long gnb_register_retry_timer_id; -# endif uint32_t gnb_id; MessageDef *msg_p = NULL; const char *msg_name = NULL; @@ -166,15 +149,15 @@ void *gNB_app_task(void *args_p) configure_nr_rrc(gnb_id); } -# if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { /* Try to register each gNB */ //registered_gnb = 0; //register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p); -# else + } else { /* Start L2L1 task */ - msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE); - itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); -# endif + msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE); + itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); + } do { // Wait for a message @@ -193,7 +176,7 @@ void *gNB_app_task(void *args_p) LOG_I(GNB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p)); break; -# if defined(ENABLE_USE_MME) + /* case S1AP_REGISTER_ENB_CNF: LOG_I(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name, @@ -254,7 +237,6 @@ void *gNB_app_task(void *args_p) //} break; -# endif default: LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name); @@ -265,8 +247,6 @@ void *gNB_app_task(void *args_p) AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } while (1); -#endif - return NULL; } diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index f4a7b1a74a..acf87ab538 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -36,13 +36,9 @@ #include "gnb_config.h" #include "UTIL/OTG/otg.h" #include "UTIL/OTG/otg_externs.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -# include "sctp_eNB_task.h" -# endif -#endif +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" #include "sctp_default_values.h" // #include "SystemInformationBlockType2.h" // #include "LAYER2/MAC/extern.h" @@ -225,11 +221,10 @@ void RCconfig_nr_flexran() /* gNB ID from configuration, as read in by RCconfig_RRC() */ if (!GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr) { // Calculate a default gNB ID -# if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) gnb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8); -# else + else gnb_id = i; -# endif } else { gnb_id = *(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr); } @@ -648,7 +643,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { AssertFatal (i0) { @@ -671,13 +666,13 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { if (GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr == NULL) { // Calculate a default gNB ID - # if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { uint32_t hash; hash = s1ap_generate_eNB_id (); gnb_id = i + (hash & 0xFFFF8); - # else + } else { gnb_id = i; - # endif + } } else { gnb_id = *(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr); } @@ -2739,7 +2734,7 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); /* -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { asn_debug = 0; asn1_xer_print = 0; @@ -2753,7 +2748,7 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { asn_debug = 0; asn1_xer_print = 0; } -#endif + } */ AssertFatal (imodule_id].Info[eNB_index].SIStatus_MBMS = 1; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag_MBMS = sib1_MBMS->systemInfoValueTag_r14; -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) + /* + if (EPC_MODE_ENABLED) { int cell_valid = 0; @@ -2781,8 +2782,8 @@ int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_in LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); } } + } */ -#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); return 0; } @@ -2922,8 +2923,8 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - { + + if (EPC_MODE_ENABLED) { int cell_valid = 0; if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { @@ -2982,7 +2983,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); } } -#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); return 0; } diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c index 12532e0fd4..24c4115980 100644 --- a/targets/COMMON/create_nr_tasks.c +++ b/targets/COMMON/create_nr_tasks.c @@ -19,24 +19,22 @@ * contact@openairinterface.org */ -#if defined(ENABLE_ITTI) + # include "intertask_interface.h" # include "create_nr_tasks.h" # include "common/utils/LOG/log.h" # ifdef OPENAIR2 -# if defined(ENABLE_USE_MME) -# include "sctp_eNB_task.h" -# include "s1ap_eNB.h" -# include "nas_ue_task.h" -# include "udp_eNB_task.h" -# include "gtpv1u_eNB_task.h" -# endif +#include "sctp_eNB_task.h" +#include "s1ap_eNB.h" +#include "nas_ue_task.h" +#include "udp_eNB_task.h" +#include "gtpv1u_eNB_task.h" # if ENABLE_RAL # include "lteRALue.h" # include "lteRALenb.h" # endif -# include "RRC/NR/nr_rrc_defs.h" +#include "RRC/NR/nr_rrc_defs.h" # endif # include "gnb_app.h" @@ -61,7 +59,7 @@ int create_gNB_tasks(uint32_t gnb_nb) } /* -# if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { if (gnb_nb > 0) { if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); @@ -85,7 +83,7 @@ int create_gNB_tasks(uint32_t gnb_nb) } } -# endif + } */ if (gnb_nb > 0) { From 6cdac7e12f92a0a37c85479523a2c4999901a665 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 20 Jan 2020 19:45:21 +0100 Subject: [PATCH 172/343] fix config lib and config sources usage in CmakeList.txt --- cmake_targets/CMakeLists.txt | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 36feb99d2f..007f093437 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1587,11 +1587,8 @@ set(PHY_MEX_UE ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/utils/T/T.c ${OPENAIR_DIR}/common/utils/T/local_tracer.c - ${OPENAIR_DIR}/common/config/config_cmdline.c - ${OPENAIR_DIR}/common/config/config_userapi.c - ${OPENAIR_DIR}/common/config/config_load_configmodule.c ) -add_library(PHY_MEX ${PHY_MEX_UE}) +add_library(PHY_MEX ${PHY_MEX_UE} ${CONFIG_LIB}) #Layer 2 library ##################### @@ -2414,13 +2411,10 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) add_library(minimal_lib ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/LOG/log.c - ${OPENAIR_DIR}/common/config/config_userapi.c - ${OPENAIR_DIR}/common/config/config_load_configmodule.c - ${OPENAIR_DIR}/common/config/config_cmdline.c ${OPENAIR_DIR}/common/utils/minimal_stub.c ${T_SOURCE} ) -target_link_libraries(minimal_lib pthread dl ${T_LIB}) +target_link_libraries(minimal_lib pthread dl ${T_LIB} ${CONFIG_LIB}) add_executable(nfapi_test ${OPENAIR_DIR}/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c @@ -2474,7 +2468,7 @@ target_link_libraries (lte-softmodem -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem ${T_LIB}) @@ -2547,7 +2541,7 @@ target_link_libraries (lte-uesoftmodem -Wl,--end-group z dl) target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${T_LIB}) @@ -2586,7 +2580,7 @@ target_link_libraries (nr-softmodem -Wl,--end-group z dl) target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) @@ -2626,7 +2620,7 @@ target_link_libraries (nr-uesoftmodem -Wl,--end-group z dl) target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) @@ -2672,7 +2666,7 @@ add_executable(dlsim_tm4 ) target_link_libraries (dlsim_tm4 -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ${ITTI_LIB} -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${T_LIB} + pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB} ) add_executable(polartest @@ -2795,7 +2789,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ) target_link_libraries (${myExe} -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl + pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) @@ -2808,7 +2802,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 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} + -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_LIB} ) add_executable(test_epc_play_scenario @@ -2827,7 +2821,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 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} + -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_LIB} ) @@ -2847,7 +2841,7 @@ foreach(myExe s1ap ${OPENAIR3_DIR}/TEST/test_${myExe}.c ) target_link_libraries (test_${myExe} - -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} ) endforeach(myExe) From 22e45b8adf1bef50e111d3df883c339c18ecd84b Mon Sep 17 00:00:00 2001 From: frtabu Date: Tue, 21 Jan 2020 18:01:50 +0100 Subject: [PATCH 173/343] update doc/BUILD.md and doc/RUNMODEM.md to reflect develop/develop-nr merge and latest merge requests affecting the build procedure --- doc/BUILD.md | 59 ++++++++++++++++++++++++++++++------------------- doc/RUNMODEM.md | 9 ++++---- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/doc/BUILD.md b/doc/BUILD.md index 388f9f2658..24c9de253e 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -18,22 +18,33 @@ This page is valid on tags starting from **`2019.w09`**. oai EPC is developed in a distinct project with it's own [documentation](https://github.com/OPENAIRINTERFACE/openair-cn/wiki) , it is not described here. -OAI UE and eNodeB sources can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md). +OAI softmodem sources, which aim to implement 3GPP compliant UEs, eNodeB and gNodeB can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md). Sources come with a build script [build_oai](../cmake_targets/build_oai) located at the root of the `openairinterface5g/cmake_targets` directory. This script is developed to build the oai binaries (executables,shared libraries) for different hardware platforms, and use cases. The main oai binaries, which are tested by the Continuous Integration process are: - The LTE UE: `lte-uesoftmodem` +- The 5G UE: `nr-uesoftmodem` - The LTE eNodeB: `lte-softmodem` -- The PHY simulators: `dlsim` and `ulsim` +- The 5G gNodeB: `nr-softmodem` +- The LTE PHY simulators: `dlsim` and `ulsim` +- The 5G PHY simulators: `nr_dlschsim` `nr_dlsim` `nr_pbchsim` `nr_pucchsim` `nr_ulschsim` `nr_ulsim` `polartest` `smallblocktest` + `ulsim` `ldpctest` + +Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries: + +- `con2uedata`: a binary used to build the UE data from a configuration file. The created file emulates the sim card of a 3GPP compliant phone. +- `nvram`: a binary used to build UE (IMEI...) and EMM (IMSI, registered PLMN) non volatile data. +- `rb_tool`: radio bearer utility +- `genids` T Tracer utility, used at build time to generate T_IDs.h include file. This binary is located in the [T Tracer source file directory](../common/utils/T) . The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../cmake_targets/CMakeLists.txt), it is used as input by cmake to generate the makefiles. The oai softmodem supports many use cases, and new ones are regularly added. Most of them are accessible using the configuration file or the command line options and continuous effort is done to avoid introducing build options as it makes tests and usage more complicated than run-time options. The following functionalities, originally requiring a specific build are now accessible by configuration or command line options: - s1, noS1 -- all simulators, with exception of PHY simulators, which are distinct executables. +- all simulators as the rfsimulator, the L2 simulator, with exception of PHY simulators, which are distinct executables. Calling the `build_oai` script with the -h option gives the list of all available options, but a process to simplify and check the requirements of all these options is on-going. Check the [table](BUILD.md "# `build_oai` options") At the end of this page to know the status of `buid_oai` options which are not described hereafter. @@ -42,25 +53,27 @@ Calling the `build_oai` script with the -h option gives the list of all availabl Detailed information about these simulators can be found [in this dedicated page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/OpenAirLTEPhySimul) -# Building UE and eNodeB Executables +# Building UEs, eNodeB and gNodeB Executables -After downloading the source files, a single build command can be used to get the binaries supporting all the oai softmodem use cases (UE and eNodeB): +After downloading the source files, a single build command can be used to get the binaries supporting all the oai softmodem use cases (UE and [eg]NodeB): ``` cd /openairinterface5g/ source oaienv cd cmake_targets/ -./build_oai -I -w USRP --eNB --UE +./build_oai -I -w USRP --eNB --UE --nrUE --gNB ``` - The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. -- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be build using `-w SIMU` option. +- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be specifically built using `-w SIMU` option, but is also built during any softmodem build. - `--eNB` is to build the `lte-softmodem` executable and all required shared libraries +- `--gNB` is to build the `nr-softmodem` executable and all required shared libraries - `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries +- `--nrUE` is to build the `nr-uesoftmodem` executable and all required shared libraries -You can build the eNodeB and the UE separately, you may not need both of them depending on your oai usage. +You can build any oai softmodem executable separately, you may not need all of them depending on your oai usage. -After completing the build, the binaries are available in the `cmake_targets/ran_build/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel14 by default. It must be noticed that the option for building for a specific 3GPP release number is not tested by the CI and may be removed in the future. +After completing the build, the binaries are available in the `cmake_targets/ran_build/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel15. ## Issue when building `nasmeh` module ## @@ -106,13 +119,13 @@ or You can get documentation about the telnet server [here](common/utils/telnetsrv/DOC/telnetsrv.md) -## USRP record player -The USRP record player today needs a specific build. Work to make it available as a run time option is under consideration ## Other optional libraries -Using the help option of the build script you can get the list of available optional libraries. Those which haven't been mentioned above are known to need more tests and documentation +Using the help option of the build script you can get the list of available optional libraries. Those which haven't been mentioned above are known to need more tests and documentation. + +`./build_oai --build-lib all` will build all available optional libraries. # `build_oai` options @@ -122,30 +135,30 @@ Using the help option of the build script you can get the list of available opti | -c | maintained | erase all previously built files for this target before starting the new build. | | -C | maintained, needs improvement | erase all previously built files for any target before starting the new build. | | --verbose-compile | maintained | get compilation messages, as when running `make` or `gcc` directly. | -| --cflags_processor | maintained | used to pass options to the compiler | +| --cflags_processor | maintained | used to pass options to the compiler. | | --clean-kernel | unknown | no code in the script corresponding to this option | | --install-system-files | maintained | install oai built binaries in linux system files repositories | | -w | maintained and tested in CI for USRP device | build corresponding oai device and create the soft link to enforce this device usage at run-time | -| --phy_simulators | maintained, tested in CI | build all PHY simulators, a set of executables allowing unitary tests of LTE channel implementation within oai. | +| --phy_simulators | maintained, tested in CI | build all PHY simulators, a set of executables allowing unitary tests of LTE and 5G channel implementation within oai. | | --core_simulators | | | | -s | | | | --run-group | | | | -I | maintained, tested in CI | install external dependencies before starting the build | -| --install-optional-packages | maintained | install optional packages, useful for developing and testing. look at the | -| | | check_install_additional_tools function in cmake_targets/tools/build_helper script to get the list | -| -g | maintained | build binaries with gdb support. | +| --install-optional-packages | maintained | install optional packages, useful for developing and testing. look at the check_install_additional_tools function in cmake_targets/tools/build_helper script to get the list | +| -g | maintained | Specifies the level of debugging options used to build the binaries. Available levels are `Release`, `RelWithDebInfo`, `MinSizeRe` and `Debug`. If -g is not specified, `Release` is used, if -g is used without any level, `Debug` is used. | +| -G | maintained | Display Cmake debugging messages | | --eNB | maintained and tested in CI | build `lte-softmodem` the LTE eNodeB | | --UE | maintained and tested in CI | build `lte-uesoftmodem` the LTE UE | -| --usrp-recplay | maintained | build with support for the record player. Implementation will be soon reviewed to switch to a run-time option. | -| --build-lib | maintained | build optional shared library(ies), which can then be loaded at run time via command line option. Use the --help option to get the list of supported optional libraries. | -| --UE-conf-nvram | | | -| --UE-gen-nvram | | | -| -r | unknown, to be removed | specifies which 3GPP release to build for. Only the default (today rel14) is tested in CI and it is likely that future oai release will remove this option | +| --gNB | maintained and tested in CI | build `nr-softmodem` the 5G gNodeB | +| --nrUE | maintained and tested in CI | build `nr-uesoftmodem` the 5G UE | +| --usrp-recplay | deprecated | use the USRP configuration parameters to use the record player. | +| --build-lib | maintained | build optional shared library(ies), which can then be loaded at run time via command line option. Use the --help option to get the list of supported optional libraries. `all` can be used to build all available optional libraries. | +| --UE-conf-nvram | maintained | Specifies the path to the input file used by the conf2uedata utility. defaults to [openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf](../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf) | +| --UE-gen-nvram | maintained | Specifies the path where the output file created by the conf2uedata utility will be placed. Defaults to `target/bin` | | -V | deprecated | Used to build with support for synchronization diagram utility. This is now available via the T-Tracer and is included if T-Tracer is not disabled. | | --build-doxygen | unknown | build doxygen documentation, many oai source files do not include doxygen comments | | --disable-deadline --enable-deadline --disable-cpu-affinity | deprecated | These options were used to activate or de-activate specific code depending on the choice of a specific linux scheduling mode. This has not been tested for a while and should be implemented as configuration options | | --disable-T-Tracer | maintained, to be tested | Remove T_Tracer and console LOG messages except error messages. | -| --disable-hardware-dependency | | | | --ue-autotest-trace --ue-timing --ue-trace | deprecated | Were used to enable conditional code implementing debugging messages or debugging statistics. These functionalities are now either available from run-time options or not maintained. | | --build-eclipse | unknown | | | | | | diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 71354e663a..0c66b58547 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -20,19 +20,18 @@ See the [dedicated page](BASIC_SIM.md). # RF Simulator -The rf simulator is a oai device replacing the radio heads (for example the USRP device). It allows connecting the oai UE and the oai eNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. This is the ideal tool to check signal processing algorithms and protocols implementation. +The rf simulator is a oai device replacing the radio heads (for example the USRP device). It allows connecting the oai UE (LTE or 5G) and respectively the oai eNodeB or gNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. This is the ideal tool to check signal processing algorithms and protocols implementation. The rf simulator has some preliminary support for channel modeling. It is planned to enhance this simulator with the following functionalities: -- Support for multiple UE connections,each UE being a `lte-uesoftmodem` instance. -- Support for multiple eNodeB for hand-over tests -- Support for channel modeling +- Support for multiple UE connections,each UE being a `lte-uesoftmodem` or `nr_uesoftmodem` instance. +- Support for multiple eNodeB's or gNodeB's for hand-over tests This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../targets/ARCH/rfsimulator/README.md ) contains the detailed documentation. # L2 nFAPI Simulator -This simulator connects a eNodeB and UEs through a nfapi interface, short-cutting the L1 layer. The objective of this simulator is to allow multi UEs simulation, with a large number of UEs (ideally up to 255 ) .Here to ease the platform setup, UEs are simulated via a single `lte-uesoftmodem` instance. Today the CI tests just with one UE and architecture has to be reviewed to allow a number of UE above about 16. This work is on-going. +This simulator connects a eNodeB and UEs through a nfapi interface, short-cutting the L1 layer. The objective of this simulator is to allow multi UEs simulation, with a large number of UEs (ideally up to 255 ) .Here to ease the platform setup, UEs are simulated via a single `lte-uesoftmodem` instance. Today the CI tests just with one UE and architecture has to be reviewed to allow a number of UE above about 16. This work is on-going. As for the rf simulator, no specific hardware is required. The [L2 nfapi simlator page](L2NFAPI.md) contains the detailed documentation. From 99fce8a3599b31d20c067b82b5e08b3c66b15dd2 Mon Sep 17 00:00:00 2001 From: matzakos Date: Wed, 22 Jan 2020 13:05:10 +0100 Subject: [PATCH 174/343] nr-ip noS1 uplink: Uplink IP traffic successfully received at the IP TUN interface of the gNB now. Logs cleanup. --- executables/nr-softmodem.c | 1 + executables/nr-ue.c | 1 - openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 12 ++++--- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 25 ++++++++++---- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 12 ++++--- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 ++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 13 ++++++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 1 - openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 33 ++++++++++++++++--- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 2 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 2 +- 11 files changed, 85 insertions(+), 27 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 0a638f7265..62383b6dc9 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -910,6 +910,7 @@ init_opt(); #ifdef PDCP_USE_NETLINK +if(!IS_SOFTMODEM_NOS1) netlink_init(); #if defined(PDCP_USE_NETLINK_QUEUES) pdcp_netlink_init(); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 24288d76d3..fde6e24398 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -420,7 +420,6 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { 0x1234, proc->frame_rx, proc->nr_tti_rx, 0); pdcp_run(&ctxt); - pdcp_fifo_flush_sdus(&ctxt); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 1d3e62714b..4a90523fd1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -593,16 +593,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, p_procTime); if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - //#ifdef PRINT_CRC_CHECK + #ifdef PRINT_CRC_CHECK //if (prnt_crc_cnt % 10 == 0) LOG_I(PHY, "Segment %d CRC OK\n",r); - //#endif + #endif ret = no_iteration_ldpc; } else { - //#ifdef PRINT_CRC_CHECK + #ifdef PRINT_CRC_CHECK //if (prnt_crc_cnt%10 == 0) LOG_I(PHY, "CRC NOK\n"); - //#endif + #endif ret = ulsch->max_ldpc_iterations + 1; } @@ -719,12 +719,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } - LOG_I(PHY, "output encoder: \n"); +#ifdef DEBUG_ULSCH_DECODING + LOG_I(PHY, "Decoder output (payload): \n"); for (i = 0; i < harq_process->TBS / 8; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); printf("0x%02x",harq_process->b[i]); } +#endif ulsch->last_iteration_cnt = ret; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index a5c747bbba..fd0eb3f996 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -45,6 +45,7 @@ //#define DEBUG_SCFDMA //#define DEBUG_PUSCH_MAPPING +#define DEBUG_MAC_PDU //extern int32_t uplink_counter; @@ -160,13 +161,25 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if(data_existing){ //harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char)); memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8); - LOG_I(PHY, "input encoder: \n"); + + #ifdef DEBUG_MAC_PDU + LOG_I(PHY, "Printing MAC PDU to be encoded: \n"); + for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { + printf("0x%02x",harq_process_ul_ue->a[i]); + } + printf("\n"); + #endif + } + else{ + //Use different rnti for the random (non-IP traffic) in noS1 mode, in order to use it as a filter + //to block this traffic from being forwarded to the MAC layer of the gNB + ulsch_ue->rnti = 0x1111; + LOG_E(PHY, "Random data to be tranmsitted: \n"); for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { - //harq_process_ul_ue->a[i] = (unsigned char) rand(); - //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - //printf("0x%02x",harq_process_ul_ue->a[i]); - printf("0x%02x",harq_process_ul_ue->b[i]); - } + harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } + data_existing = 1; } } //else if(uplink_counter == 0){ //if(!IS_SOFTMODEM_NOS1){ diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a849e3c2d9..7f43c02fcb 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -38,6 +38,7 @@ #include "PHY/INIT/phy_init.h" #include "PHY/MODULATION/nr_modulation.h" #include "T.h" +#include "executables/nr-softmodem.h" #include "assertions.h" #include "msc.h" @@ -261,10 +262,12 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id if (ret > gNB->ulsch[UE_id][0]->max_ldpc_iterations) LOG_I(PHY, "ULSCH in error\n"); //gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b - else if(gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b!=NULL){ - LOG_I(PHY, "ULSCH received ok, number of iterations: %d \n", ret); - nr_fill_crc_indication (gNB, UE_id, frame_rx, slot_rx, 0); - nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); + else if(gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->b!=NULL){ + LOG_D(PHY, "ULSCH received ok \n"); + if(IS_SOFTMODEM_NOS1 && gNB->ulsch[UE_id][0]->rnti == 0x1234){ + nr_fill_crc_indication (gNB, UE_id, frame_rx, slot_rx, 0); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); + } } } @@ -295,7 +298,6 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = gNB->ulsch[UE_id][0]->rnti; pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; - pdu->rx_indication_rel8.length = gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation pdu->data = harq_process->b;//gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; // estimate timing advance for MAC diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index c0c8a9ec24..11bb2ee69f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3028,6 +3028,16 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, (char) (taus() & 0xff); } } +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_D(MAC, "Printing UL MAC payload without the header UE side: \n"); + for (int i = payload_offset; i < sdu_length_total ; i++) { + //harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + printf("%02x ",(unsigned char)ulsch_buffer[i]); + } + printf("\n"); +#endif + return 1; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index f0a8545141..d9e6b0d583 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -634,7 +634,7 @@ nr_rx_sdu(const module_id_t enb_mod_idP, } // end for loop on control element for (int i = 0; i < num_sdu; i++) { - LOG_I(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", + LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", i, rx_lcids[i], rx_lengths[i]); @@ -701,9 +701,16 @@ nr_rx_sdu(const module_id_t enb_mod_idP, if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - 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); +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing UL MAC payload after removing the header: \n"); + for (int j = 0; j < rx_lengths[i] ; j++) { + printf("%02x ",(unsigned char) *(payload_ptr+j)); + } + pritnf("\n"); +#endif + 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+1, rx_lengths[i], 1, NULL); } else { /* rx_length[i] Max size */ - UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + //UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", enb_mod_idP, CC_idP, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index f234e02c04..c2ebf8d1ea 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -2171,7 +2171,6 @@ 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); - //Add --nr-ip-over-lte option check for next line if (IS_SOFTMODEM_NOS1) nas_config(1, 1, 2, "ue"); LOG_I(PDCP, "UE pdcp will use tun interface\n"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 260e7c3ba3..8a87dad1be 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -124,18 +124,34 @@ 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 ); + #if defined(ENABLE_PDCP_PAYLOAD_DEBUG) + LOG_I(PHY, "PDCP output to be sent to TUN interface: \n"); + for (int i = sizeof(pdcp_data_ind_header_t); i < sizeToWrite; i++) { + printf("%02x ",(unsigned char)sdu_p->data[i]); + } + printf("\n"); + #endif + ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + } else if (ENB_NAS_USE_TUN) { - ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); - LOG_I(PDCP, "ENB_NAS_USE_TUN is enabled, ret: %d, ctxt_pP->module_id:%d, sizeToWrite:%d, header size:%d \n", ctxt_pP->module_id, ret, sizeToWrite, sizeof (pdcp_data_ind_header_t)); + #if defined(ENABLE_PDCP_PAYLOAD_DEBUG) + LOG_I(PHY, "PDCP output to be sent to TUN interface: \n"); + for (int i = sizeof(pdcp_data_ind_header_t); i < sizeToWrite; i++) { + printf("%02x ",(unsigned char)sdu_p->data[i]); + } + printf("\n"); + #endif + 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)); + AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]); #if defined(ENABLE_PDCP_PAYLOAD_DEBUG) LOG_I(PDCP, "Printing first bytes of PDCP SDU before removing it from the list: \n"); @@ -187,6 +203,15 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { 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); + +#if defined ENABLE_PDCP_PAYLOAD_DEBUG + LOG_I(PHY, "TUN interface output received from PDCP: \n"); + for (int i = 0; i < 128; i++) { + printf("%02x ",(unsigned char)nl_rx_buf[i]); + } + printf("\n"); +#endif + 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 diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 35b2980d41..67931f22a9 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -81,7 +81,7 @@ void mac_rlc_data_ind ( } else { LOG_E(RLC, "%s:%d:%s: fatal: no RB found (channel ID %d)\n", __FILE__, __LINE__, __FUNCTION__, channel_idP); - //exit(1); + exit(1); } nr_rlc_manager_unlock(nr_rlc_ue_manager); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 94aa458b96..2094b3517e 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -192,7 +192,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } else { - LOG_I(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); + LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); nr_rx_sdu(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, From b85731f4a9ece2caeb1d34c1223d889b100f0b16 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 22 Jan 2020 17:59:21 +0100 Subject: [PATCH 175/343] CI: Add LTE RF Simulator test (normal and with MBMS) Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 222 +++++++++++++++++++++++++++++++- ci-scripts/runTestOnVM.sh | 212 +++++++++++++++++++++++++----- openair2/RRC/NAS/nas_config.c | 4 +- 3 files changed, 404 insertions(+), 34 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index ff92460e35..f8f9025004 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -403,11 +403,231 @@ function report_test { ARCHIVES_LOC=archives/rf_sim/test if [ -d $ARCHIVES_LOC ] then + echo "

4G LTE RF Simulator Check

" >> ./test_simulator_results.html + + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `egrep -c "LTE: 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 " " >> ./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=("wS1 noS1") + TRANS_MODES=("fdd") + BW_CASES=(05) + 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}MHz_${CN_CONFIG}_enb.log + UE_LOG=`echo $ENB_LOG | sed -e "s#enb#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` + if [[ $CN_CONFIG =~ .*noS1.* ]] + then + NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfully configured" $ENB_LOG` + fi + NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "Generating RRCConnectionReconfigurationComplete" $UE_LOG` + if [[ $CN_CONFIG =~ .*noS1.* ]] + then + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG` + else + NB_UE_TUNNEL_UP=`egrep -c "executing ifconfig oaitun_ue1" $UE_LOG` + fi + 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_${CN_CONFIG}_ping*.log 2> /dev/null` + analyzePingFiles + + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl*client*txt | grep -v mbms 2> /dev/null` + analyzeIperfFiles + + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul*client*txt | grep -v mbms 2> /dev/null` + analyzeIperfFiles + done + done + done + + # MBMS Case + CN_CONFIG="noS1" + TMODE="fdd" + BW_CASES=(05) + for BW in ${BW_CASES[@]} + do + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_enb_mbms.log + UE_LOG=`echo $ENB_LOG | sed -e "s#enb#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 successfully configured" $ENB_LOG` + NB_ENB_MTUNNEL_UP=`egrep -c "Interface oaitun_enm1 successfully configured" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "Generating RRCConnectionReconfigurationComplete" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG` + NB_UE_MTUNNEL_UP=`egrep -c "Interface oaitun_uem1 successfully configured" $UE_LOG` + NB_UE_MBMS_PUSH_MSG=`egrep -c "TRIED TO PUSH MBMS DATA TO" $UE_LOG` + if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] && [ $NB_UE_MBMS_PUSH_MSG -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_${CN_CONFIG}_ping*.log 2> /dev/null` + #analyzePingFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl*client*txt | grep -v mbms 2> /dev/null` + #analyzeIperfFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul*client*txt | grep -v mbms 2> /dev/null` + #analyzeIperfFiles + done + echo "
Log File NameCommandStatusStatistics
Test with EPC (aka withS1): ${TMODE} -- ${BW}MHz Test without EPC (aka noS1): ${TMODE} -- ${BW}MHz
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
+                    if [ $NB_ENB_GOT_SYNC -gt 0 ]
+                    then
+                        echo "- eNB --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- eNB NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [[ $CN_CONFIG =~ .*noS1.* ]]
+                    then
+                        if [ $NB_ENB_TUNNEL_UP -gt 0 ]
+                        then
+                            echo "- eNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                        else
+                            echo "- eNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                        fi
+                    fi
+                    if [ $NB_UE_GOT_SYNC -gt 0 ]
+                    then
+                        echo "- LTE UE --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- LTE UE NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
+                    then
+                        echo "- LTE UE attached to eNB" >> ./test_simulator_results.html
+                    else
+                        echo "- LTE UE NEVER attached to eNB" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_UE_TUNNEL_UP -gt 0 ]
+                    then
+                        echo "- LTE UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                    else
+                        echo "- LTE UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                    fi
+                    echo "        
Test MBMS without EPC (aka noS1): ${TMODE} -- ${BW}MHz
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
+                if [ $NB_ENB_GOT_SYNC -gt 0 ]
+                then
+                    echo "- eNB --> got sync" >> ./test_simulator_results.html
+                else
+                    echo "- eNB NEVER got sync" >> ./test_simulator_results.html
+                fi
+                if [ $NB_ENB_TUNNEL_UP -gt 0 ]
+                then
+                    echo "- eNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- eNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_ENB_MTUNNEL_UP -gt 0 ]
+                then
+                    echo "- eNB mounted oaitun_enm1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- eNB NEVER mounted oaitun_enm1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_UE_GOT_SYNC -gt 0 ]
+                then
+                    echo "- LTE UE --> got sync" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER got sync" >> ./test_simulator_results.html
+                fi
+                if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
+                then
+                    echo "- LTE UE attached to eNB" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER attached to eNB" >> ./test_simulator_results.html
+                fi
+                if [ $NB_UE_TUNNEL_UP -gt 0 ]
+                then
+                    echo "- LTE UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_UE_MTUNNEL_UP -gt 0 ]
+                then
+                    echo "- LTE UE mounted oaitun_uem1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER mounted oaitun_uem1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_UE_MBMS_PUSH_MSG -gt 0 ]
+                then
+                    echo "- LTE UE tried to push ${NB_UE_MBMS_PUSH_MSG} MBMS DATA" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER pushed MBMS DATA" >> ./test_simulator_results.html
+                fi
+                echo "        
" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + 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 ] + if [ `egrep -c "5G-NR: TEST_OK" $ARCHIVES_LOC/test_final_status.log` -eq 1 ] then echo "
" >> ./test_simulator_results.html echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 1f9d945a63..289f4500e6 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -169,6 +169,14 @@ function get_ue_ip_addr { rm $1 } +function get_ue_mbms_ip_addr { + local LOC_IF_ID=$3 + echo "ifconfig oaitun_uem${LOC_IF_ID} | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 + UE_IP_ADDR=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` + echo "Test UE${LOC_IF_ID} MBMS IP Address is : $UE_IP_ADDR" + rm $1 +} + function get_enb_noS1_ip_addr { echo "ifconfig oaitun_enb1 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 ENB_IP_ADDR=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` @@ -176,6 +184,13 @@ function get_enb_noS1_ip_addr { rm $1 } +function get_enb_mbms_noS1_ip_addr { + echo "ifconfig oaitun_enm1 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 + ENB_IP_ADDR=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` + echo "Test eNB MBMS IP Address is : $ENB_IP_ADDR" + rm $1 +} + function ping_ue_ip_addr { local LOC_FG_OR_BG=$5 echo "echo \"COMMAND IS: ping -c 20 $3\" > $4" > $1 @@ -957,9 +972,9 @@ function start_rf_sim_enb { echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 if [ $LOC_S1_CONFIGURATION -eq 0 ] then - echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --rfsim --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --rfsim --log_config.global_log_options level,nocolor --noS1 --eNBs.[0].rrc_inactivity_threshold 0\" > ./my-lte-softmodem-run.sh " >> $1 else - echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --rfsim --log_config.global_log_options level,nocolor \" > ./my-lte-softmodem-run.sh " >> $1 + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --rfsim --log_config.global_log_options level,nocolor --eNBs.[0].rrc_inactivity_threshold 0 --eNBs.[0].plmn_list.[0].mnc 93\" > ./my-lte-softmodem-run.sh " >> $1 fi echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 echo "cat ./my-lte-softmodem-run.sh" >> $1 @@ -1015,6 +1030,31 @@ function start_rf_sim_enb { else echo "RF-SIM eNB oaitun_enb1 is UP and CONFIGURED" fi + if [[ $LOC_CONF_FILE =~ .*mbms.* ]] + then + echo "ifconfig oaitun_enm1 | egrep -c \"inet addr\"" > $1 + # Checking oaitun_enm1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_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 + ENB_SYNC=0 + echo "RF-SIM eNB oaitun_enm1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM eNB oaitun_enm1 is UP and CONFIGURED" + fi + fi fi sleep 10 } @@ -1027,6 +1067,7 @@ function start_rf_sim_ue { local LOC_FREQUENCY=$6 # 1 is with S1 and 0 without S1 aka noS1 local LOC_S1_CONFIGURATION=$7 + local LOC_MBMS_CONFIGURATION=$8 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 \"export RFSIMULATOR=${LOC_ENB_VM_IP_ADDR}\"" >> $1 @@ -1036,9 +1077,9 @@ function start_rf_sim_ue { echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 if [ $LOC_S1_CONFIGURATION -eq 0 ] then - echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --ue-rxgain 140 --ue-txgain 120 --nokrnmod 1 --rfsim --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1 else - echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --log_config.global_log_options level,nocolor\" > ./my-lte-softmodem-run.sh " >> $1 + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --ue-rxgain 140 --ue-txgain 120 --nokrnmod 1 --rfsim --log_config.global_log_options level,nocolor\" > ./my-lte-softmodem-run.sh " >> $1 fi echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 echo "cat ./my-lte-softmodem-run.sh" >> $1 @@ -1093,6 +1134,31 @@ function start_rf_sim_ue { else echo "RF-SIM UE oaitun_ue1 is UP and CONFIGURED" fi + if [ $LOC_MBMS_CONFIGURATION -eq 1 ] + then + # Checking oaitun_uem1 interface has now an IP address + i="0" + echo "ifconfig oaitun_uem1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_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 + UE_SYNC=0 + echo "RF-SIM UE oaitun_uem1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM UE oaitun_uem1 is UP and CONFIGURED" + fi + fi sleep 10 } @@ -1668,7 +1734,7 @@ function run_test_on_vm { fi fi - if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-ru-sim.* ]] + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] then PING_STATUS=0 IPERF_STATUS=0 @@ -1686,11 +1752,10 @@ function run_test_on_vm { install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` fi - # withS1 configuration is not working #EPC_CONFIGS=("wS1" "noS1") #TRANS_MODES=("fdd" "tdd") #BW_CASES=(05 10 20) - EPC_CONFIGS=("noS1" "wS1") + EPC_CONFIGS=("wS1" "noS1") TRANS_MODES=("fdd") BW_CASES=(05) for CN_CONFIG in ${EPC_CONFIGS[@]} @@ -1754,7 +1819,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : Starting the UE" echo "############################################################" CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ue.log - start_rf_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG + start_rf_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 0 if [ $UE_SYNC -eq 0 ] then echo "Problem w/ eNB and UE not syncing" @@ -1762,13 +1827,13 @@ function run_test_on_vm { terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - if [ $S1_NOS1_CFG -eq 1 ] - then - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - fi - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + #if [ $S1_NOS1_CFG -eq 1 ] + #then + # terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + #fi + # Now we keep running STATUS=-1 - return + break fi if [ $S1_NOS1_CFG -eq 1 ] @@ -1814,15 +1879,37 @@ function run_test_on_vm { check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 fi - if [ $S1_NOS1_CFG -eq 0 ] + if [ $S1_NOS1_CFG -eq 1 ] then - get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR echo "############################################################" - echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "${CN_CONFIG} : iperf DL -- UE is server and EPC is client" echo "############################################################" IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 - THROUGHPUT=4 + THROUGHPUT=10 + generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR $REAL_EPC_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : iperf UL -- EPC is server and UE is client" + echo "############################################################" + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul + THROUGHPUT=2 + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + generic_iperf $EPC_VM_CMDS $EPC_VM_IP_ADDR $REAL_EPC_IP_ADDR $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + else + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + THROUGHPUT=10 generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC @@ -1852,6 +1939,67 @@ function run_test_on_vm { done done + #################### + ## MSMS CASE noS1 ## + #################### + CONF_FILE=lte-fdd-mbms-basic-sim.conf + CN_CONFIG="noS1" + S1_NOS1_CFG=0 + LTEBOX=0 + TMODE="fdd" + FREQUENCY=2680 + BW_CASES=(05) + + for BW in ${BW_CASES[@]} + do + if [[ $BW =~ .*05.* ]]; then PRB=25; fi + if [[ $BW =~ .*10.* ]]; then PRB=50; fi + if [[ $BW =~ .*20.* ]]; then PRB=100; fi + + echo "############################################################" + echo "${CN_CONFIG} : Starting the eNB with MSMS in ${TMODE}-${BW}MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_enb_mbms.log + start_rf_sim_enb $ENB_VM_CMDS "$ENB_VM_IP_ADDR" "$EPC_VM_IP_ADDR" $CURRENT_ENB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG + + echo "############################################################" + echo "${CN_CONFIG} : Starting the UE" + echo "############################################################" + CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ue_mbms.log + start_rf_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + STATUS=-1 + break + fi + + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + get_enb_mbms_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl_mbms + get_ue_mbms_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + THROUGHPUT=2 + generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + #check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + + done + full_l2_sim_destroy echo "############################################################" @@ -1862,21 +2010,19 @@ function run_test_on_vm { if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi if [ $STATUS -eq 0 ] then - echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + echo "LTE RFSIM seems OK" + echo "LTE: TEST_OK" > $ARCHIVES_LOC/test_final_status.log else - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + echo "LTE RFSIM seems to FAIL" + echo "LTE: TEST_KO" > $ARCHIVES_LOC/test_final_status.log fi fi if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] then + NR_STATUS=0 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 @@ -1904,7 +2050,8 @@ function run_test_on_vm { 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 + echo "5G-NR RFSIM seems to FAIL" + echo "5G-NR: TEST_KO" >> $ARCHIVES_LOC/test_final_status.log STATUS=-1 return fi @@ -1936,13 +2083,16 @@ function run_test_on_vm { 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 ] + if [ $PING_STATUS -ne 0 ]; then NR_STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then NR_STATUS=-1; fi + if [ $NR_STATUS -eq 0 ] then - echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + echo "5G-NR RFSIM seems OK" + echo "5G-NR: TEST_OK" >> $ARCHIVES_LOC/test_final_status.log else - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + echo "5G-NR RFSIM seems to FAIL" + echo "5G-NR: TEST_KO" >> $ARCHIVES_LOC/test_final_status.log + STATUS=-1 fi fi diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index c4bb52b1bb..2eb439b9e9 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -260,7 +260,7 @@ int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifn 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", @@ -301,7 +301,7 @@ int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char * printf("returnValue %d\n",returnValue); 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, "255.255.255.0", broadcastAddress); else LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n", From fb57ef2fd4b727d2b218f0e2596211495c653565 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Wed, 22 Jan 2020 20:18:51 +0100 Subject: [PATCH 176/343] patch from Robert Schmidt -BUGFIX: CD/DU F1 split --- openair2/LAYER2/MAC/eNB_scheduler.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 3659933378..901043d8d9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -897,10 +897,12 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } // end for loop on UE_id #if (!defined(PRE_SCD_THREAD)) - 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); + if (!NODE_IS_DU(RC.rrc[module_idP]->node_type)) { + 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 for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { From b723418c335a1e91734523d0179b79789b8850b7 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 22 Jan 2020 21:36:58 +0100 Subject: [PATCH 177/343] CI: fix RF simulator hyperlinks in HTML report Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 14 +++++++------- cmake_targets/autotests/test_case_list.xml | 5 ++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index f8f9025004..cd1e4e9546 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -253,7 +253,7 @@ function report_test { ARCHIVES_LOC=archives/basic_sim/test if [ -d $ARCHIVES_LOC ] then - echo "

Basic Simulator Check

" >> ./test_simulator_results.html + echo "

4G LTE Basic Simulator Check

" >> ./test_simulator_results.html if [ -f $ARCHIVES_LOC/test_final_status.log ] then @@ -373,7 +373,7 @@ function report_test { if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] then - echo "

Basic Simulator + FlexRan Controller Check

" >> ./test_simulator_results.html + echo "

4G LTE Basic Simulator + FlexRan Controller Check

" >> ./test_simulator_results.html echo "
" >> ./test_simulator_results.html echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html echo "
" >> ./test_simulator_results.html @@ -423,8 +423,8 @@ function report_test { echo "
" >> ./test_simulator_results.html fi - 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 echo " " >> ./test_simulator_results.html @@ -643,8 +643,8 @@ function report_test { echo " " >> ./test_simulator_results.html fi - echo " " >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html echo "
Log File Name
" >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html @@ -743,7 +743,7 @@ function report_test { ARCHIVES_LOC=archives/l2_sim/test if [ -d $ARCHIVES_LOC ] then - echo "

L2-NFAPI Simulator Check

" >> ./test_simulator_results.html + echo "

4G LTE L2-NFAPI Simulator Check

" >> ./test_simulator_results.html if [ -f $ARCHIVES_LOC/test_final_status.log ] then diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 6795f2d1fa..c4f15c3a16 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1045,7 +1045,7 @@ $OPENAIR_DIR/targets/bin/polartest.Rel15-q -s-10 -f0 -q -s-10 -f0 -m1 - polartest.test1 + polartest.test1 polartest.test2BLER= 0.000000segmentation fault|assertion|exiting|fatal3 @@ -1107,8 +1107,7 @@ -n100 -R217 -a80 -n100 -R217 -a110 -b100 -n100 -e28 - nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 - nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 + nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11PDSCH test OKsegmentation fault|assertion|exiting|fatal3 From 009c75d60b328687bece5a09e228134e6631b0bc Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 22 Jan 2020 21:15:39 +0100 Subject: [PATCH 178/343] CI: removed obsolete python obsolete options split the RRC inactivity scenarios Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 2 + ci-scripts/Jenkinsfile-tmp-full-ran | 12 +- ci-scripts/Jenkinsfile-tmp-multi-enb | 12 +- ci-scripts/Jenkinsfile-tmp-ran | 12 +- ci-scripts/Jenkinsfile-tmp-ue | 12 +- .../enb_usrp210_band7_test_05mhz_tm1.xml | 124 ---------------- ...st_05mhz_tm1_rrc_inactivity_no_flexran.xml | 125 ++++++++++++++++ ...est_05mhz_tm1_rrc_inactivity_w_flexran.xml | 138 ++++++++++++++++++ 8 files changed, 289 insertions(+), 148 deletions(-) create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 2792e3556a..fcfd56a4a2 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -55,6 +55,8 @@ pipeline { "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", + "Test L1-sim", + "Test RF-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran index 7211a54bcf..096ff7f52d 100644 --- a/ci-scripts/Jenkinsfile-tmp-full-ran +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -51,7 +51,7 @@ termStatusArray[termOAIUE] = false def eNB_Repository def eNB_Branch def eNB_CommitID -def eNB_AllowMergeRequestProcess = false +def ranAllowMergeRequestProcess = false def eNB_TargetBranch def doEpcLogCollection = true @@ -130,8 +130,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { + ranAllowMergeRequestProcess = params.eNB_mergeRequest + if (ranAllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -168,7 +168,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { + if (ranAllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { @@ -208,12 +208,12 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { - sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { if (fileExists(xmlFile)) { try { - sh "python3 main.py --mode=TesteNB --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { currentBuild.result = 'FAILURE' buildStageStatus = false diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb index c3b825ec06..4df2006ed2 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb @@ -41,7 +41,7 @@ def ciSmartPhoneResource = params.smartphonesResource def eNB_Repository def eNB_Branch def eNB_CommitID -def eNB_AllowMergeRequestProcess = false +def ranAllowMergeRequestProcess = false def eNB_TargetBranch pipeline { @@ -124,8 +124,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { + ranAllowMergeRequestProcess = params.eNB_mergeRequest + if (ranAllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -157,7 +157,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { + if (ranAllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { @@ -198,12 +198,12 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${ranAllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { if (fileExists(xmlFile)) { try { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${ranAllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { currentBuild.result = 'FAILURE' buildStageStatus = false diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 5ffaefa89f..ad852b8e93 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -54,7 +54,7 @@ termStatusArray[termHSS] = false def eNB_Repository def eNB_Branch def eNB_CommitID -def eNB_AllowMergeRequestProcess = false +def ranAllowMergeRequestProcess = false def eNB_TargetBranch pipeline { @@ -145,8 +145,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { + ranAllowMergeRequestProcess = params.eNB_mergeRequest + if (ranAllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -178,7 +178,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { + if (ranAllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { @@ -217,12 +217,12 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { - sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { if (fileExists(xmlFile)) { try { - sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { currentBuild.result = 'FAILURE' buildStageStatus = false diff --git a/ci-scripts/Jenkinsfile-tmp-ue b/ci-scripts/Jenkinsfile-tmp-ue index c2db977bcb..e22cd45615 100644 --- a/ci-scripts/Jenkinsfile-tmp-ue +++ b/ci-scripts/Jenkinsfile-tmp-ue @@ -54,7 +54,7 @@ termStatusArray[termHSS] = false def eNB_Repository def eNB_Branch def eNB_CommitID -def eNB_AllowMergeRequestProcess = false +def ranAllowMergeRequestProcess = false def eNB_TargetBranch pipeline { @@ -116,8 +116,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { + ranAllowMergeRequestProcess = params.eNB_mergeRequest + if (ranAllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -149,7 +149,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { + if (ranAllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { @@ -187,12 +187,12 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { - sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { if (fileExists(xmlFile)) { try { - sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { currentBuild.result = 'FAILURE' buildStageStatus = false diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml index 3b07ed4950..ec6090c00c 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml @@ -28,101 +28,15 @@ 030201 040101 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 - 030102 000010 040301 040502 000011 040302 000001 000012 040303 000002 000013 040503 040401 040201 030201 - 050102 - 030103 000020 040301 040504 000021 040302 000001 000022 040303 000002 040504 000023 040401 040201 030201 - 050202 - - IdleSleep - Waiting for 35 seconds - 35 - - - - IdleSleep - Waiting for 10 seconds - 10 - - - - CheckStatusUE - Check UE(s) status before attachment - 0 - - - - CheckStatusUE - Check UE(s) status before data disabling - 2 - - - - CheckStatusUE - Check UE(s) status after data disabling - 0 - - - - CheckStatusUE - Check UE(s) status after data re-enabling - 2 - - - - CheckStatusUE - Check UE(s) status before attachment - 0 - - - - CheckStatusUE - Check UE(s) status before data disabling - 2 - - - - CheckStatusUE - Check UE(s) status after data disabling - 0 - - - - CheckStatusUE - Check UE(s) status after data re-enabling - 2 - - - - Initialize_FlexranCtrl - Starting Flexran Controller - - - - Terminate_FlexranCtrl - Stopping Flexran Controller - - Initialize_eNB Initialize eNB (FDD/Band7/5MHz) -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf - - Initialize_eNB - Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- no FlexRan Ctl - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf - - - - Initialize_eNB - Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- with FlexRan Ctl - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf - - Terminate_eNB Terminate eNB @@ -148,16 +62,6 @@ Detach UE - - DataDisable_UE - Disabling Data Service on UE - - - - DataEnable_UE - Enabling Data Service on UE - - Ping ping (5MHz - 20 sec) @@ -165,34 +69,6 @@ 5 - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - - Iperf iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml new file mode 100644 index 0000000000..686e5b1b38 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml @@ -0,0 +1,125 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + + 030201 + 040101 + 030102 000010 040301 040502 000011 040302 000001 000012 040303 000002 000013 040503 040401 040201 030201 + + + + + IdleSleep + Waiting for 35 seconds + 35 + + + + IdleSleep + Waiting for 10 seconds + 10 + + + + CheckStatusUE + Check UE(s) status before attachment + 0 + + + + CheckStatusUE + Check UE(s) status before data disabling + 2 + + + + CheckStatusUE + Check UE(s) status after data disabling + 0 + + + + CheckStatusUE + Check UE(s) status after data re-enabling + 2 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- no FlexRan Ctl + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + DataDisable_UE + Disabling Data Service on UE + + + + DataEnable_UE + Enabling Data Service on UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml new file mode 100644 index 0000000000..9e7227aa47 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml @@ -0,0 +1,138 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + 2 + + 030201 + 040101 + 050102 + 030103 000020 040301 040504 000021 040302 000001 000022 040303 000002 040505 000023 040401 040201 030201 + 050202 + + + + + IdleSleep + Waiting for 35 seconds + 35 + + + + IdleSleep + Waiting for 10 seconds + 10 + + + + CheckStatusUE + Check UE(s) status before attachment + 0 + + + + CheckStatusUE + Check UE(s) status before data disabling + 2 + + + + CheckStatusUE + Check UE(s) status after data disabling + 0 + + + + CheckStatusUE + Check UE(s) status after data re-enabling + 2 + + + + Initialize_FlexranCtrl + Starting Flexran Controller + + + + Terminate_FlexranCtrl + Stopping Flexran Controller + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- with FlexRan Ctl + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + DataDisable_UE + Disabling Data Service on UE + + + + DataEnable_UE + Enabling Data Service on UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + From 9b920255b395c1c1031910014da50583333fd290 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 22 Jan 2020 22:53:34 +0100 Subject: [PATCH 179/343] DOC: added kernel headers install guidelines for CentOS / RHEL Signed-off-by: Raphael Defosseux --- doc/BUILD.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/BUILD.md b/doc/BUILD.md index 24c9de253e..9ada32e532 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -105,6 +105,20 @@ Install it: $ sudo apt-get install --yes linux-headers-your-version ``` +On CentOS or RedHat Entreprise Linux: + +```bash +$ uname -r +3.10.0-1062.9.1.rt56.1033.el7.x86_64 +$ yum list installed | grep kernel | grep devel +kernel-devel.x86_64 3.10.0-1062.9.1.el7 @rhel-7-server-rpms +kernel-rt-devel.x86_64 3.10.0-1062.9.1.rt56.1033.el7 +``` + +If your kernel is generic, install `kernel-devel` package: `sudo yum install kernel-devel` + +In most case, your kernel is real-time. Install `kernel-rt-devel` package: `sudo yum install kernel-rt-devel` + # Building Optional Binaries ## Telnet Server From 4a2abc03b59c52a7ed70d32261c8bde8c581b5b2 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 23 Jan 2020 11:05:08 +0100 Subject: [PATCH 180/343] CI: splitting build xml files into build and epc-start XML files Signed-off-by: Raphael Defosseux --- .../xml_files/enb_ue_usrp210_band7_build.xml | 38 +++++++++++ .../enb_ue_usrp210_band7_ue_build.xml | 38 +++++++++++ .../xml_files/enb_usrp210_band13_build.xml | 16 ----- .../enb_usrp210_band13_epc_start.xml | 48 ++++++++++++++ .../xml_files/enb_usrp210_band40_build.xml | 16 ----- .../enb_usrp210_band40_epc_start.xml | 47 ++++++++++++++ .../xml_files/enb_usrp210_band7_build.xml | 16 ----- .../xml_files/enb_usrp210_band7_epc_start.xml | 47 ++++++++++++++ ...st_05mhz_tm1_rrc_inactivity_no_flexran.xml | 4 +- ...est_05mhz_tm1_rrc_inactivity_w_flexran.xml | 8 +-- .../xml_files/enb_usrpB210_band7_50PRB.xml | 65 ------------------- .../xml_files/if4p5_usrp210_band40_build.xml | 16 ----- .../if4p5_usrp210_band40_epc_start.xml | 48 ++++++++++++++ .../xml_files/if4p5_usrp210_band7_build.xml | 16 ----- .../if4p5_usrp210_band7_epc_start.xml | 48 ++++++++++++++ .../x2ho_enb_usrp210_band13_build.xml | 16 ----- .../x2ho_enb_usrp210_band13_epc_start.xml | 48 ++++++++++++++ 17 files changed, 368 insertions(+), 167 deletions(-) create mode 100644 ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml create mode 100644 ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band13_epc_start.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_epc_start.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_epc_start.xml delete mode 100644 ci-scripts/xml_files/enb_usrpB210_band7_50PRB.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40_epc_start.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7_epc_start.xml create mode 100644 ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_start.xml diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml new file mode 100644 index 0000000000..64c3517166 --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_build.xml @@ -0,0 +1,38 @@ + + + build-tab + Build + wrench + + 010101 + + + + + Build_eNB + Build eNB (USRP) + -w USRP -c --eNB + + + diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml new file mode 100644 index 0000000000..7280a87fb8 --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml @@ -0,0 +1,38 @@ + + + oai-ue-build-tab + OAI-UE-Build + wrench + +090101 + + + + + Build_OAI_UE + Build OAI UE + -w USRP --UE + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band13_build.xml b/ci-scripts/xml_files/enb_usrp210_band13_build.xml index 96ab517b34..888a1230ae 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_build.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_build.xml @@ -26,7 +26,6 @@ wrench 010101 - 050101 060101 070101 @@ -37,19 +36,4 @@ -w USRP -c --eNB - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - diff --git a/ci-scripts/xml_files/enb_usrp210_band13_epc_start.xml b/ci-scripts/xml_files/enb_usrp210_band13_epc_start.xml new file mode 100644 index 0000000000..0a788cb614 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band13_epc_start.xml @@ -0,0 +1,48 @@ + + + epc-start-tab + EPC-Start + log-in + + 050101 060101 070101 + + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_build.xml b/ci-scripts/xml_files/enb_usrp210_band40_build.xml index fd32019bb5..64c3517166 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_build.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_build.xml @@ -26,7 +26,6 @@ wrench 010101 - 050101 060101 070101 @@ -36,19 +35,4 @@ -w USRP -c --eNB - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - diff --git a/ci-scripts/xml_files/enb_usrp210_band40_epc_start.xml b/ci-scripts/xml_files/enb_usrp210_band40_epc_start.xml new file mode 100644 index 0000000000..354cff346e --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_epc_start.xml @@ -0,0 +1,47 @@ + + + epc-start-tab + EPC-Start + log-in + + 050101 060101 070101 + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_build.xml b/ci-scripts/xml_files/enb_usrp210_band7_build.xml index fd32019bb5..64c3517166 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_build.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_build.xml @@ -26,7 +26,6 @@ wrench 010101 - 050101 060101 070101 @@ -36,19 +35,4 @@ -w USRP -c --eNB - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - diff --git a/ci-scripts/xml_files/enb_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/enb_usrp210_band7_epc_start.xml new file mode 100644 index 0000000000..354cff346e --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_epc_start.xml @@ -0,0 +1,47 @@ + + + epc-start-tab + EPC-Start + log-in + + 050101 060101 070101 + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml index 686e5b1b38..a28a81d970 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml @@ -21,8 +21,8 @@ --> - test-05-tm1 - Test-05MHz-TM1 + test-05-tm1-rrc-no-flex + Test-05MHz-TM1-RRC-Inactivity tasks 030201 diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml index 9e7227aa47..07cd8fbb30 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml @@ -21,8 +21,8 @@ --> - test-05-tm1 - Test-05MHz-TM1 + test-05-tm1-rrc-w-flex + Test-05MHz-TM1-RRC-Inactivity-FlexRan tasks 2 @@ -36,8 +36,8 @@ IdleSleep - Waiting for 35 seconds - 35 + Waiting for 45 seconds + 45 diff --git a/ci-scripts/xml_files/enb_usrpB210_band7_50PRB.xml b/ci-scripts/xml_files/enb_usrpB210_band7_50PRB.xml deleted file mode 100644 index 56dfe2be72..0000000000 --- a/ci-scripts/xml_files/enb_usrpB210_band7_50PRB.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - 030101 040101 040301 040501 040401 040201 030201 - - - - Initialize_eNB - Initialize eNB (FDD/Band1/5MHz/info) - -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf - - - - Terminate_eNB - Terminate eNB - - - - Initialize_UE - Initialize UE - - - - Terminate_UE - Terminate UE - - - - Attach_UE - Attach UE - - - - Detach_UE - Detach UE - - - - Ping - ping (20 sec) - -c 20 - 5 - - - diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml index 752049349f..ab221c918d 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml @@ -26,7 +26,6 @@ wrench 010101 - 050101 060101 070101 @@ -37,19 +36,4 @@ -w USRP -c --eNB - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_epc_start.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_epc_start.xml new file mode 100644 index 0000000000..0a788cb614 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_epc_start.xml @@ -0,0 +1,48 @@ + + + epc-start-tab + EPC-Start + log-in + + 050101 060101 070101 + + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml index 8cbd2d84c6..ab221c918d 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml @@ -26,7 +26,6 @@ wrench 010101 - 050101 060101 070101 040101 @@ -37,19 +36,4 @@ -w USRP -c --eNB - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_epc_start.xml new file mode 100644 index 0000000000..e8d08de507 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_epc_start.xml @@ -0,0 +1,48 @@ + + + epc-start-tab + EPC-Start + log-in + + 050101 060101 070101 040101 + + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml index 0d2a122537..c5a912a33d 100644 --- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml @@ -27,7 +27,6 @@ 010101 010102 - 050101 060101 070101 @@ -48,19 +47,4 @@ 1 - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_start.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_start.xml new file mode 100644 index 0000000000..0a788cb614 --- /dev/null +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_start.xml @@ -0,0 +1,48 @@ + + + epc-start-tab + EPC-Start + log-in + + 050101 060101 070101 + + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + From b7a027f905bd36d3de4e28b6373d21946805778d Mon Sep 17 00:00:00 2001 From: WANG Tsu-Han Date: Thu, 23 Jan 2020 14:52:30 +0100 Subject: [PATCH 181/343] fixes for mutex lock for wake up signal --- executables/nr-gnb.c | 15 +++++++++------ executables/nr-ru.c | 4 ++-- targets/RT/USER/lte-enb.c | 5 ++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 062cec07ab..374b5b8b2f 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -422,10 +422,14 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - waitret=wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh"); - AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); + AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); + while (proc->instance_cnt_RUs < 0) { + pthread_cond_wait(&proc->cond_RUs,&proc->mutex_RUs_tx); // this unlocks mutex_rxtx while waiting and then locks it again + } + proc->instance_cnt_RUs = -1; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); + AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); @@ -451,7 +455,6 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ru = gNB->RU_list[i]; ru_proc = &ru->proc; - //AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); if (ru_proc->instance_cnt_gNBs == 0) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); @@ -459,11 +462,11 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); gNB->proc.RU_mask_tx = 0; AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - //AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); return(-1); } + AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); ru_proc->instance_cnt_gNBs = 0; ru_proc->timestamp_tx = timestamp_tx; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 37e6b71d85..ad418e73ab 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1354,11 +1354,11 @@ static void *ru_thread_tx( void *param ) { ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); // the thread can now be woken up - //if (L1_proc->instance_cnt_RUs == -1) { + if (L1_proc->instance_cnt_RUs == -1) { L1_proc->instance_cnt_RUs = 0; AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, "ERROR pthread_cond_signal for gNB_L1_thread\n"); - //} //else AssertFatal(1==0,"gNB TX thread is not ready\n"); + } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx); AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index c718d9251a..8c5c50836f 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -512,17 +512,16 @@ int wakeup_txfh(PHY_VARS_eNB *eNB, continue;//hacking only works when all RU_tx works on the same subframe #TODO: adding mask stuff } - AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_eNBs))==0,"ERROR pthread_mutex_lock failed on mutex_eNBs L1_thread_tx with ret=%d\n",ret); - if (ru_proc->instance_cnt_eNBs == 0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->subframe_rx); AssertFatal((ret=pthread_mutex_lock(&eNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); eNB->proc.RU_mask_tx = 0; AssertFatal((ret=pthread_mutex_unlock(&eNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_eNBs ))==0,"mutex_unlock return %d\n",ret); return(-1); } + AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_eNBs))==0,"ERROR pthread_mutex_lock failed on mutex_eNBs L1_thread_tx with ret=%d\n",ret); + ru_proc->instance_cnt_eNBs = 0; ru_proc->timestamp_tx = timestamp_tx; ru_proc->tti_tx = subframe_tx; From d3b19823f0aea8f30cdc7e3df34935bca5b7ee65 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 23 Jan 2020 15:54:19 +0100 Subject: [PATCH 182/343] CI: count ULSCH received ok messages --- ci-scripts/main.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index e4618919ee..6854520c8f 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3079,6 +3079,7 @@ class SSHConnection(): uciStatMsgCount = 0 pdcpFailure = 0 ulschFailure = 0 + ulschOK = 0 cdrxActivationMessageCount = 0 dropNotEnoughRBs = 0 mbmsRequestMsg = 0 @@ -3191,6 +3192,9 @@ class SSHConnection(): result = re.search('ULSCH in error in round', str(line)) if result is not None: ulschFailure += 1 + result = re.search('ULSCH received ok', str(line)) + if result is not None: + ulschOK += 1 result = re.search('BAD all_segments_received', str(line)) if result is not None: rlcDiscardBuffer += 1 @@ -3223,6 +3227,10 @@ class SSHConnection(): statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmleNBFailureMsg += statMsg + '\n' + if ulschOK > 0: + statMsg = nodeB_prefix + 'NB showed ' + str(ulschOK) + ' "ULSCH received ok" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmleNBFailureMsg += statMsg + '\n' if dropNotEnoughRBs > 0: statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') From 51ab31a3b92b0193850be46d87aeafa2f5820610 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 23 Jan 2020 16:10:29 +0100 Subject: [PATCH 183/343] trigger NR activation based on RRC measurements An NR-capable UE will transmit some NR measurements. Once received, the whole process on nr-cell addition is started. It will fail quickly. Many things are still missing. What is not handled properly with this commit: - in x2ap_eNB_handle_sgNB_add_req we hardcode the gNB ID - nr triggering is done if we receive a measurement but this measurement is not analyzed at all - no timers (T_dc_overall, T_dc_prep) and as is the code fails and then the next triggering after UE reconnection will not work (x2 ID are not well handled here and there in the code) Note also that the gNB part has not been looked at all for this commit. This is work in progress... --- openair2/COMMON/x2ap_messages_types.h | 2 +- openair2/RRC/LTE/rrc_defs.h | 3 +- openair2/RRC/LTE/rrc_eNB.c | 22 ++++++++++++- openair2/X2AP/x2ap_eNB.c | 37 +++++++++++++++++++++- openair2/X2AP/x2ap_eNB_generate_messages.c | 2 +- openair2/X2AP/x2ap_eNB_handler.c | 30 ++++++++++++++---- openair2/X2AP/x2ap_ids.h | 3 +- 7 files changed, 87 insertions(+), 12 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 23d6e543fa..ed3470a7d6 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -357,7 +357,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { int SgNB_ue_x2_id; - /* used for RRC->X2AP in source eNB */ + /* used for X2AP->RRC in source eNB */ int rnti; uint8_t nb_e_rabs_admitted_tobeadded; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 2540ee09bd..53ba6d9314 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -265,7 +265,8 @@ typedef enum UE_STATE_e { RRC_SI_RECEIVED, RRC_CONNECTED, RRC_RECONFIGURED, - RRC_HO_EXECUTION + RRC_HO_EXECUTION, + RRC_NR_NSA, } UE_STATE_t; typedef enum HO_STATE_e { diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 086f7c3a8b..aa17118a17 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4297,6 +4297,10 @@ rrc_eNB_process_MeasurementReport( ctxt_pP->subframe); break; + case 7: + LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe); + break; + default: LOG_D(RRC,"Other event report frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); break; @@ -4310,6 +4314,22 @@ rrc_eNB_process_MeasurementReport( ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20); } + /* TODO: improve NR triggering */ + if (measResults2->measId == 7) { + if (ue_context_pP->ue_context.Status != RRC_NR_NSA) { + MessageDef *msg; + ue_context_pP->ue_context.Status = RRC_NR_NSA; + + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; + LOG_I(RRC, + "[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n", + ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti); + itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg); + return; + } + } + if (measResults2->measResultNeighCells == NULL) return; @@ -8399,7 +8419,7 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, ENB_FLAG_YES, - 4660,//ue_context->ue_context.rnti, + m->rnti, 0, 0); size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf); diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 39c3d77816..b297c96e56 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -446,6 +446,37 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack); } +static +void x2ap_eNB_handle_sgNB_add_req(instance_t instance, + x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req) +{ + x2ap_id_manager *id_manager; + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + int ue_id; + + /* TODO: remove hardcoded value */ + x2ap_eNB_data = x2ap_is_eNB_id_in_list(3584); + DevAssert(x2ap_eNB_data != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + /* allocate x2ap ID */ + id_manager = &instance_p->id_manager; + ue_id = x2ap_allocate_new_id(id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + /* TODO: cancel NSA: send (to be defined) message to RRC */ + exit(1); + } + /* id_source is ue_id, id_target is unknown yet */ + x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1); + x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE); + + x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id); +} + static void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_ENDC_sgnb_addition_req_ACK) @@ -552,11 +583,15 @@ void *x2ap_task(void *arg) { &X2AP_UE_CONTEXT_RELEASE(received_msg)); break; + case X2AP_ENDC_SGNB_ADDITION_REQ: + x2ap_eNB_handle_sgNB_add_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_ENDC_SGNB_ADDITION_REQ(received_msg)); + break; + case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: x2ap_gNB_trigger_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(received_msg)); LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n"); - break; case SCTP_INIT_MSG_MULTI_CNF: diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 6dc4b675d1..47a3475063 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1569,7 +1569,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; //Not sure about that ie->criticality= X2AP_Criticality_reject; ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t)); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index c80507a78f..b7a9b70596 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1482,9 +1482,7 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); - return x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data,0); // Not the right place to call the X2 function. Used only initially for testing. - + return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); } int @@ -1804,6 +1802,9 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; int ue_id; + int id_source; + int id_target; + int rnti; DevAssert (pdu != NULL); x2SgNBAdditionRequest_ack = &pdu->choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge; @@ -1835,6 +1836,8 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, return -1; } + id_source = ie->value.choice.UE_X2AP_ID; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID; @@ -1846,6 +1849,24 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, return -1; } + id_target = ie->value.choice.SgNB_UE_X2AP_ID; + + ue_id = id_source; + + if (ue_id != x2ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { + X2AP_WARN("incorrect/unknown X2AP IDs for UE (old ID %d new ID %d), ignoring sGNB addition response\n", + id_source, id_target); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + return 0; + } + + rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + + /* id_target is a new information, store it */ + x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target); + + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rnti = rnti; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID; /* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */ @@ -1907,10 +1928,7 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); - x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(instance_p, x2ap_eNB_data,0,0); // Not the right place to call the X2 function. Used only initially for testing. - return 0; - } static diff --git a/openair2/X2AP/x2ap_ids.h b/openair2/X2AP/x2ap_ids.h index 3d2799e8c4..f2670f3612 100644 --- a/openair2/X2AP/x2ap_ids.h +++ b/openair2/X2AP/x2ap_ids.h @@ -37,7 +37,8 @@ typedef enum { X2ID_STATE_SOURCE_PREPARE, X2ID_STATE_SOURCE_OVERALL, - X2ID_STATE_TARGET + X2ID_STATE_TARGET, + X2ID_STATE_NSA_PREPARE, } x2id_state_t; typedef struct { From 855752f4d2093baa7660fca82a2767d1a9f1c6f5 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 24 Jan 2020 11:20:10 +0100 Subject: [PATCH 184/343] Fix a few warnings Signed-off-by: Raphael Defosseux --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +--- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 8 ++++---- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 30fd260ec9..0067efb4d9 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -3558,7 +3558,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe; uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl; - int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1, d_2_1, d; + int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d; uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP // TODO this should corresponds to the switching time as defined in // TS 38.133 @@ -4276,8 +4276,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, uint8_t do_pdcch_flag, runmode_t mode) { - int l,l2; - int pilot1; int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; int slot_pbch; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0c23ad808d..77e5059772 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2127,7 +2127,7 @@ void nr_ue_process_mac_pdu( uint16_t mac_subheader_len; uint16_t mac_sdu_len; - NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); + //NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); //uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; //uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 15c96fec94..5233270149 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -91,7 +91,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, timing_advance_cmd = gNB->ta_command; AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n", timing_advance_cmd); ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - if (gNB->tag->tag_Id != NULL){ + if (gNB->tag->tag_Id != 0){ tag_id = gNB->tag->tag_Id; ((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index b8af0a1167..5fb7fdeef5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -288,8 +288,8 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, unsigned char sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int padding = 0, post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int CC_id, lcid, offset, i, j=0, k=0, header_length_last, TBS_bytes; + int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; + int CC_id, lcid, offset, i, header_length_last, TBS_bytes; int UE_id = 0; uint16_t rnti = 0x1234; @@ -398,10 +398,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (TBS_bytes >= 2 + header_length_total + sdu_length_total + ta_len) { // we have to consider padding // padding param currently not in use - padding = TBS_bytes - header_length_total - sdu_length_total - ta_len - 1; + //padding = TBS_bytes - header_length_total - sdu_length_total - ta_len - 1; post_padding = 1; } else { - padding = 0; + //padding = 0; post_padding = 0; } From 5162f0c4ef292fd738178040c42c7c971b417d43 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 24 Jan 2020 11:22:14 +0100 Subject: [PATCH 185/343] CI: fix the missing 5G-NR UE build report Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 6 +++++- ci-scripts/reportBuildLocally.sh | 36 ++++++++++++++++---------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 2792e3556a..ac17a0ec7b 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -340,7 +340,11 @@ pipeline { always { script { dir ('archives') { - sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nrue_usrp red_hat" + if (fileExists('red_hat')) { + sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat" + } else { + sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp" + } } if(fileExists('archives/vm_build_logs.zip')) { archiveArtifacts artifacts: 'archives/vm_build_logs.zip' diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index b6c2ca104a..54372ac6ba 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -509,7 +509,7 @@ function report_build { sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder sca_summary_table_footer ./archives/cppcheck/cppcheck.xml - summary_table_header "OAI Build eNB -- USRP option" ./archives/enb_usrp + summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html @@ -521,7 +521,7 @@ function report_build { summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html summary_table_footer - summary_table_header "OAI Build basic simulator option" ./archives/basic_sim + summary_table_header "OAI Build: 4G LTE basic simulator option" ./archives/basic_sim summary_table_row "LTE SoftModem - Release 15" ./archives/basic_sim/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./basic_sim_row1.html summary_table_row "LTE UE SoftModem - Release 15" ./archives/basic_sim/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./basic_sim_row2.htm summary_table_row "Coding - Release 15" ./archives/basic_sim/coding.Rel15.txt "Built target coding" ./basic_sim_row3.html @@ -537,7 +537,7 @@ function report_build { summary_table_row "NVRAM - Release 15" ./archives/basic_sim/nvram.Rel15.txt "Built target nvram" ./basic_sim_row13.html summary_table_footer - summary_table_header "OAI Build Physical simulators option" ./archives/phy_sim + summary_table_header "OAI Build: 4G LTE / 5G NR Physical simulators option" ./archives/phy_sim summary_table_row "LTE DL Simulator - Release 15" ./archives/phy_sim/dlsim.Rel15.txt "Built target dlsim" ./phy_sim_row1.html summary_table_row "LTE UL Simulator - Release 15" ./archives/phy_sim/ulsim.Rel15.txt "Built target ulsim" ./phy_sim_row2.html summary_table_row "Coding - Release 15" ./archives/phy_sim/coding.Rel15.txt "Built target coding" ./phy_sim_row3.html @@ -581,7 +581,7 @@ function report_build { if [ -f archives/gnb_usrp/nr-softmodem.Rel15.txt ] then - summary_table_header "OAI Build gNB -- USRP option" ./archives/gnb_usrp + summary_table_header "OAI Build: 5G NR gNB -- USRP option" ./archives/gnb_usrp summary_table_row "5G NR SoftModem - Release 15" ./archives/gnb_usrp/nr-softmodem.Rel15.txt "Built target nr-softmodem" ./gnb_usrp_row1.html summary_table_row "Coding - Release 15" ./archives/gnb_usrp/coding.Rel15.txt "Built target coding" ./gnb_usrp_row2.html summary_table_row "OAI USRP device if - Release 15" ./archives/gnb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html @@ -592,20 +592,20 @@ function report_build { summary_table_footer fi - if [ -f archives/nrue_usrp/nr-uesoftmodem.Rel15.txt ] + if [ -f archives/nr_ue_usrp/nr-uesoftmodem.Rel15.txt ] then - summary_table_header "OAI Build 5G NR UE -- USRP option" ./archives/nrue_usrp - summary_table_row "5G NR UE SoftModem - Release 15" ./archives/nrue_usrp/nr-uesoftmodem.Rel15.txt "Built target nr-uesoftmodem" ./nrue_usrp_row1.html - summary_table_row "Coding - Release 15" ./archives/nrue_usrp/coding.Rel15.txt "Built target coding" ./nrue_usrp_row2.html - summary_table_row "OAI USRP device if - Release 15" ./archives/nrue_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./nrue_usrp_row3.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/nrue_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./nrue_usrp_row4.html - summary_table_row "NASMESH - Release 15" ./archives/nrue_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./nrue_usrp_row5.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/nrue_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./nrue_usrp_row6.html - summary_table_row "RB Tool - Release 15" ./archives/nrue_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./nrue_usrp_row7.html + summary_table_header "OAI Build: 5G NR UE -- USRP option" ./archives/nr_ue_usrp + summary_table_row "5G NR UE SoftModem - Release 15" ./archives/nr_ue_usrp/nr-uesoftmodem.Rel15.txt "Built target nr-uesoftmodem" ./nr_ue_usrp_row1.html + summary_table_row "Coding - Release 15" ./archives/nr_ue_usrp/coding.Rel15.txt "Built target coding" ./nr_ue_usrp_row2.html + summary_table_row "OAI USRP device if - Release 15" ./archives/nr_ue_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./nr_ue_usrp_row3.html + summary_table_row "OAI ETHERNET transport - Release 15" ./archives/nr_ue_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./nr_ue_usrp_row4.html + summary_table_row "NASMESH - Release 15" ./archives/nr_ue_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./nr_ue_usrp_row5.html + summary_table_row "Parameters Lib Config - Release 15" ./archives/nr_ue_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./nr_ue_usrp_row6.html + summary_table_row "RB Tool - Release 15" ./archives/nr_ue_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./nr_ue_usrp_row7.html summary_table_footer fi - summary_table_header "OAI Build eNB -- ETHERNET transport option" ./archives/enb_eth + summary_table_header "OAI Build: 4G LTE eNB -- ETHERNET transport option" ./archives/enb_eth summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html @@ -614,7 +614,7 @@ function report_build { summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html summary_table_footer - summary_table_header "OAI Build UE -- ETHERNET transport option" ./archives/ue_eth + summary_table_header "OAI Build: 4G LTE UE -- ETHERNET transport option" ./archives/ue_eth summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html @@ -631,7 +631,7 @@ function report_build { then echo "

Red Hat Enterprise Linux Server release 7.6) -- Summary

" >> ./build_results.html - summary_table_header "Red Hat -- OAI Build eNB -- USRP option" ./archives/red_hat + summary_table_header "OAI Build: 4G LTE eNB -- USRP option (RHEL)" ./archives/red_hat summary_table_row "LTE SoftModem - Release 15" ./archives/red_hat/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html summary_table_row "Coding - Release 15" ./archives/red_hat/coding.Rel15.txt "Built target coding" ./enb_usrp_rh_row2.html summary_table_row "OAI USRP device if - Release 15" ./archives/red_hat/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html @@ -671,9 +671,9 @@ function report_build { cat $DETAILS_TABLE >> ./build_results.html done fi - if [ -f ./nrue_usrp_row1.html ] || [ -f ./nrue_usrp_row2.html ] || [ -f ./nrue_usrp_row3.html ] || [ -f ./nrue_usrp_row4.html ] + if [ -f ./nr_ue_usrp_row1.html ] || [ -f ./nr_ue_usrp_row2.html ] || [ -f ./nr_ue_usrp_row3.html ] || [ -f ./nr_ue_usrp_row4.html ] then - for DETAILS_TABLE in `ls ./nrue_usrp_row*.html` + for DETAILS_TABLE in `ls ./nr_ue_usrp_row*.html` do cat $DETAILS_TABLE >> ./build_results.html done From fd865ea06d02ada99cdbe547dad6f453cd00e5f6 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 24 Jan 2020 12:05:58 +0100 Subject: [PATCH 186/343] CI: doing the check only in NR Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 6854520c8f..4c5a10c1eb 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3192,9 +3192,10 @@ class SSHConnection(): result = re.search('ULSCH in error in round', str(line)) if result is not None: ulschFailure += 1 - result = re.search('ULSCH received ok', str(line)) - if result is not None: - ulschOK += 1 + if self.air_interface == 'nr': + result = re.search('ULSCH received ok', str(line)) + if result is not None: + ulschOK += 1 result = re.search('BAD all_segments_received', str(line)) if result is not None: rlcDiscardBuffer += 1 @@ -3227,10 +3228,11 @@ class SSHConnection(): statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmleNBFailureMsg += statMsg + '\n' - if ulschOK > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(ulschOK) + ' "ULSCH received ok" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' + if self.air_interface == 'nr': + if ulschOK > 0: + statMsg = nodeB_prefix + 'NB showed ' + str(ulschOK) + ' "ULSCH received ok" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmleNBFailureMsg += statMsg + '\n' if dropNotEnoughRBs > 0: statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') From 9078a01e35ce7027838ab41d995de917a1699685 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 24 Jan 2020 16:03:42 +0100 Subject: [PATCH 187/343] CI: adding FDD-10MHz to RFSIM Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 2 +- ci-scripts/runTestOnVM.sh | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index cd1e4e9546..c4236a4e0e 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -435,7 +435,7 @@ function report_test { EPC_CONFIGS=("wS1 noS1") TRANS_MODES=("fdd") - BW_CASES=(05) + BW_CASES=(05 10) for CN_CONFIG in ${EPC_CONFIGS[@]} do for TMODE in ${TRANS_MODES[@]} diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 289f4500e6..e6440ffef9 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1757,7 +1757,7 @@ function run_test_on_vm { #BW_CASES=(05 10 20) EPC_CONFIGS=("wS1" "noS1") TRANS_MODES=("fdd") - BW_CASES=(05) + BW_CASES=(05 10) for CN_CONFIG in ${EPC_CONFIGS[@]} do if [[ $CN_CONFIG =~ .*wS1.* ]] @@ -1949,6 +1949,7 @@ function run_test_on_vm { TMODE="fdd" FREQUENCY=2680 BW_CASES=(05) + MBMS_STATUS=0 for BW in ${BW_CASES[@]} do @@ -1997,6 +1998,8 @@ function run_test_on_vm { terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + NB_UE_MBMS_MESSAGES=`egrep -c "TRIED TO PUSH MBMS DATA TO" $ARCHIVES_LOC/$CURRENT_UE_LOG_FILE` + if [ $NB_UE_MBMS_MESSAGES -eq 0 ]; then MBMS_STATUS=-1; fi done @@ -2008,6 +2011,13 @@ function run_test_on_vm { if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $MBMS_STATUS -eq 0 ] + then + echo "LTE MBMS RFSIM seems OK" + else + echo "LTE MBMS RFSIM seems to FAIL" + STATUS=-1 + fi if [ $STATUS -eq 0 ] then echo "LTE RFSIM seems OK" From 44cfdab5b7a21208c3c51eeee509e1ed03a8c0af Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 24 Jan 2020 11:22:14 +0100 Subject: [PATCH 188/343] CI: fix the missing 5G-NR UE build report Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 6 +++++- ci-scripts/reportBuildLocally.sh | 36 ++++++++++++++++---------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index fcfd56a4a2..8dfa5c4ec4 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -342,7 +342,11 @@ pipeline { always { script { dir ('archives') { - sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nrue_usrp red_hat" + if (fileExists('red_hat')) { + sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat" + } else { + sh "zip -r -qq vm_build_logs.zip basic_sim enb_usrp phy_sim cppcheck enb_eth ue_eth gnb_usrp nr_ue_usrp" + } } if(fileExists('archives/vm_build_logs.zip')) { archiveArtifacts artifacts: 'archives/vm_build_logs.zip' diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index b6c2ca104a..54372ac6ba 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -509,7 +509,7 @@ function report_build { sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder sca_summary_table_footer ./archives/cppcheck/cppcheck.xml - summary_table_header "OAI Build eNB -- USRP option" ./archives/enb_usrp + summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html @@ -521,7 +521,7 @@ function report_build { summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html summary_table_footer - summary_table_header "OAI Build basic simulator option" ./archives/basic_sim + summary_table_header "OAI Build: 4G LTE basic simulator option" ./archives/basic_sim summary_table_row "LTE SoftModem - Release 15" ./archives/basic_sim/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./basic_sim_row1.html summary_table_row "LTE UE SoftModem - Release 15" ./archives/basic_sim/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./basic_sim_row2.htm summary_table_row "Coding - Release 15" ./archives/basic_sim/coding.Rel15.txt "Built target coding" ./basic_sim_row3.html @@ -537,7 +537,7 @@ function report_build { summary_table_row "NVRAM - Release 15" ./archives/basic_sim/nvram.Rel15.txt "Built target nvram" ./basic_sim_row13.html summary_table_footer - summary_table_header "OAI Build Physical simulators option" ./archives/phy_sim + summary_table_header "OAI Build: 4G LTE / 5G NR Physical simulators option" ./archives/phy_sim summary_table_row "LTE DL Simulator - Release 15" ./archives/phy_sim/dlsim.Rel15.txt "Built target dlsim" ./phy_sim_row1.html summary_table_row "LTE UL Simulator - Release 15" ./archives/phy_sim/ulsim.Rel15.txt "Built target ulsim" ./phy_sim_row2.html summary_table_row "Coding - Release 15" ./archives/phy_sim/coding.Rel15.txt "Built target coding" ./phy_sim_row3.html @@ -581,7 +581,7 @@ function report_build { if [ -f archives/gnb_usrp/nr-softmodem.Rel15.txt ] then - summary_table_header "OAI Build gNB -- USRP option" ./archives/gnb_usrp + summary_table_header "OAI Build: 5G NR gNB -- USRP option" ./archives/gnb_usrp summary_table_row "5G NR SoftModem - Release 15" ./archives/gnb_usrp/nr-softmodem.Rel15.txt "Built target nr-softmodem" ./gnb_usrp_row1.html summary_table_row "Coding - Release 15" ./archives/gnb_usrp/coding.Rel15.txt "Built target coding" ./gnb_usrp_row2.html summary_table_row "OAI USRP device if - Release 15" ./archives/gnb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html @@ -592,20 +592,20 @@ function report_build { summary_table_footer fi - if [ -f archives/nrue_usrp/nr-uesoftmodem.Rel15.txt ] + if [ -f archives/nr_ue_usrp/nr-uesoftmodem.Rel15.txt ] then - summary_table_header "OAI Build 5G NR UE -- USRP option" ./archives/nrue_usrp - summary_table_row "5G NR UE SoftModem - Release 15" ./archives/nrue_usrp/nr-uesoftmodem.Rel15.txt "Built target nr-uesoftmodem" ./nrue_usrp_row1.html - summary_table_row "Coding - Release 15" ./archives/nrue_usrp/coding.Rel15.txt "Built target coding" ./nrue_usrp_row2.html - summary_table_row "OAI USRP device if - Release 15" ./archives/nrue_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./nrue_usrp_row3.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/nrue_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./nrue_usrp_row4.html - summary_table_row "NASMESH - Release 15" ./archives/nrue_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./nrue_usrp_row5.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/nrue_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./nrue_usrp_row6.html - summary_table_row "RB Tool - Release 15" ./archives/nrue_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./nrue_usrp_row7.html + summary_table_header "OAI Build: 5G NR UE -- USRP option" ./archives/nr_ue_usrp + summary_table_row "5G NR UE SoftModem - Release 15" ./archives/nr_ue_usrp/nr-uesoftmodem.Rel15.txt "Built target nr-uesoftmodem" ./nr_ue_usrp_row1.html + summary_table_row "Coding - Release 15" ./archives/nr_ue_usrp/coding.Rel15.txt "Built target coding" ./nr_ue_usrp_row2.html + summary_table_row "OAI USRP device if - Release 15" ./archives/nr_ue_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./nr_ue_usrp_row3.html + summary_table_row "OAI ETHERNET transport - Release 15" ./archives/nr_ue_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./nr_ue_usrp_row4.html + summary_table_row "NASMESH - Release 15" ./archives/nr_ue_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./nr_ue_usrp_row5.html + summary_table_row "Parameters Lib Config - Release 15" ./archives/nr_ue_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./nr_ue_usrp_row6.html + summary_table_row "RB Tool - Release 15" ./archives/nr_ue_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./nr_ue_usrp_row7.html summary_table_footer fi - summary_table_header "OAI Build eNB -- ETHERNET transport option" ./archives/enb_eth + summary_table_header "OAI Build: 4G LTE eNB -- ETHERNET transport option" ./archives/enb_eth summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html @@ -614,7 +614,7 @@ function report_build { summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html summary_table_footer - summary_table_header "OAI Build UE -- ETHERNET transport option" ./archives/ue_eth + summary_table_header "OAI Build: 4G LTE UE -- ETHERNET transport option" ./archives/ue_eth summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html @@ -631,7 +631,7 @@ function report_build { then echo "

Red Hat Enterprise Linux Server release 7.6) -- Summary

" >> ./build_results.html - summary_table_header "Red Hat -- OAI Build eNB -- USRP option" ./archives/red_hat + summary_table_header "OAI Build: 4G LTE eNB -- USRP option (RHEL)" ./archives/red_hat summary_table_row "LTE SoftModem - Release 15" ./archives/red_hat/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html summary_table_row "Coding - Release 15" ./archives/red_hat/coding.Rel15.txt "Built target coding" ./enb_usrp_rh_row2.html summary_table_row "OAI USRP device if - Release 15" ./archives/red_hat/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html @@ -671,9 +671,9 @@ function report_build { cat $DETAILS_TABLE >> ./build_results.html done fi - if [ -f ./nrue_usrp_row1.html ] || [ -f ./nrue_usrp_row2.html ] || [ -f ./nrue_usrp_row3.html ] || [ -f ./nrue_usrp_row4.html ] + if [ -f ./nr_ue_usrp_row1.html ] || [ -f ./nr_ue_usrp_row2.html ] || [ -f ./nr_ue_usrp_row3.html ] || [ -f ./nr_ue_usrp_row4.html ] then - for DETAILS_TABLE in `ls ./nrue_usrp_row*.html` + for DETAILS_TABLE in `ls ./nr_ue_usrp_row*.html` do cat $DETAILS_TABLE >> ./build_results.html done From 8a6f346ec49e7ce0521501cff45fff40b697b84d Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 24 Jan 2020 20:04:00 +0100 Subject: [PATCH 189/343] nr-ip-ul nos1: Small modification to be able to block the random traffic (which is generated when there is no Uplink IP traffic at the UE) at the MAC layer of the gNB --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 19 +++++++++++-------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 3 +-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 +++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 077f417a99..1d4fdcd538 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -45,7 +45,7 @@ //#define DEBUG_SCFDMA //#define DEBUG_PUSCH_MAPPING -#define DEBUG_MAC_PDU +//#define DEBUG_MAC_PDU //extern int32_t uplink_counter; @@ -174,6 +174,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (IS_SOFTMODEM_NOS1){ data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame, slot, 0, ulsch_input_buffer, harq_process_ul_ue->TBS/8, &access_mode); + //IP traffic to be transmitted if(data_existing){ //harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char)); memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8); @@ -186,16 +187,20 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, printf("\n"); #endif } + //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity else{ - //Use different rnti for the random (non-IP traffic) in noS1 mode, in order to use it as a filter - //to block this traffic from being forwarded to the MAC layer of the gNB - ulsch_ue->rnti = 0x1111; + //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid + //and block this traffic from being forwarded to the upper layers at the gNB + uint16_t payload_offset = 5; LOG_E(PHY, "Random data to be tranmsitted: \n"); - for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { + //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver + for (i = 0; ia[i] = 0; + + for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) { harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); } - data_existing = 1; } } //else if(uplink_counter == 0){ //if(!IS_SOFTMODEM_NOS1){ @@ -205,7 +210,6 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); } - data_existing = 1; //uplink_counter++; } } else { @@ -219,7 +223,6 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// - //if(data_existing){ nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid); /////////// diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 2f30b6af39..3c727738cf 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -289,7 +289,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id //gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b else if(gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->b!=NULL){ LOG_D(PHY, "ULSCH received ok \n"); - if(IS_SOFTMODEM_NOS1 && gNB->ulsch[UE_id][0]->rnti == 0x1234){ + if(IS_SOFTMODEM_NOS1){ //&& gNB->ulsch[UE_id][0]->rnti == 0x1234 nr_fill_crc_indication (gNB, UE_id, frame_rx, slot_rx, 0); nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index a116e7b8ca..568ef5f736 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2502,7 +2502,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } // UE_mode==PUSCH */ - //if(data_existing){ LOG_I(PHY, "Sending data \n"); nr_ue_pusch_common_procedures(ue, harq_pid, @@ -2510,7 +2509,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, thread_id, gNB_id, &ue->frame_parms); - //} + diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 8010a1f714..4b966fd7b1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2995,6 +2995,8 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Generate header // if (num_sdus>0) { + // cycle through SDUs and place in ulsch_buffer + if (sdu_length_total) { payload_offset = nr_generate_ulsch_header(ulsch_buffer, // mac header num_sdus, // num sdus short_padding, // short pading @@ -3012,8 +3014,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, short_padding, post_padding, bsr_len, phr_len, buflen - sdu_length_total - payload_offset); - // cycle through SDUs and place in ulsch_buffer - if (sdu_length_total) { + memcpy(&ulsch_buffer[payload_offset], ulsch_buff, sdu_length_total); } From 4eaadf8d8219fb6e598435ae906abf9759c00781 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Sun, 26 Jan 2020 13:41:36 +0100 Subject: [PATCH 190/343] CI: fixing slave pipelines Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-tmp-full-ran | 8 ++++---- ci-scripts/Jenkinsfile-tmp-multi-enb | 12 ++++++------ ci-scripts/Jenkinsfile-tmp-ran | 8 ++++---- ci-scripts/Jenkinsfile-tmp-ue | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran index 096ff7f52d..15ad0379af 100644 --- a/ci-scripts/Jenkinsfile-tmp-full-ran +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -51,7 +51,7 @@ termStatusArray[termOAIUE] = false def eNB_Repository def eNB_Branch def eNB_CommitID -def ranAllowMergeRequestProcess = false +def eNB_AllowMergeRequestProcess = false def eNB_TargetBranch def doEpcLogCollection = true @@ -130,8 +130,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - ranAllowMergeRequestProcess = params.eNB_mergeRequest - if (ranAllowMergeRequestProcess) { + eNB_AllowMergeRequestProcess = params.eNB_mergeRequest + if (eNB_AllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -168,7 +168,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (ranAllowMergeRequestProcess) { + if (eNB_AllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb index 4df2006ed2..c3b825ec06 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb @@ -41,7 +41,7 @@ def ciSmartPhoneResource = params.smartphonesResource def eNB_Repository def eNB_Branch def eNB_CommitID -def ranAllowMergeRequestProcess = false +def eNB_AllowMergeRequestProcess = false def eNB_TargetBranch pipeline { @@ -124,8 +124,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - ranAllowMergeRequestProcess = params.eNB_mergeRequest - if (ranAllowMergeRequestProcess) { + eNB_AllowMergeRequestProcess = params.eNB_mergeRequest + if (eNB_AllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -157,7 +157,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (ranAllowMergeRequestProcess) { + if (eNB_AllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { @@ -198,12 +198,12 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${ranAllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { if (fileExists(xmlFile)) { try { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${ranAllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { currentBuild.result = 'FAILURE' buildStageStatus = false diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index ad852b8e93..a93a3a3758 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -54,7 +54,7 @@ termStatusArray[termHSS] = false def eNB_Repository def eNB_Branch def eNB_CommitID -def ranAllowMergeRequestProcess = false +def eNB_AllowMergeRequestProcess = false def eNB_TargetBranch pipeline { @@ -145,8 +145,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - ranAllowMergeRequestProcess = params.eNB_mergeRequest - if (ranAllowMergeRequestProcess) { + eNB_AllowMergeRequestProcess = params.eNB_mergeRequest + if (eNB_AllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -178,7 +178,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (ranAllowMergeRequestProcess) { + if (eNB_AllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { diff --git a/ci-scripts/Jenkinsfile-tmp-ue b/ci-scripts/Jenkinsfile-tmp-ue index e22cd45615..e5e456cf7f 100644 --- a/ci-scripts/Jenkinsfile-tmp-ue +++ b/ci-scripts/Jenkinsfile-tmp-ue @@ -54,7 +54,7 @@ termStatusArray[termHSS] = false def eNB_Repository def eNB_Branch def eNB_CommitID -def ranAllowMergeRequestProcess = false +def eNB_AllowMergeRequestProcess = false def eNB_TargetBranch pipeline { @@ -116,8 +116,8 @@ pipeline { } echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { - ranAllowMergeRequestProcess = params.eNB_mergeRequest - if (ranAllowMergeRequestProcess) { + eNB_AllowMergeRequestProcess = params.eNB_mergeRequest + if (eNB_AllowMergeRequestProcess) { if (params.eNB_TargetBranch != null) { eNB_TargetBranch = params.eNB_TargetBranch } else { @@ -149,7 +149,7 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" - if (ranAllowMergeRequestProcess) { + if (eNB_AllowMergeRequestProcess) { sh "git fetch" sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" } else { From 1d4d8d685f1cfafcb9bdd61b49120b881e09fc6f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Jan 2020 10:13:16 +0100 Subject: [PATCH 191/343] add drb 1 with nea0 phone was not happy with other settings --- openair2/RRC/NR/rrc_gNB_reconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 98744abd2a..9632d7f0c8 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -64,7 +64,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; - RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=5; + RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1; RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC)); *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true; RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); @@ -2044,7 +2044,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity=5; - drb_ToAddMod->drb_Identity = 4; + drb_ToAddMod->drb_Identity = 1; drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); @@ -2073,7 +2073,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); - rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea2; + rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; From 615f365b375e6b2fb92f665748ff8828eeb79212 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 27 Jan 2020 11:13:06 +0100 Subject: [PATCH 192/343] adding support for beam selection in usrp_lib --- executables/nr-ru.c | 4 ++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 56 +++++++++++++------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index b2eb471016..7e2ddb0645 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -754,6 +754,10 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { nextslot_type == NR_UPLINK_SLOT) { flags = 3; // end of burst } + + // the beam index is written in bits 8-10 of the flags + // the following choice cycles through the beams every slot, starting with beam 3 + flags |= ((3+slot)&7)<<8; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e2418bcb76..f3395d9c93 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -276,14 +276,17 @@ static int trx_usrp_start(openair0_device *device) { // 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); + s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff); + //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually) + s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff); //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); + // set the output pins to 0 + s->usrp->set_gpio_attr("FP0", "OUT", 3<<7, 0xf80); + // 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)); @@ -404,10 +407,19 @@ static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp ti @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(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { +static int trx_usrp_write(openair0_device *device, + openair0_timestamp timestamp, + void **buff, + int nsamps, + int cc, + int flags) { int ret=0; usrp_state_t *s = (usrp_state_t *)device->priv; int nsamps2; // aligned to upper 32 or 16 byte boundary + + int flags_lsb = flags&0xff; + int flags_msb = (flags>>8)&0xff; + #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -441,40 +453,48 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, boolean_t first_packet_state=false,last_packet_state=false; - if (flags == 2) { // start of burst + if (flags_lsb == 2) { // start of burst // s->tx_md.start_of_burst = true; // s->tx_md.end_of_burst = false; first_packet_state = true; last_packet_state = false; - } else if (flags == 3) { // end of burst + } else if (flags_lsb == 3) { // end of burst //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 == 4) { // start and end - // s->tx_md.start_of_burst = true; - // s->tx_md.end_of_burst = true; + } else if (flags_lsb == 4) { // start and end + // 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; + } else if (flags_lsb==1) { // middle of burst + // 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_lsb==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; } + // push GPIO bits 7-9 from flags_msb + int gpio789=(flags_msb&7)<<7; + s->tx_md.has_time_spec = true; 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++; + s->usrp->set_command_time(s->tx_md.time_spec); + s->usrp->set_gpio_attr("FP0", "OUT", gpio789, 0xfff); + s->usrp->clear_command_time(); + if (cc>1) { std::vector buff_ptrs; From 6970bea6794c76e957af6e35e554692b5f0a0970 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Jan 2020 12:20:08 +0100 Subject: [PATCH 193/343] fix value in fill_default_secondaryCellGroup --- openair2/RRC/NR/rrc_gNB_reconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 9632d7f0c8..6d52f47a18 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -106,7 +106,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = NULL; secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config)); secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf80; - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf320; + secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf320; secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config)); secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList)); From f594ae8b82a4d56d619a72e9126363c939ce2c3a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Jan 2020 12:24:48 +0100 Subject: [PATCH 194/343] release DRB1 on LTE side of things to configure UE for endc --- openair2/RRC/LTE/rrc_eNB_endc.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB_endc.c b/openair2/RRC/LTE/rrc_eNB_endc.c index c6efb2b166..d6fb910507 100644 --- a/openair2/RRC/LTE/rrc_eNB_endc.c +++ b/openair2/RRC/LTE/rrc_eNB_endc.c @@ -47,12 +47,16 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, LTE_RRCConnectionReconfiguration_t *r; int trans_id; LTE_RadioResourceConfigDedicated_t rrcd; +#if 0 LTE_DRB_ToAddModList_t drb_list; struct LTE_DRB_ToAddMod drb; long eps_bearer_id; struct LTE_RLC_Config rlc; long lcid; struct LTE_LogicalChannelConfig lc; +#endif + LTE_DRB_ToReleaseList_t drb_list; + LTE_DRB_Identity_t drb; struct LTE_LogicalChannelConfig__ul_SpecificParameters ul_params; long lcg; struct LTE_RadioResourceConfigDedicated__mac_MainConfig mac; @@ -62,8 +66,10 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, memset(&rrcd, 0, sizeof(rrcd)); memset(&drb_list, 0, sizeof(drb_list)); memset(&drb, 0, sizeof(drb)); +#if 0 memset(&rlc, 0, sizeof(rlc)); memset(&lc, 0, sizeof(lc)); +#endif memset(&ul_params, 0, sizeof(ul_params)); memset(&mac, 0, sizeof(mac)); memset(&mac_ext4, 0, sizeof(mac_ext4)); @@ -83,6 +89,7 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, r->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8; r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated = &rrcd; +#if 0 rrcd.drb_ToAddModList = &drb_list; eps_bearer_id = 5; @@ -93,6 +100,8 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, drb.logicalChannelIdentity = &lcid; drb.logicalChannelConfig = &lc; + ASN_SEQUENCE_ADD(&drb_list.list, &drb); + rlc.present = LTE_RLC_Config_PR_am; rlc.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; rlc.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; @@ -102,6 +111,12 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rlc.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; lc.ul_SpecificParameters = &ul_params; +#endif + + /* release drb 1 */ + drb = 1; + ASN_SEQUENCE_ADD(&drb_list.list, &drb); + rrcd.drb_ToReleaseList = &drb_list; ul_params.priority = 12; ul_params.prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; @@ -202,13 +217,13 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, #endif +#if 0 OCTET_STRING_t nr2_conf; unsigned char nr2_buf[4] = { 0, 0, 0, 0 }; cr_1510.nr_RadioBearerConfig2_r15 = &nr2_conf; nr2_conf.buf = nr2_buf; nr2_conf.size = 4; - - ASN_SEQUENCE_ADD(&drb_list.list, &drb); +#endif enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, From 9e1c94835c5e0f5c2ed1086755b88964a1a551b0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Jan 2020 14:39:50 +0100 Subject: [PATCH 195/343] fix for lte UE compilation --- targets/RT/USER/lte-uesoftmodem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index cd96b8adf4..cd0db857d7 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -123,7 +123,7 @@ clock_source_t clock_source = internal,time_source=internal; unsigned int mmapped_dma=0; -uint32_t downlink_frequency[MAX_NUM_CCs][4]; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; From e21b00adab40454c983f0db50c9131e561edf748 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 28 Jan 2020 17:47:15 +0100 Subject: [PATCH 196/343] Bugfix - missing call to mac_rlc_data_ind in the noS1 mode: - now the UE is passing again data to the upper layers in noS1 mode - minor cleanups --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 6 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 1 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 159 +++++------------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 14 +- 4 files changed, 51 insertions(+), 129 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index acb63ea4dc..7202f2e520 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -94,9 +94,9 @@ typedef struct { // 38.321 ch6.2.1, 38.331 #define DL_SCH_LCID_CCCH 0x00 -#define DL_SCH_LCID_SRB1 0x01 -#define DL_SCH_LCID_SRB2 0x02 -#define DL_SCH_LCID_SRB3 0x03 +#define DL_SCH_LCID_DCCH 0x01 +#define DL_SCH_LCID_DCCH1 0x02 +#define DL_SCH_LCID_DTCH 0x03 #define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F #define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30 #define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index e74531da16..e610db8008 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -142,6 +142,7 @@ void nr_ue_send_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP, uint8_ void nr_ue_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t *pduP, uint16_t mac_pdu_len, uint8_t eNB_index, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 77e5059772..79851c7179 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -30,6 +30,8 @@ * \warning */ +#include "executables/nr-softmodem.h" + /* MAC related headers */ #include "mac_proto.h" #include "LAYER2/NR_MAC_COMMON/nr_mac.h" @@ -52,11 +54,6 @@ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" -/* TODO remove this for debugging purpose -#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" -#include "LAYER2/MAC/mac.h" -*/ - #include #include @@ -2055,10 +2052,6 @@ void nr_ue_send_sdu(module_id_t module_idP, LOG_D(MAC, "Handling PDU frame %d slot %d\n", frameP, ttiP); - // Changes wrt LTE: replaced subframeP with ttiP - // TODO double check this and eventually create a type for TTI (tti_t) - // Note: pdu_len was previously named sdu and sdu_len - uint8_t * pduP = pdu; NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); @@ -2098,7 +2091,8 @@ void nr_ue_send_sdu(module_id_t module_idP, // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, gNB_index, ul_time_alignment); + if (pduP != NULL) + nr_ue_process_mac_pdu(module_idP, CC_id, frameP, pduP, pdu_len, gNB_index, ul_time_alignment); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); @@ -2112,6 +2106,7 @@ void nr_ue_send_sdu(module_id_t module_idP, void nr_ue_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t *pduP, uint16_t mac_pdu_len, uint8_t gNB_index, @@ -2120,12 +2115,9 @@ void nr_ue_process_mac_pdu( // This function is adapting code from the old // parse_header(...) and ue_send_sdu(...) functions of OAI LTE - uint8_t *pdu_ptr = pduP; + uint8_t *pdu_ptr = pduP, rx_lcid, done = 0, i; int pdu_len = mac_pdu_len; - - uint16_t mac_ce_len; - uint16_t mac_subheader_len; - uint16_t mac_sdu_len; + uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; //NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); //uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; @@ -2155,14 +2147,14 @@ void nr_ue_process_mac_pdu( // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; // F: lenght of L is 0:8 or 1:16 bits wide // R: Reserved bit, set to zero. - - uint8_t done = 0; while (!done && pdu_len > 0){ mac_ce_len = 0; mac_subheader_len = 1; // default to fixed-length subheader = 1-oct mac_sdu_len = 0; - switch(((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID){ + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + + switch(rx_lcid){ // MAC CE /*#ifdef DEBUG_HEADER_PARSING @@ -2178,24 +2170,6 @@ void nr_ue_process_mac_pdu( mac_subheader_len = 3; } - /*LOG_D(MAC, "[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n", - module_idP, UE_mac_inst[module_idP].crnti, frameP, eNB_index, rx_lengths[i]);*/ - - /*#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - int j; - for (j = 0; j < rx_lengths[i]; j++) { - LOG_T(MAC, "%x.", (uint8_t) payload_ptr[j]); - } - LOG_T(MAC, "\n"); - #endif*/ - - /*mac_rrc_data_ind_ue(module_idP, - CC_id, - frameP, subframeP, - UE_mac_inst[module_idP].crnti, - CCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], eNB_index, 0);*/ break; case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH: @@ -2306,48 +2280,6 @@ void nr_ue_process_mac_pdu( // 38.321 Ch6.1.3.3 mac_ce_len = 6; - // TODO index should be shifted by 1 - // LOG_I(MAC,"[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5]); - - // TODO RACH is missing - - /*if (UE_mac_inst[module_idP].RA_active == 1) { - LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", - module_idP, frameP); - UE_mac_inst[module_idP].RA_active = 0; - // check if RA procedure has finished completely (no contention) - tx_sdu = &UE_mac_inst[module_idP].CCCH_pdu.payload[3]; - - //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits) - // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or SCH_SUBHEADER_SHORT) - for (i = 0; i < 6; i++) - if (tx_sdu[i] != payload_ptr[i]) { - LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP); - if(nfapi_mode == 3) { // phy_stub mode - // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to - // PRACH state. - LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n"); - UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH; - //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; - } - else{ - ra_failed(module_idP, CC_id, eNB_index); - } - UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); - return; - } - LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n", module_idP, frameP); - UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; - if(nfapi_mode == 3){ - // phy_stub mode - // Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH - UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH; - } else { // Full stack mode - ra_succeeded(module_idP,CC_id,eNB_index); - } - }*/ - break; case DL_SCH_LCID_PADDING: done = 1; @@ -2355,43 +2287,13 @@ void nr_ue_process_mac_pdu( break; // MAC SDU - /* TODO double check SRBs 1-3 & DRB 1-3 */ - case DL_SCH_LCID_SRB1: - // check if LCID is valid at current time. - - /*if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) { - - LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", - module_idP, frameP, rx_lcids[i], eNB_index, rx_lengths[i]); - - mac_rlc_data_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, ENB_FLAG_NO, - MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); - } else if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1)) { - LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", - module_idP, frameP, rx_lcids[i], eNB_index, rx_lengths[i]); - - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - int j; - for (j = 0; j < rx_lengths[i]; j++) - LOG_T(MAC, "%x.", (unsigned char) payload_ptr[j]); - LOG_T(MAC, "\n"); - #endif - - mac_rlc_data_ind(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - rx_lcids[i], - (char *) payload_ptr, rx_lengths[i], 1, NULL); - }*/ - - case UL_SCH_LCID_SRB2: + case DL_SCH_LCID_DCCH: // check if LCID is valid at current time. - case UL_SCH_LCID_SRB3: + + case DL_SCH_LCID_DCCH1: // check if LCID is valid at current time. + default: // check if LCID is valid at current time. if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ @@ -2405,8 +2307,37 @@ void nr_ue_process_mac_pdu( mac_subheader_len = 2; } - // DRB LCID by RRC - break; + LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len); + + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + + for (i = 0; i < 32; i++) + LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); + + LOG_T(MAC, "\n"); + #endif + + if (IS_SOFTMODEM_NOS1){ + if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DTCH) { + + mac_rlc_data_ind(module_idP, + 0x1234, + gNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + } else { + LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index); + } + } + + break; } pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 5fb7fdeef5..abfcbd5fee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -21,9 +21,9 @@ /*! \file gNB_scheduler_phytest.c * \brief gNB scheduling procedures in phy_test mode - * \author Guy De Souza + * \author Guy De Souza, G. Casati * \date 07/2018 - * \email: desouza@eurecom.fr + * \email: desouza@eurecom.fr, guido.casati@iis.fraunhofer.de * \version 1.0 * @ingroup _mac */ @@ -311,16 +311,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //through the LTE stack if (IS_SOFTMODEM_NOS1){ - /* TODO - // RLC data on DCCH - if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { - }*/ - - /* TODO - // RLC data on DCCH1 - if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { - }*/ - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); From 51f5a5b30cde323dda4656e5d4030abfdb8baa16 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 29 Jan 2020 12:25:37 +0100 Subject: [PATCH 197/343] scs parameters from BW not from RB --- openair1/PHY/INIT/nr_parms.c | 107 +++++++++++++++-------------------- 1 file changed, 45 insertions(+), 62 deletions(-) diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 246e3323ee..cfc96168c6 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -83,7 +83,7 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) return symbol; } -void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) +void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) { switch(mu) { @@ -107,15 +107,13 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu); } - switch(fp->N_RB_DL){ - case 11: - case 24: - case 38: - case 78: - case 51: - case 65: - - case 106: //40 MHz + switch(bw){ + case 5: + case 15: + case 20: + case 25: + case 30: + case 40: //40 MHz if (fp->threequarter_fs) { fp->ofdm_symbol_size = 1536; fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 ) @@ -130,11 +128,11 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) } break; - case 133: - case 162: - case 189: + case 50: + case 60: + case 70: - case 217: //80 MHz + case 80: //80 MHz if (fp->threequarter_fs) { fp->ofdm_symbol_size = 3072; fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 ) @@ -149,14 +147,14 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) } break; - case 245: + case 90: AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu); fp->ofdm_symbol_size = 4096; fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 ) fp->nb_prefix_samples0 = 352; fp->nb_prefix_samples = 288; break; - case 273: + case 100: AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu); fp->ofdm_symbol_size = 4096; fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 ) @@ -172,19 +170,19 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; - switch(fp->N_RB_DL){ //FR1 bands only - case 11: - case 18: - case 38: - case 24: - case 31: - case 51: - case 65: - case 79: - case 93: - case 107: - case 121: - case 135: + switch(bw){ //FR1 bands only + case 10: + case 15: + case 20: + case 25: + case 30: + case 40: + case 50: + case 60: + case 70: + case 80: + case 90: + case 100: default: AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp); } @@ -194,14 +192,14 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; fp->ssb_type = nr_ssb_type_D; - switch(fp->N_RB_DL){ - case 66: + switch(bw){ + case 100: fp->ofdm_symbol_size = 1024; fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 ) fp->nb_prefix_samples0 = 88; fp->nb_prefix_samples = 72; break; - case 32: + case 50: fp->ofdm_symbol_size = 512; fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 ) fp->nb_prefix_samples0 = 44; @@ -224,21 +222,22 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu) } -int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, - nfapi_nr_config_request_scf_t* cfg, - int mu0, - int Ncp, - int N_RB_DL, - int N_RB_UL) - +int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, + NR_DL_FRAME_PARMS *fp) { - int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : mu0; + fp->frame_type = cfg->cell_config.frame_duplex_type.value; + fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[1].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[0].ssb_mask.value ; + fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; + fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; + + int Ncp = NFAPI_CP_NORMAL; + int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : 0; #if DISABLE_LOG_X - printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp); + printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp); #else - LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp); + LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp); #endif if (Ncp == NFAPI_CP_EXTENDED) @@ -246,11 +245,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->half_frame_bit = 0; // half frame bit initialized to 0 here fp->numerology_index = mu; - fp->Ncp = Ncp; - fp->N_RB_DL = N_RB_DL; - fp->N_RB_UL = N_RB_UL; - set_scs_parameters(fp, mu); + set_scs_parameters(fp, mu, cfg->carrier_config.dl_bandwidth.value); fp->slots_per_frame = 10* fp->slots_per_subframe; @@ -268,6 +264,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; + fp->Ncp = Ncp; + // definition of Lmax according to ts 38.213 section 4.1 if (fp->dl_CarrierFreq < 6e9) { if(fp->frame_type && (fp->ssb_type==2)) @@ -285,22 +283,7 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->N_ssb += ((fp->L_ssb >> p) & 0x01); return 0; -} -int nr_init_frame_parms(nfapi_nr_config_request_scf_t* config, - NR_DL_FRAME_PARMS *fp) -{ - - fp->frame_type = config->cell_config.frame_duplex_type.value; - fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask.value)<<32) | config->ssb_table.ssb_mask_list[0].ssb_mask.value ; - int N_RB_DL = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - int N_RB_UL = config->carrier_config.ul_grid_size[config->ssb_config.scs_common.value].value; - return nr_init_frame_parms0(fp, - config, - 0, - NFAPI_CP_NORMAL, - N_RB_DL, - N_RB_UL); } int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, @@ -336,7 +319,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Ncp = Ncp; - set_scs_parameters(fp,fp->numerology_index); + set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth); fp->slots_per_frame = 10* fp->slots_per_subframe; From 0f77c961b5e1651b246376ec5200d5b06fc41846 Mon Sep 17 00:00:00 2001 From: laurent Date: Wed, 29 Jan 2020 18:56:20 +0100 Subject: [PATCH 198/343] fix segv in drs_modulation.c --- openair1/PHY/LTE_TRANSPORT/if5_tools.c | 987 +++++++++++++++++- .../PHY/LTE_UE_TRANSPORT/drs_modulation.c | 13 +- 2 files changed, 989 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index fcbf639a7e..1e0dd9db1b 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -41,9 +41,992 @@ //#define DEBUG_UL_MOBIPASS #define SUBFRAME_SKIP_NUM_MOBIPASS 8 -const uint8_t lin2alaw_if5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; +const uint8_t lin2alaw_if5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, +214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, +210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, +219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, +199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, +195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, +204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, +200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, +245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, +247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, +241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, +243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, +254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, +248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, +250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, +229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, +228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, +231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, +230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, +225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, +224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, +226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, +237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, +236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, +239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, +238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, +233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, +233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, +232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, +235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, +234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, +149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, +149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, +148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, +148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, +151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, +151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, +150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, +150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, +145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, +145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, +144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, +144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, +144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, +147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, +147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, +146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, +146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, +157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, +157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, +156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, +156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, +159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, +159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, +153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, +153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, +152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, +152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, +152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, +155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, +155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, +154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, +154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, +133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, +133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, +133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, +133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, +132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, +132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, +132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, +132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, +135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, +135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, +135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, +135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, +135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, +134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, +134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, +134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, +134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, +129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, +129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, +129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, +129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, +128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, +128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, +128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, +128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, +131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, +131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, +131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, +131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, +131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, +130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, +130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, +130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, +130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, +141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, +141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, +141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, +141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, +143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, +143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, +143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, +143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, +142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, +142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, +142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, +142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, +137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, +137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, +137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, +137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, +136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, +136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, +136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, +136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, +136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, +139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, +139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, +139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, +139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, +138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, +138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, +138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, +138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, +181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, +180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, +183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, +182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, +179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, +178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, +189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, +190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, +185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, +184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, +187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, +186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, +165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, +164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, +167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, +166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, +161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, +163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, +162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, +173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, +172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, +175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, +169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, +171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, +170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, +42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, +41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, +47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, +34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, +33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, +38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, +39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, +36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, +59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, +57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, +62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, +62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, +62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, +62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, +62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, +62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, +60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, +61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, +49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, +54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, +55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, +9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, +9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, +31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, +31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, +18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, +18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, +19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, +19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, +17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, +17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, +20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, +106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, +107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, +104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, +105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, +110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, +111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, +108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, +109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, +98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, +99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, +96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, +97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, +102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, +103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, +100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, +101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, +122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, +120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, +124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, +114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, +112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, +118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, +119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, +117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, +78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, +66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, +71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, +88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, +81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; -const uint16_t alaw2lin_if5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; +const uint16_t alaw2lin_if5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, +48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, +65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, +64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, +30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, +152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; struct timespec start_comp, start_decomp, end_comp, end_decomp; int dummy_cnt = 0; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c index a15166eed5..77c0d9ca7a 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c @@ -62,11 +62,10 @@ int generate_drs_pusch(PHY_VARS_UE *ue, LTE_DL_FRAME_PARMS *fp = (ue==NULL) ? frame_parms : &ue->frame_parms; int32_t *txF = (ue==NULL) ? txdataF[ant] : ue->common_vars.txdataF[ant]; uint32_t u,v,alpha_ind; - uint32_t u0 = (ue==NULL) ? 0 : frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]; - uint32_t u1 = (ue==NULL) ? 0 : frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]; - uint32_t v0 = (ue==NULL) ? 0 : frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; - uint32_t v1 = (ue==NULL) ? 0 : frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; - + uint32_t u0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]; + uint32_t u1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]; + uint32_t v0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; int32_t ref_re,ref_im; uint8_t harq_pid = (proc == NULL) ? 0: subframe2harq_pid(fp,proc->frame_tx,subframe); @@ -82,10 +81,6 @@ int generate_drs_pusch(PHY_VARS_UE *ue, fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+1]+ ((ue->ulsch[0]->cooperation_flag==2)?10:0)+ ant*6) % 12; - u0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]; - u1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]; - v0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; - v1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; } From 538e08d0a5c8e8a350e06474dc56a2314e777c3c Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 29 Jan 2020 22:05:54 +0100 Subject: [PATCH 199/343] Revert "adding support for beam selection in usrp_lib" This reverts commit 615f365b375e6b2fb92f665748ff8828eeb79212. --- executables/nr-ru.c | 4 -- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 56 +++++++------------- 2 files changed, 18 insertions(+), 42 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 7e2ddb0645..b2eb471016 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -754,10 +754,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { nextslot_type == NR_UPLINK_SLOT) { flags = 3; // end of burst } - - // the beam index is written in bits 8-10 of the flags - // the following choice cycles through the beams every slot, starting with beam 3 - flags |= ((3+slot)&7)<<8; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index f3395d9c93..e2418bcb76 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -276,17 +276,14 @@ static int trx_usrp_start(openair0_device *device) { // setup GPIO for TDD, GPIO(4) = ATR_RX //set data direction register (DDR) to output - s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff); - //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually) - s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff); + s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); + //set control register to ATR + s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0x7f); //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); - // set the output pins to 0 - s->usrp->set_gpio_attr("FP0", "OUT", 3<<7, 0xf80); - // 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)); @@ -407,19 +404,10 @@ static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp ti @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(openair0_device *device, - openair0_timestamp timestamp, - void **buff, - int nsamps, - int cc, - int flags) { +static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { int ret=0; usrp_state_t *s = (usrp_state_t *)device->priv; int nsamps2; // aligned to upper 32 or 16 byte boundary - - int flags_lsb = flags&0xff; - int flags_msb = (flags>>8)&0xff; - #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -453,48 +441,40 @@ static int trx_usrp_write(openair0_device *device, boolean_t first_packet_state=false,last_packet_state=false; - if (flags_lsb == 2) { // start of burst + if (flags == 2) { // start of burst // s->tx_md.start_of_burst = true; // s->tx_md.end_of_burst = false; first_packet_state = true; last_packet_state = false; - } else if (flags_lsb == 3) { // end of burst + } else if (flags == 3) { // end of burst //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_lsb == 4) { // start and end - // s->tx_md.start_of_burst = true; - // s->tx_md.end_of_burst = true; + } else if (flags == 4) { // start and end + // 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_lsb==1) { // middle of burst - // s->tx_md.start_of_burst = false; - // s->tx_md.end_of_burst = false; + } else if (flags==1) { // middle of burst + // 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_lsb==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; } - // push GPIO bits 7-9 from flags_msb - int gpio789=(flags_msb&7)<<7; - s->tx_md.has_time_spec = true; 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++; - s->usrp->set_command_time(s->tx_md.time_spec); - s->usrp->set_gpio_attr("FP0", "OUT", gpio789, 0xfff); - s->usrp->clear_command_time(); - if (cc>1) { std::vector buff_ptrs; From 5006aa029139f13636ed719947d22742f06b6c0d Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 29 Jan 2020 22:06:28 +0100 Subject: [PATCH 200/343] harmonizing TDD configuration for 106 with the one for 217 PRB --- .../CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index da38d5546c..22df17cd9f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -171,10 +171,10 @@ gNBs = # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 dl_UL_TransmissionPeriodicity = 6; - nrofDownlinkSlots = 2; - nrofDownlinkSymbols = 1; - nrofUplinkSlots = 7; - nrofUplinkSymbols = 7; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; ssPBCH_BlockPower = 10; } From 9331d38d85a2b85c20aeb897adfe9fdf4d3d2e3d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 30 Jan 2020 15:10:35 +0100 Subject: [PATCH 201/343] CI: fixing a few compilation warnings Signed-off-by: Raphael Defosseux --- executables/nr-gnb.c | 5 +---- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 6 +++--- openair2/RRC/LTE/rrc_eNB_S1AP.c | 3 +++ 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 95cff7cf58..a1e05d4dc3 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -412,10 +412,8 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot RU_t *ru; RU_proc_t *ru_proc; - int waitret,ret; + int waitret = 0,ret; - - // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); while (proc->instance_cnt_RUs < 0) { @@ -425,7 +423,6 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); if (waitret == ETIMEDOUT) { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 56c7b4214b..1bb544d204 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -358,7 +358,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, void nr_fill_crc_indication (PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t crc_flag){ // pthread_mutex_lock(&gNB->UL_INFO_mutex); - nfapi_crc_indication_pdu_t *pdu = &gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; + // nfapi_crc_indication_pdu_t *pdu = &gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; // gNB->UL_INFO.crc_ind.sfn_sf = frame<<4 | subframe; // gNB->UL_INFO.crc_ind.header.message_id = NFAPI_CRC_INDICATION; // gNB->UL_INFO.crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 79851c7179..579f5c6928 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2067,8 +2067,8 @@ void nr_ue_send_sdu(module_id_t module_idP, if (opt_enabled) { trace_pdu(DIRECTION_DOWNLINK, pduP, pdu_len, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP - LOG_D(OPT, "[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", + (int) UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP + LOG_D(OPT, "[UE %d][DLSCH] Frame %d trace pdu for rnti %p with size %d\n", module_idP, frameP, UE_mac_inst[module_idP].cs_RNTI, pdu_len); } @@ -2115,7 +2115,7 @@ void nr_ue_process_mac_pdu( // This function is adapting code from the old // parse_header(...) and ue_send_sdu(...) functions of OAI LTE - uint8_t *pdu_ptr = pduP, rx_lcid, done = 0, i; + uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; int pdu_len = mac_pdu_len; uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 2512cf6820..11c6d27f5f 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1686,6 +1686,9 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms memcpy(&e_rab_release_params[0], &(S1AP_E_RAB_RELEASE_COMMAND (msg_p).e_rab_release_params[0]), sizeof(e_rab_release_t)*S1AP_MAX_E_RAB); eNB_ue_s1ap_id = S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id; nb_e_rabs_torelease = S1AP_E_RAB_RELEASE_COMMAND (msg_p).nb_e_rabs_torelease; + if (nb_e_rabs_torelease > S1AP_MAX_E_RAB) { + return -1; + } ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); if(ue_context_p != NULL) { From 5e9b64c0d3084d7fcb0de389d45b72923154aeec Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 30 Jan 2020 17:08:26 +0100 Subject: [PATCH 202/343] Proper patch on the waitret for warning compilation --- executables/nr-gnb.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index a1e05d4dc3..46689b137a 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -412,18 +412,28 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot RU_t *ru; RU_proc_t *ru_proc; - int waitret = 0,ret; - -// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time + int waitret = 0, ret = 0, time_ns = 1000*1000; + struct timespec now, abstime; + + // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); + time_ns = time_ns/gNB->frame_parms.slots_per_subframe; AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); while (proc->instance_cnt_RUs < 0) { - pthread_cond_wait(&proc->cond_RUs,&proc->mutex_RUs_tx); // this unlocks mutex_rxtx while waiting and then locks it again + clock_gettime(CLOCK_REALTIME, &now); + abstime.tv_sec = now.tv_sec; + abstime.tv_nsec = now.tv_nsec + time_ns; + + if (abstime.tv_nsec >= 1000*1000*1000) { + abstime.tv_nsec -= 1000*1000*1000; + abstime.tv_sec += 1; + } + if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again } proc->instance_cnt_RUs = -1; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); if (waitret == ETIMEDOUT) { LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx); From cef2ed8dda468b4d122c3d5d64d4a37b1131e1fa Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 31 Jan 2020 09:07:56 +0100 Subject: [PATCH 203/343] bugfix in nr_dlsch_encoding --- 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 7f52443fce..79c2011d94 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -323,7 +323,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_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; uint16_t nb_rb = rel15->rbSize; From 0bb1bcc0bb06e48cea83840bda940905fd5237ec Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 31 Jan 2020 18:15:32 +0100 Subject: [PATCH 204/343] Updated CP length as per spec for FR2 --- openair1/PHY/INIT/nr_parms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index cfc96168c6..54a6fc2a96 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -196,13 +196,13 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) case 100: fp->ofdm_symbol_size = 1024; fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 ) - fp->nb_prefix_samples0 = 88; + fp->nb_prefix_samples0 = 136; fp->nb_prefix_samples = 72; break; case 50: fp->ofdm_symbol_size = 512; fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 ) - fp->nb_prefix_samples0 = 44; + fp->nb_prefix_samples0 = 68; fp->nb_prefix_samples = 36; break; default: From bc38ec6b298b10e7479afe774b64dd267c392626 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 31 Jan 2020 18:16:17 +0100 Subject: [PATCH 205/343] Updated samples per slot as per specs. gNB runs fine. UE yet to be tested. --- executables/nr-gnb.c | 25 ++++---- executables/nr-ru.c | 66 ++++++++++++---------- openair1/PHY/INIT/nr_parms.c | 35 ++++++++++-- openair1/PHY/MODULATION/slot_fep_nr.c | 4 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 16 +++--- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- openair1/PHY/defs_nr_common.h | 22 ++++++-- openair1/SCHED_NR/nr_ru_procedures.c | 8 +-- 9 files changed, 111 insertions(+), 69 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index c6f71024aa..983189f5f0 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -108,8 +108,7 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int transmission_mode; -uint16_t sl_ahead=6; -uint16_t sf_ahead=6; +uint16_t sf_ahead=3; //pthread_t main_gNB_thread; time_stats_t softmodem_stats_mt; // main thread @@ -216,7 +215,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t if (oai_exit) return(-1); // ***************************************** - // TX processing for subframe n+sl_ahead + // TX processing for subframe n+sf_ahead // run PHY TX procedures the one after the other for all CCs to avoid race conditions // (may be relaxed in the future for performance reasons) // ***************************************** @@ -407,11 +406,11 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct if (!oai_exit) { T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx)); - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot); + L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); L1_proc->frame_rx = ru_proc->frame_rx; L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; + L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; + L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id); @@ -571,7 +570,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { abstime.tv_sec += 1; } - // wake up TX for subframe n+sl_ahead + // wake up TX for subframe n+sf_ahead // lock the TX mutex and make sure the thread is ready AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); @@ -587,15 +586,15 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti, - // and proc->slot_tx = proc->slot_rx+sl_ahead - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot); + // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, + // and proc->slot_tx = proc->slot_rx+sf_ahead + L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); L1_proc->frame_rx = ru_proc->frame_rx; L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; + L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; + L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; - LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead); + LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead); pthread_mutex_unlock( &L1_proc->mutex ); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index b2eb471016..6379a94a2f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -50,6 +50,7 @@ #include #include #include +#include #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all @@ -134,7 +135,7 @@ void configure_rru(int idx, void *arg); int attach_rru(RU_t *ru); int connect_rau(RU_t *ru); -extern uint16_t sl_ahead; +extern uint16_t sf_ahead; extern int emulate_rf; extern int numerology; @@ -331,8 +332,9 @@ void fh_if5_south_in(RU_t *ru, NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; RU_proc_t *proc = &ru->proc; recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL); - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*20))&1023; - proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%20; + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; + uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe; + proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); if (proc->first_rx == 0) { if (proc->tti_rx != *tti) { @@ -390,12 +392,12 @@ void fh_if4p5_south_in(RU_t *ru, } while(proc->symbol_mask[sl] != symbol_mask_full); //caculate timestamp_rx, timestamp_tx based on frame and subframe - proc->tti_rx = sl; - proc->frame_rx = f; - proc->timestamp_rx = ((proc->frame_rx * fp->slots_per_frame) + proc->tti_rx ) * fp->samples_per_slot ; + proc->tti_rx = sl; + proc->frame_rx = f; + proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(proc->tti_rx, fp); // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe); - proc->tti_tx = (sl+sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (sl>(fp->slots_per_frame-sl_ahead)) ? (f+1)&1023 : f; + proc->tti_tx = (sl+(fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; + proc->frame_tx = (sl>(fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (f+1)&1023 : f; if (proc->first_rx == 0) { if (proc->tti_rx != *slot) { @@ -502,8 +504,9 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { openair0_timestamp timestamp_tx; recv_IF5(ru, ×tamp_tx, *slot, IF5_RRH_GW_DL); // printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); - tti_tx = (timestamp_tx/fp->samples_per_slot)%fp->slots_per_frame; - frame_tx = (timestamp_tx/(fp->samples_per_slot*fp->slots_per_frame))&1023; + frame_tx = (timestamp_tx / (fp->samples_per_subframe*10))&1023; + uint32_t idx_sf = timestamp_tx / fp->samples_per_subframe; + tti_tx = (idx_sf * fp->slots_per_subframe + (int)round((timestamp_tx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); if (proc->first_tx != 0) { *slot = tti_tx; @@ -556,12 +559,12 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { if ((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT)>0) stop_meas(&ru->rx_fhaul); - proc->tti_tx = slot_tx; - proc->frame_tx = frame_tx; + proc->tti_tx = slot_tx; + proc->frame_tx = frame_tx; if ((frame_tx == 0)&&(slot_tx == 0)) proc->frame_tx_unwrap += 1024; - proc->timestamp_tx = ((((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->slots_per_frame) + (uint64_t)slot_tx) * (uint64_t)fp->samples_per_slot; + proc->timestamp_tx = (((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(slot_tx, fp); 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,slot_tx); // dump VCD output for first RU in list @@ -628,26 +631,27 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { void *rxp[ru->nb_rx]; unsigned int rxs; int i; + uint32_t samples_per_slot = fp->get_samples_per_slot(*slot,fp); openair0_timestamp ts,old_ts; AssertFatal(*slotslots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame); for (i=0; inb_rx; i++) - rxp[i] = (void *)&ru->common.rxdata[i][*slot*fp->samples_per_slot]; + rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot,fp)]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); old_ts = proc->timestamp_rx; - LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]); + LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",samples_per_slot,*slot,rxp[0]); if(emulate_rf) { wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); - rxs = fp->samples_per_slot; + rxs = samples_per_slot; ts = old_ts + rxs; } else { rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, - fp->samples_per_slot, + samples_per_slot, ru->nb_rx); } @@ -657,21 +661,22 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { //AssertFatal(rxs == fp->samples_per_subframe, //"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs); - if (rxs != fp->samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_slot,rxs); + if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",samples_per_slot,rxs); if (proc->first_rx == 1) { ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; } else { - if (proc->timestamp_rx - old_ts != fp->samples_per_slot) { - LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset); - ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot); + if (proc->timestamp_rx - old_ts != samples_per_slot) { + LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot,ru->ts_offset); + ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot); proc->timestamp_rx = ts-ru->ts_offset; } } - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023; - proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame; + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; + uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe; + proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); // synchronize first reception to frame 0 subframe 0 LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, @@ -687,7 +692,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { if (proc->first_rx == 0) { if (proc->tti_rx != *slot) { - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot); + LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot); exit_fun("Exiting"); } @@ -704,7 +709,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - if (rxs != fp->samples_per_slot) { + if (rxs != samples_per_slot) { //exit_fun( "problem receiving samples" ); LOG_E(PHY, "problem receiving samples\n"); } @@ -719,13 +724,13 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { unsigned int txs; int i,txsymb; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), - T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4)); + T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp)], fp->samples_per_subframe)); int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame); int sf_extension = 0; //sf_extension = ru->sf_extension; - int siglen=fp->samples_per_slot; + int siglen=fp->get_samples_per_slot(slot,fp); int flags=1; //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); @@ -738,7 +743,10 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { txsymb++; } AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); - siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + if(slot%(fp->slots_per_subframe/2)) + siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); //+ ru->end_of_burst_delay; flags=3; // end of burst } @@ -759,7 +767,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); for (i=0; inb_tx; i++) - txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; + txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp)-sf_extension]; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 54a6fc2a96..6fdfe87ee7 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -221,6 +221,23 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) } } +uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) +{ + if(slot%(fp->slots_per_subframe/2)) + return fp->samples_per_slotN0; + else + return fp->samples_per_slot0; +} + +uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp) +{ + uint32_t samp_count = 0; + + for(uint8_t idx_slot = 0; idx_slot < slot; idx_slot++) + samp_count += fp->get_samples_per_slot(idx_slot, fp); + + return samp_count; +} int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp) @@ -258,9 +275,12 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; - fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); - fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) + - (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); + fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot; + fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); + fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + + (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2); + fp->get_samples_per_slot = &get_samples_per_slot; + fp->get_samples_slot_timestamp = &get_samples_slot_timestamp; fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; @@ -331,9 +351,12 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; - fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); - fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) + - (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); + fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot; + fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); + fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + + (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2); + fp->get_samples_per_slot = &get_samples_per_slot; + fp->get_samples_slot_timestamp = &get_samples_slot_timestamp; fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 930eee39fb..beb769c01e 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -109,7 +109,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (no_prefix) { slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns); } else { - slot_offset = (frame_parms->samples_per_slot) * (Ns); + slot_offset = frame_parms->get_samples_per_slot(Ns,frame_parms); } /*if (l<0 || l>=7-frame_parms->Ncp) { @@ -258,7 +258,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, break; } - slot_offset = Ns * frame_parms->samples_per_slot; + slot_offset = frame_parms->get_samples_per_slot(Ns,frame_parms); if(symbol == 0) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 268f2f5fcf..5710499e1a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -65,7 +65,7 @@ void rx_nr_prach_ru(RU_t *ru, AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n"); for (int aa=0; aanb_rx; aa++) - prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_slot<<1)-ru->N_TA_offset]; + prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_subframe)-ru->N_TA_offset]; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 9af68a9bc5..f407119024 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -104,7 +104,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t first_nonzero_root_idx=0; #if defined(OAI_USRP) - prach_start = (ue->rx_offset+subframe*(fp->samples_per_slot<<1)-ue->hw_timing_advance-ue->N_TA_offset); + prach_start = (ue->rx_offset+subframe*fp->samples_per_subframe-ue->hw_timing_advance-ue->N_TA_offset); #ifdef NR_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, prach_start, @@ -114,13 +114,13 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, #endif if (prach_start<0) - prach_start+=((fp->samples_per_slot<<1)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + prach_start+=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - if (prach_start>=((fp->samples_per_slot<<1)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) - prach_start-=((fp->samples_per_slot<<1)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + if (prach_start>=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) + prach_start-=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); #else //normal case (simulation) - prach_start = subframe*(fp->samples_per_slot<<1)-ue->N_TA_offset; + prach_start = subframe*fp->samples_per_subframe-ue->N_TA_offset; LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, prach_start, ue->rx_offset, @@ -793,10 +793,10 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int j; - int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*(fp->samples_per_slot<<1); + int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe; LOG_D( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); - for (i=prach_start,j=0; isamples_per_slot<<1)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { + for (i=prach_start,j=0; isamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; } @@ -820,7 +820,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, #if defined(PRACH_WRITE_OUTPUT_DEBUG) LOG_M("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1); LOG_M("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1); - LOG_M("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]),4*fp->samples_per_slot,1,1); + LOG_M("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]),fp->samples_per_subframe,1,1); exit(-1); #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index d2dbd6fef2..20e1956f89 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -364,7 +364,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, timing_advance = 0; #endif - tx_offset = slot*frame_parms->samples_per_slot - timing_advance; + tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms) - timing_advance; if (tx_offset < 0) tx_offset += frame_parms->samples_per_frame; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 487b28473f..5e4829c7a4 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -223,7 +223,13 @@ typedef struct { NR_PRACH_CONFIG_INFO prach_ConfigInfo; } NR_PRACH_CONFIG_COMMON; -typedef struct NR_DL_FRAME_PARMS { +typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; + +typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp); + +typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, NR_DL_FRAME_PARMS* fp); + +struct NR_DL_FRAME_PARMS { /// frequency range nr_frequency_range_e freq_range; // /// Placeholder to replace overlapping fields below @@ -270,12 +276,18 @@ typedef struct NR_DL_FRAME_PARMS { uint16_t symbols_per_slot; /// Number of slots per subframe uint16_t slots_per_subframe; - /// Number of slots per frame + /// Number of slots per frame uint16_t slots_per_frame; /// Number of samples in a subframe uint32_t samples_per_subframe; - /// Number of samples in a slot - uint32_t samples_per_slot; + /// Number of samples in current slot + get_samples_per_slot_t get_samples_per_slot; + /// Number of samples before slot + get_samples_slot_timestamp_t get_samples_slot_timestamp; + /// Number of samples in 0th and center slot of a subframe + uint32_t samples_per_slot0; + /// Number of samples in other slots of the subframe + uint32_t samples_per_slotN0; /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) uint16_t symbols_per_tti; /// Number of samples in a radio frame @@ -339,7 +351,7 @@ typedef struct NR_DL_FRAME_PARMS { /// PBCH polar encoder params t_nrPolar_params pbch_polar_params; -} NR_DL_FRAME_PARMS; +}; #define KHz (1000UL) #define MHz (1000*KHz) diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 559244643d..144d92c03f 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -66,7 +66,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); - slot_offset = slot*fp->samples_per_slot; + slot_offset = fp->get_samples_slot_timestamp(slot,fp); slot_offsetF = first_symbol*fp->ofdm_symbol_size; @@ -370,7 +370,7 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { int slot_sizeF = (fp->ofdm_symbol_size)* ((cyclic_prefix_type == 1) ? 12 : 14); int slot = tti_tx; - int *txdata = &ru->common.txdata[aa][slot*fp->samples_per_slot]; + int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(slot,fp)]; if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; @@ -386,8 +386,8 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { stop_meas(&ru->ofdm_mod_stats); LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n", - frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_slot)), - dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); + frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->get_samples_per_slot( + slot,fp))),dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); } From 101a55e332be2d81f7e843fbdb17b3e30cbc3271 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 3 Feb 2020 10:30:16 +0100 Subject: [PATCH 206/343] commit before rebasing onto develop --- cmake_targets/CMakeLists.txt | 8 ++++---- executables/nr-ru.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- openair2/LAYER2/NR_MAC_gNB/main.c | 2 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 4564fdd270..bb7cc25ec0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2442,7 +2442,7 @@ add_executable(lte-softmodem ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c - ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c @@ -2511,7 +2511,7 @@ add_executable(lte-uesoftmodem ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c - ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c @@ -2560,7 +2560,7 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/executables/nr-gnb.c ${OPENAIR_DIR}/executables/nr-ru.c ${OPENAIR_DIR}/executables/nr-softmodem.c - ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c @@ -2599,7 +2599,7 @@ add_executable(nr-uesoftmodem ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c ${OPENAIR_DIR}/executables/nr-uesoftmodem.c ${OPENAIR_DIR}/executables/nr-ue.c - ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 42fbd7f22c..0003cf770d 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -81,7 +81,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "enb_config.h" -#include +#include #ifdef SMBV #include "PHY/TOOLS/smbv.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index abfcbd5fee..43ca0a981c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -33,7 +33,7 @@ #include "mac_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" -#include "executables/nr-softmodem.h" +#include "executables/softmodem-common.h" extern RAN_CONTEXT_t RC; //#define ENABLE_MAC_PAYLOAD_DEBUG 1 diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 15b5f0ca9c..fcc3581b84 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -40,7 +40,7 @@ //#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "common/ran_context.h" -#include "executables/nr-softmodem.h" +#include "executables/softmodem-common.h" extern RAN_CONTEXT_t RC; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 67b73f60c1..494baefc29 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -36,7 +36,7 @@ #include "assertions.h" #include "LAYER2/NR_MAC_UE/mac_extern.h" #include "SCHED_NR_UE/fapi_nr_ue_l1.h" -#include "executables/nr-softmodem.h" +#include "executables/softmodem-common.h" #include From 1b8e18e05b25ad3ad5851cb7f3c81a428768e6c3 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 3 Feb 2020 12:30:45 +0100 Subject: [PATCH 207/343] absoluteFrequencySSB is the center of SSB (correction of 10 RB in ref to point A needed) --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 2 +- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b5041396a4..b36ce6f3ea 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -221,7 +221,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) scs_scaling = scs_scaling>>2; uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); - cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling); + cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10; cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; cfg->ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC? switch (scc->ssb_PositionsInBurst->present) { diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 44a3f11711..aa6d87a37d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -207,7 +207,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) scs_scaling = scs_scaling>>2; uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); - cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scs_scaling); + cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scs_scaling) - 10; //absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total cfg->ssb_table.ssb_offset_point_a.tl.tag = NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG; cfg->num_tlv++; cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 2983c699c0..1e743522f5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -135,7 +135,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ AssertFatal(1==0,"SCS %ld not allowed for SSB \n", *cc->ServingCellConfigCommon->ssbSubcarrierSpacing); } dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = 0; //kSSB - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12); + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1); dl_req->nPDUs++; From cd20e9083a8c2a8320dd45b73897250d0eb8fa4b Mon Sep 17 00:00:00 2001 From: laurent Date: Mon, 3 Feb 2020 13:48:17 +0100 Subject: [PATCH 208/343] fix compilation error for Lime driver --- openair1/PHY/TOOLS/tools_defs.h | 8 ++++++++ targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 57f5a782de..5ba956fd39 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -29,6 +29,10 @@ */ +#ifdef __cplusplus +extern "C" { +#endif + #include #include "PHY/sse_intrin.h" @@ -428,4 +432,8 @@ double interp(double x, double *xs, double *ys, int count); int write_output(const char *fname,const char *vname,void *data,int length,int dec,char format); +#ifdef __cplusplus +} +#endif + #endif //__PHY_TOOLS_DEFS__H__ diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index a57ebf8b6d..9fcfbdf571 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -178,7 +178,7 @@ int trx_lms_start(openair0_device *device){ } LMS_Init(lms_device); - LMS_EnableCalibCache(lms_device,false); + LMS_EnableCache(lms_device,false); if (LMS_LoadConfig(lms_device,device->openair0_cfg[0].configFilename) != 0) { @@ -277,6 +277,7 @@ int trx_lms_stop(openair0_device *device) { LMS_DestroyStream(lms_device,&rx_stream); LMS_DestroyStream(lms_device,&tx_stream); LMS_Close(lms_device); + return 0; } /*! \brief Set frequencies (TX/RX) From 980407a1df534c63c1dff94e4df4e0e69e0f314e Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 3 Feb 2020 16:59:53 +0100 Subject: [PATCH 209/343] Fixed conflicts after merge --- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 7 +++++-- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index f237f14384..737bd4d1ff 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -800,8 +800,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, 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; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dl_config_pdu = &harq_processes[harq_pid]->dl_config_pdu + uint8_t dmrs_type = dl_config_pdu->dmrsConfigType; + //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==1)?6:4; uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index a820f48699..1a5498dc4c 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1794,7 +1794,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(nr_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(get_nr_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif #ifdef UE_DEBUG_TRACE @@ -2169,7 +2169,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(nr_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(get_nr_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif #ifdef UE_DEBUG_TRACE @@ -2277,7 +2277,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(nr_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(get_nr_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", From 9ea4ebdc5f0c26cef9762f7cfb895cb181b4a353 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 4 Feb 2020 11:09:19 +0100 Subject: [PATCH 210/343] more updates on samples_per_slot --- executables/nr-ru.c | 10 ++++----- executables/nr-ue.c | 24 +++++++++++++--------- openair1/PHY/INIT/nr_parms.c | 12 +++++++---- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- openair1/PHY/defs_nr_common.h | 2 +- openair1/SCHED_NR/nr_ru_procedures.c | 4 ++-- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 6379a94a2f..ac94b8ae39 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -394,7 +394,7 @@ void fh_if4p5_south_in(RU_t *ru, //caculate timestamp_rx, timestamp_tx based on frame and subframe proc->tti_rx = sl; proc->frame_rx = f; - proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(proc->tti_rx, fp); + proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(proc->tti_rx, fp, 0); // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe); proc->tti_tx = (sl+(fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; proc->frame_tx = (sl>(fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (f+1)&1023 : f; @@ -564,7 +564,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { if ((frame_tx == 0)&&(slot_tx == 0)) proc->frame_tx_unwrap += 1024; - proc->timestamp_tx = (((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(slot_tx, fp); + proc->timestamp_tx = (((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(slot_tx, fp, 0); 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,slot_tx); // dump VCD output for first RU in list @@ -636,7 +636,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { AssertFatal(*slotslots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame); for (i=0; inb_rx; i++) - rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot,fp)]; + rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot,fp,0)]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); old_ts = proc->timestamp_rx; @@ -724,7 +724,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { unsigned int txs; int i,txsymb; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), - T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp)], fp->samples_per_subframe)); + T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe)); int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); @@ -767,7 +767,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); for (i=0; inb_tx; i++) - txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp)-sf_extension]; + txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension]; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index d79c1028fd..681f1d9e67 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -239,7 +239,8 @@ static void UE_synch(void *arg) { if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync - hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot; + hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + + round(((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n", hw_slot_offset, freq_offset, @@ -719,24 +720,25 @@ void *UE_thread(void *arg) { for (int i=0; iframe_parms.nb_antennas_rx; i++) rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ - UE->frame_parms.nb_prefix_samples0+ - slot_nr*UE->frame_parms.samples_per_slot]; +- UE->frame_parms.nb_prefix_samples0+UE->frame_parms. + get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)]; for (int i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void *)&UE->common_vars.txdata[i][((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame)*UE->frame_parms.samples_per_slot]; + txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp( + ((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame),&UE->frame_parms,0)]; int readBlockSize, writeBlockSize; if (slot_nr<(nb_slot_frame - 1)) { - readBlockSize=UE->frame_parms.samples_per_slot; - writeBlockSize=UE->frame_parms.samples_per_slot; + readBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms); + writeBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms); } else { UE->rx_offset_diff = computeSamplesShift(UE); - readBlockSize=UE->frame_parms.samples_per_slot - + readBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms) - UE->frame_parms.ofdm_symbol_size - UE->frame_parms.nb_prefix_samples0 - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.samples_per_slot - + writeBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms) - UE->rx_offset_diff; } @@ -750,7 +752,8 @@ void *UE_thread(void *arg) { AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, timestamp+ - (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) - + UE->frame_parms.get_samples_slot_timestamp(slot_nr, + &UE->frame_parms,DURATION_RX_TO_TX) - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - openair0_cfg[0].tx_sample_advance, txp, @@ -774,7 +777,8 @@ void *UE_thread(void *arg) { } curMsg->proc.timestamp_tx = timestamp+ - (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)- + UE->frame_parms.get_samples_slot_timestamp(slot_nr, + &UE->frame_parms,DURATION_RX_TO_TX) - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; notifiedFIFO_elt_t *res; diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 6fdfe87ee7..3969a329ce 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -229,13 +229,17 @@ uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) return fp->samples_per_slot0; } -uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp) +uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead) { uint32_t samp_count = 0; - for(uint8_t idx_slot = 0; idx_slot < slot; idx_slot++) - samp_count += fp->get_samples_per_slot(idx_slot, fp); - + if(!sl_ahead) { + for(uint8_t idx_slot = 0; idx_slot < slot; idx_slot++) + samp_count += fp->get_samples_per_slot(idx_slot, fp); + } else { + for(uint8_t idx_slot = slot; idx_slot < slot+sl_ahead; idx_slot++) + samp_count += fp->get_samples_per_slot(idx_slot, fp); + } return samp_count; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 20e1956f89..2db94c86e2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -364,7 +364,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, timing_advance = 0; #endif - tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms) - timing_advance; + tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0) - timing_advance; if (tx_offset < 0) tx_offset += frame_parms->samples_per_frame; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 5e4829c7a4..ccc79b7d47 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -227,7 +227,7 @@ typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp); -typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, NR_DL_FRAME_PARMS* fp); +typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead); struct NR_DL_FRAME_PARMS { /// frequency range diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 144d92c03f..f594c8554b 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -66,7 +66,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); - slot_offset = fp->get_samples_slot_timestamp(slot,fp); + slot_offset = fp->get_samples_slot_timestamp(slot,fp,0); slot_offsetF = first_symbol*fp->ofdm_symbol_size; @@ -370,7 +370,7 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { int slot_sizeF = (fp->ofdm_symbol_size)* ((cyclic_prefix_type == 1) ? 12 : 14); int slot = tti_tx; - int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(slot,fp)]; + int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(slot,fp,0)]; if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; From fa09fbcf12d6ce48dc978bb8430694fbcfb8c617 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 4 Feb 2020 13:21:02 +0100 Subject: [PATCH 211/343] Small fix to be able to parse ue capabilities and add NSA user when running in phytest mode --- openair2/RRC/NR/rrc_gNB.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 6fbb1b3cdc..d32c6d6f3c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -204,7 +204,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { ); - /*if (phy_test > 0) { + if (phy_test > 0) { // This is for phytest only, emulate first X2 message if uecap.raw file is present FILE *fd; @@ -253,7 +253,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); rrc_add_nsa_user(rrc,ue_context_p); } - }*/ + } } From 9367bad1a4c2b26e1628636a596f6f3dda9e01df Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 4 Feb 2020 13:38:07 +0100 Subject: [PATCH 212/343] Disable X2AP at gNB 217 PRBs config file to prevent segfault when there is no X2 link --- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 22df17cd9f..b82c455ef4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -200,7 +200,7 @@ gNBs = ); ///X2 - enable_x2 = "yes"; + enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( From cae94677f80ff7c790281c477efc155c6dc5a2e1 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 4 Feb 2020 14:17:32 +0100 Subject: [PATCH 213/343] CI: adding a EPC lockable resource to pipeline Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-tmp-ran | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index a93a3a3758..ab1573de7f 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -36,6 +36,9 @@ def testStageName = params.pipelineTestStageName // Name of the phone resource def ciSmartPhoneResource = params.smartphonesResource +// Name of the phone resource +def ciEpcResource = params.epcResource + // Terminate Status def termUE = 0 def termENB = 1 @@ -64,7 +67,7 @@ pipeline { options { disableConcurrentBuilds() ansiColor('xterm') - lock (ciSmartPhoneResource) + lock(extra: [[resource: ciEpcResource]], resource: ciSmartPhoneResource) } // the following parameter options are commented out so it shows the ones // that you SHALL have to run the job. From 64e4826c81c3e644c6bd57515448f1c8f85d0857 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 3 Feb 2020 10:36:59 +0100 Subject: [PATCH 214/343] add softmodem-common.c and common error handler --- executables/nr-softmodem-common.h | 1 - executables/nr-softmodem.c | 84 +------- executables/nr-softmodem.h | 25 --- executables/nr-uesoftmodem.c | 41 +--- executables/nr-uesoftmodem.h | 5 - .../softmodem-common.c | 87 +++++++-- executables/softmodem-common.h | 183 ++++++++++++++++++ .../PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c | 12 +- openair1/PHY/phy_extern.h | 1 - openair1/PHY/phy_extern_nr_ue.h | 1 - openair1/PHY/phy_extern_ue.h | 1 - openair1/PHY/phy_vars.h | 2 - openair1/PHY/phy_vars_nr_ue.h | 1 - openair1/PHY/phy_vars_ue.h | 1 - openair2/ENB_APP/MACRLC_paramdef.h | 7 +- openair2/ENB_APP/enb_config.c | 2 - openair2/ENB_APP/enb_paramdef.h | 2 - openair2/GNB_APP/gnb_config.c | 2 - openair2/GNB_APP/gnb_paramdef.h | 2 - openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h | 1 - openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 9 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 +- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 4 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 1 - targets/RT/USER/lte-softmodem.c | 27 +-- targets/RT/USER/lte-softmodem.h | 174 +++-------------- targets/RT/USER/lte-uesoftmodem.c | 29 +-- 27 files changed, 315 insertions(+), 395 deletions(-) rename targets/RT/USER/lte-softmodem-common.c => executables/softmodem-common.c (59%) diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index a288dbebde..e014eaf93f 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -130,7 +130,6 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int rx_input_level_dBm; -extern uint8_t exit_missed_slots; extern uint64_t num_missed_slots; // counter for the number of missed slots extern int oaisim_flag; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 5ff9618bf1..6b72562033 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -148,11 +148,9 @@ double bw = 10.0e6; static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; -char rf_config_file[1024]="/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; int chain_offset=0; -int phy_test = 0; -uint8_t usim_test = 0; + uint8_t dci_Format = 0; uint8_t agregation_Level =0xFF; @@ -176,7 +174,6 @@ int otg_enabled; uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; -uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots @@ -189,7 +186,6 @@ int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -static softmodem_params_t softmodem_params; static char *parallel_config = NULL; static char *worker_config = NULL; @@ -270,39 +266,13 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); } -#if !defined(ENABLE_ITTI) -void signal_handler(int sig) { - void *array[10]; - size_t size; - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - printf("trying to exit gracefully...\n"); - oai_exit = 1; - } -} -#endif #define KNRM "\x1B[0m" #define KRED "\x1B[31m" #define KGRN "\x1B[32m" #define KBLU "\x1B[34m" #define RESET "\033[0m" -#if defined(ENABLE_ITTI) -void signal_handler_itti(int sig) { - // Call exit function - char msg[256]; - memset(msg, 0, 256); - sprintf(msg, "caught signal %s\n", strsignal(sig)); - exit_function(__FILE__, __FUNCTION__, __LINE__, msg); -} -#endif void exit_function(const char *file, const char *function, const int line, const char *s) { int ru_id; @@ -329,9 +299,6 @@ void exit_function(const char *file, const char *function, const int line, const } sleep(1); //allow lte-softmodem threads to exit first -#if defined(ENABLE_ITTI) - itti_terminate_tasks (TASK_UNKNOWN); -#endif exit(1); } @@ -469,37 +436,14 @@ int create_gNB_tasks(uint32_t gnb_nb) { static void get_options(void) { - int tddflag, nonbiotflag; - uint32_t online_log_messages; - uint32_t glog_level, glog_verbosity; - uint32_t start_telnetsrv = 0; - uint32_t noS1; - uint32_t nokrnmod; + + paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; - paramdef_t cmdline_logparams[] = CMDLINE_LOGPARAMS_DESC_NR ; + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); - - if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { - set_glog_onlinelog(online_log_messages); - } - - if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { - set_glog(glog_level); - } - - if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0,NULL); - } - -#if T_TRACER - paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; - config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); -#endif - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { memset((void *)&RC,0,sizeof(RC)); /* Read RC configuration file */ @@ -516,14 +460,6 @@ static void get_options(void) { } -#if T_TRACER - int T_nowait = 0; /* by default we wait for the tracer */ - int T_port = 2021; /* default port to listen to to wait for the tracer */ - int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ -#endif - - - void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { @@ -653,7 +589,7 @@ void init_openair0(void) { openair0_cfg[card].rx_gain[i] = RC.gNB[0][0]->rx_total_gain_dB; - openair0_cfg[card].configFilename = rf_config_file; + openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", card,i, openair0_cfg[card].tx_gain[i], openair0_cfg[card].rx_gain[i], @@ -866,7 +802,7 @@ int main( int argc, char **argv ) if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } - + set_softmodem_sighandler(); #ifdef DEBUG_CONSOLE setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); @@ -914,11 +850,7 @@ init_opt(); pdcp_netlink_init(); #endif #endif -#if !defined(ENABLE_ITTI) - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); -#endif + #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif @@ -1031,7 +963,7 @@ init_opt(); if (RC.nb_RU >0) { printf("Initializing RU threads\n"); - init_NR_RU(rf_config_file); + init_NR_RU(get_softmodem_params()->rf_config_file); for (ru_id=0; ru_idrf_map.card=0; diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 8334c99134..20316bff2e 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -18,10 +18,6 @@ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_GNB { \ - {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ - {"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}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, 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}, \ @@ -34,34 +30,13 @@ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ - {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ - {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ - {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ - {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0} \ } -#define SOFTMODEM_NOS1_BIT (1<<0) -#define SOFTMODEM_NOKRNMOD_BIT (1<<1) -#define SOFTMODEM_RFSIM_BIT (1<<10) - -#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) -#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) - -#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) -extern uint64_t get_softmodem_optmask(void); -extern void get_common_options(void); - -extern int T_port; -extern int T_nowait; -extern int T_dont_fork; - - #include "threads_t.h" extern threads_t threads; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 82591c72b7..1781ed0d8d 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -163,11 +163,9 @@ double bw = 10.0e6; static int tx_max_power[MAX_NUM_CCs] = {0}; -char rf_config_file[1024]; int chain_offset=0; -int phy_test = 0; -uint8_t usim_test = 0; + uint8_t dci_Format = 0; uint8_t agregation_Level =0xFF; @@ -178,7 +176,6 @@ uint8_t nb_antenna_rx = 1; char ref[128] = "internal"; char channels[128] = "0"; -static softmodem_params_t softmodem_params; static char *parallel_config = NULL; static char *worker_config = NULL; @@ -197,7 +194,6 @@ int16_t node_synch_ref[MAX_NUM_CCs]; uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; -uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots @@ -273,7 +269,7 @@ void exit_function(const char *file, const char *function, const int line, const } sleep(1); //allow lte-softmodem threads to exit first - itti_terminate_tasks (TASK_UNKNOWN); + exit(1); } @@ -386,28 +382,12 @@ static void get_options(void) { int tddflag=0, nonbiotflag, vcdflag=0; char *loopfile=NULL; int dumpframe=0; - uint32_t online_log_messages; - uint32_t glog_level, glog_verbosity; - uint32_t start_telnetsrv=0; + //uint32_t noS1; //uint32_t nokrnmod; paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ; - paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC_NR ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); - - if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { - set_glog_onlinelog(online_log_messages); - } - - if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { - set_glog(glog_level); - } - - if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0,NULL); - } paramdef_t cmdline_uemodeparams[] = CMDLINE_UEMODEPARAMS_DESC; paramdef_t cmdline_ueparams[] = CMDLINE_NRUEPARAMS_DESC; @@ -476,10 +456,6 @@ static void get_options(void) { tx_gain[0][CC_id] = tx_gain[0][0]; } -#if T_TRACER - paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; - config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); -#endif if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { // Here the configuration file is the XER encoded UE capabilities @@ -490,11 +466,6 @@ static void get_options(void) { } /* UE with config file */ } -#if T_TRACER - int T_nowait = 0; /* by default we wait for the tracer */ - int T_port = 2021; /* default port to listen to to wait for the tracer */ - int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ -#endif void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { int CC_id; @@ -626,7 +597,7 @@ void init_openair0(void) { openair0_cfg[card].autocal[i] = 1; openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - openair0_cfg[card].configFilename = rf_config_file; + openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", card,i, openair0_cfg[card].tx_gain[i], openair0_cfg[card].rx_gain[i], @@ -669,7 +640,7 @@ int main( int argc, char **argv ) { if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } - + set_softmodem_sighandler(); CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); set_default_frame_parms(frame_parms); mode = normal_txrx; @@ -741,7 +712,7 @@ int main( int argc, char **argv ) { UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - if (phy_test==1) + if (get_softmodem_params()->phy_test==1) UE[CC_id]->mac_enabled = 0; else UE[CC_id]->mac_enabled = 1; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index cad8e726f4..38c4c1b607 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -61,10 +61,6 @@ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_UE { \ - {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ - {"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}, \ {"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}, \ @@ -76,7 +72,6 @@ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ - {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ diff --git a/targets/RT/USER/lte-softmodem-common.c b/executables/softmodem-common.c similarity index 59% rename from targets/RT/USER/lte-softmodem-common.c rename to executables/softmodem-common.c index 6bd8835a92..00b974e3ae 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/executables/softmodem-common.c @@ -20,26 +20,33 @@ */ /*! \file lte-softmodem-common.c - * \brief Top-level threads for eNodeB + * \brief common code for 5G and LTE softmodem main xNB and UEs source (nr-softmodem.c, lte-softmodem.c...) * \author Nokia BellLabs France, francois Taburet - * \date 2012 + * \date 2020 * \version 0.1 - * \company Eurecom + * \company Nokia BellLabs France * \email: francois.taburet@nokia-bell-labs.com * \note * \warning */ - -#include "lte-softmodem.h" +#include +#include +#include #include "UTIL/OPT/opt.h" #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" +#include "common/utils/telnetsrv/telnetsrv.h" #include "executables/thread-common.h" -#include +#include "softmodem-common.h" + static softmodem_params_t softmodem_params; char *parallel_config=NULL; char *worker_config=NULL; + + +static struct timespec start; + uint64_t get_softmodem_optmask(void) { return softmodem_params.optmask; } @@ -92,7 +99,7 @@ void get_common_options(void) { } if (nokrnmod) { - printf("nokrnmod bit enabled \n"); + printf("nokrnmod bit enabled \n"); set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT); } @@ -112,21 +119,67 @@ void get_common_options(void) { set_softmodem_optmask(SOFTMODEM_DOFORMS_BIT); } -#if BASIC_SIMULATOR - set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); -#endif - if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); } -unsigned int is_nos1exec(char *exepath) { - if ( strcmp( basename(exepath), "lte-softmodem-nos1") == 0) - return 1; +void softmodem_printresources(int sig, telnet_printfunc_t pf) { + struct rusage usage; + struct timespec stop; - if ( strcmp( basename(exepath), "lte-uesoftmodem-nos1") == 0) - return 1; + clock_gettime(CLOCK_BOOTTIME, &stop); - return 0; + uint64_t elapse = (stop.tv_sec - start.tv_sec) ; // in seconds + + + int st = getrusage(RUSAGE_SELF,&usage); + if (!st) { + pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600))); + pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec); + pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec); + pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss); + pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt); + pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt); + pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock); + pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock); + pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw); + pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw); + } +} + +void signal_handler(int sig) { + void *array[10]; + size_t size; + + if (sig==SIGSEGV) { + // get void*'s for all entries on the stack + size = backtrace(array, 10); + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(-1); + } else { + if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL) + softmodem_printresources(sig,(telnet_printfunc_t)printf); + if (sig != SOFTMODEM_RTSIGNAL) { + printf("Linux signal %s...\n",strsignal(sig)); + exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n"); + } + } +} + + + +void set_softmodem_sighandler(void) { + struct sigaction act,oldact; + clock_gettime(CLOCK_BOOTTIME, &start); + memset(&act,0,sizeof(act)); + act.sa_handler=signal_handler; + sigaction(SOFTMODEM_RTSIGNAL,&act,&oldact); + printf("Send signal %d to display resource usage...\n",SIGRTMIN+1); + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); } diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index f6ba3a6beb..69ed98635b 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -1,5 +1,178 @@ +/* + * 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 lte-softmodem-common.h + * \brief Top-level threads for eNodeB + * \author + * \date 2012 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ #ifndef SOFTMODEM_COMMON_H #define SOFTMODEM_COMMON_H +#ifdef __cplusplus +extern "C" +{ +#endif +/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ +#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" +#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" +#define CONFIG_HLP_CALUER "set UE RX calibration\n" +#define CONFIG_HLP_CALUERM "" +#define CONFIG_HLP_CALUERB "" +#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n" +#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n" +#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n" + + +#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n" +#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" +#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" +#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n" +#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" +#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" +#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" +#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" +#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" +#define CONFIG_HLP_CHOFF "Channel id offset\n" +#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" +#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" +#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" +#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" +#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" + + +//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation" +#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" +#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" + +#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" +#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" +#define CONFIG_HLP_TPORT "tracer port\n" +#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" +#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" + +#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" +#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" +#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" +#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" +#define CONFIG_HLP_NOS1 "Disable s1 interface\n" +#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n" +#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" +#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" + +/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters common to eNodeB and UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define RF_CONFIG_FILE softmodem_params.rf_config_file +#define PHY_TEST softmodem_params.phy_test +#define WAIT_FOR_SYNC softmodem_params.wait_for_sync +#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag +#define CHAIN_OFFSET softmodem_params.chain_offset +#define NUMEROLOGY softmodem_params.numerology +#define EMULATE_RF softmodem_params.emulate_rf +#define CLOCK_SOURCE softmodem_params.clock_source +#define TIMING_SOURCE softmodem_params.timing_source +#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync +#define USIM_TEST softmodem_params.usim_test + +#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; + +#define CMDLINE_PARAMS_DESC { \ + {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ + {"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}, \ + {"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \ + {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ + {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \ + {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ + {"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \ + {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ + {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ + {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ + {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \ + {"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \ + {"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \ + {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ + {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ + } + + +#define CONFIG_HLP_FLOG "Enable online log \n" +#define CONFIG_HLP_LOGL "Set the global log level, valid options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))\n" +#define CONFIG_HLP_LOGV "Set the global log verbosity \n" +#define CONFIG_HLP_TELN "Start embedded telnet server \n" +#define CONFIG_HLP_MSC "Enable the MSC tracing utility \n" +/*----------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters for LOG utility */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------*/ +#define START_MSC softmodem_params.start_msc +#define CMDLINE_LOGPARAMS_DESC { \ + {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ + {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ + {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ + {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ + {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \ + } + +#define CMDLINE_ONLINELOG_IDX 0 +#define CMDLINE_GLOGLEVEL_IDX 1 +#define CMDLINE_GLOGVERBO_IDX 2 +#define CMDLINE_STARTTELN_IDX 3 + +/* check function for global log level */ +#define CMDLINE_LOGPARAMS_CHECK_DESC { \ + { .s5= {NULL} } , \ + { .s2= {config_check_intrange, {0,4}}}, \ + { .s5= {NULL} } , \ + { .s5= {NULL} } , \ + { .s5= {NULL} } , \ + } + +/***************************************************************************************************************************************/ + +#define SOFTMODEM_NOS1_BIT (1<<0) +#define SOFTMODEM_NOKRNMOD_BIT (1<<1) +#define SOFTMODEM_NONBIOT_BIT (1<<2) +#define SOFTMODEM_RFSIM_BIT (1<<10) +#define SOFTMODEM_BASICSIM_BIT (1<<11) +#define SOFTMODEM_SIML1_BIT (1<<12) +#define SOFTMODEM_DOFORMS_BIT (1<<15) + +#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) +#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) +#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) +#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) +#define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT) +#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) +#define IS_SOFTMODEM_DOFORMS ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT) + typedef struct { uint64_t optmask; @@ -19,4 +192,14 @@ typedef struct { uint32_t send_dmrs_sync; } softmodem_params_t; +extern uint64_t get_softmodem_optmask(void); +extern uint64_t set_softmodem_optmask(uint64_t bitmask); +extern softmodem_params_t *get_softmodem_params(void); +extern void get_common_options(void); +#define SOFTMODEM_RTSIGNAL (SIGRTMIN+1) +extern void set_softmodem_sighandler(void); +extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; +#ifdef __cplusplus +} +#endif #endif diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c index fb516549ed..ef207b6cdc 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c @@ -35,6 +35,7 @@ #include #include #include "assertions.h" +#include "common/utils/LOG/log.h" #include "PHY/TOOLS/time_meas.h" #include "defs.h" @@ -482,11 +483,12 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha //Table of possible lifting sizes char temp; int simd_size; - int macro_segment, macro_segment_end; - + unsigned int macro_segment, macro_segment_end; + macro_segment = 8*macro_num; - macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; + // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; + macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments); ///printf("macro_segment: %d\n", macro_segment); ///printf("macro_segment_end: %d\n", macro_segment_end ); @@ -506,7 +508,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha masks[7] = _mm256_set1_epi8(0x80); #endif - ///AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments); + //determine number of bits in codeword if (BG==1) @@ -562,7 +564,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha for (i=0; i>5; i++) { c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]); //for (j=1; jpuSch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCH10xSNR_IDX ].iptr); RC.mac[j]->puCch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCH10xSNR_IDX ].iptr); RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr); - //RC.mac[j]->phy_test = *(MacRLC_ParamList.paramarray[j][MACRLC_PHY_TEST_IDX].iptr); - //printf("PHY_TEST = %d,%d\n", RC.mac[j]->phy_test, j); if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { // check number of instances is same as RRC/PDCP diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 2975cf4aea..373dbf9a4e 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -1172,7 +1172,6 @@ typedef struct srb1_params_s { #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" #define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode" -#define CONFIG_STRING_MACRLC_PHY_TEST_MODE "phy_test_mode" #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -1192,7 +1191,6 @@ typedef struct srb1_params_s { #define MACRLC_LOCAL_S_PORTD_IDX 15 #define MACRLC_REMOTE_S_PORTD_IDX 16 #define MACRLC_SCHED_MODE_IDX 17 -#define MACRLC_PHY_TEST_IDX 18 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* thread configuration parameters section name */ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index acf87ab538..7061423ba6 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -374,8 +374,6 @@ void RCconfig_nr_macrlc() { for (j=0;jphy_test = *(MacRLC_ParamList.paramarray[j][MACRLC_PHY_TEST_IDX].iptr); - //printf("PHY_TEST = %d,%d\n", RC.nrmac[j]->phy_test, j); if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { // check number of instances is same as RRC/PDCP diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 4041338251..76d24f75f3 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -1008,7 +1008,6 @@ typedef enum { #define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" -#define CONFIG_STRING_MACRLC_PHY_TEST_MODE "phy_test_mode" #define MACRLC_CC_IDX 0 @@ -1029,7 +1028,6 @@ typedef enum { #define MACRLC_LOCAL_S_PORTD_IDX 15 #define MACRLC_REMOTE_S_PORTD_IDX 16 #define MACRLC_SCHED_MODE_IDX 17 -#define MACRLC_PHY_TEST_IDX 18 /* thread configuration parameters section name */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 10df4567c4..2cfce4766f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -59,7 +59,6 @@ extern unsigned short NODE_ID[1]; /* Scheduler */ extern RAN_CONTEXT_t RC; -extern int phy_test; extern uint8_t nfapi_mode; /*#if defined(PRE_SCD_THREAD) diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 0478a6b7d5..c29f75cd01 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -32,7 +32,14 @@ //#include "defs.h" #include "mac_proto.h" -#include "executables/nr-softmodem.h" +#include "../../ARCH/COMMON/common_lib.h" +//#undef MALLOC +#include "assertions.h" +#include "PHY/types.h" +#include "PHY/defs_UE.h" +#include "openair2/LAYER2/RLC/rlc.h" +#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h" +#include "executables/softmodem-common.h" static NR_UE_MAC_INST_t *nr_ue_mac_inst; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 579f5c6928..f4a53fa383 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -30,7 +30,6 @@ * \warning */ -#include "executables/nr-softmodem.h" /* MAC related headers */ #include "mac_proto.h" @@ -49,7 +48,7 @@ /*Openair Packet Tracer */ #include "UTIL/OPT/opt.h" #include "OCG.h" - +#include "executables/softmodem-common.h" /* log utils */ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -2067,7 +2066,7 @@ void nr_ue_send_sdu(module_id_t module_idP, if (opt_enabled) { trace_pdu(DIRECTION_DOWNLINK, pduP, pdu_len, module_idP, WS_C_RNTI, - (int) UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP + (int)(UE_mac_inst[module_idP].cs_RNTI), frameP, ttiP, 0, 0); //subframeP LOG_D(OPT, "[UE %d][DLSCH] Frame %d trace pdu for rnti %p with size %d\n", module_idP, frameP, UE_mac_inst[module_idP].cs_RNTI, pdu_len); } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 9c5c17e223..4ebd12c26f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -471,7 +471,7 @@ rb_found: #endif } -static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) +__attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) { nr_rlc_entity_t *nr_rlc_am; nr_rlc_ue_t *ue; @@ -739,7 +739,7 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s) nr_rlc_manager_unlock(nr_rlc_ue_manager); } -static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) +__attribute__ ((unused)) static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) { switch (s->rlc_Config->present) { case LTE_RLC_Config_PR_am: diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 44fe980ebe..a3bdffb5f6 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -128,7 +128,6 @@ typedef struct xer_sprint_string_s { //replace LTE //extern unsigned char NB_eNB_INST; extern unsigned char NB_gNB_INST; -extern uint8_t usim_test; extern RAN_CONTEXT_t RC; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 05c794bdc4..eccece02ca 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -150,7 +150,6 @@ char channels[128] = "0"; int rx_input_level_dBm; int otg_enabled; -uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots @@ -235,24 +234,6 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { } -void signal_handler(int sig) { - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - printf("Linux signal %s...\n",strsignal(sig)); - exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n"); - } -} - - void exit_function(const char *file, const char *function, const int line, const char *s) { int ru_id; @@ -537,9 +518,6 @@ int main ( int argc, char **argv ) printf("Reading in command-line options\n"); get_options (); - if (is_nos1exec(argv[0]) ) - set_softmodem_optmask(SOFTMODEM_NOS1_BIT); - EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { @@ -570,10 +548,7 @@ int main ( int argc, char **argv ) MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); init_opt(); // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); + set_softmodem_sighandler(); check_clock(); #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 26a70843e6..7b896b2817 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -35,63 +35,7 @@ #include "proto_agent.h" #include "executables/softmodem-common.h" -/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ -#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" -#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" -#define CONFIG_HLP_CALUER "set UE RX calibration\n" -#define CONFIG_HLP_CALUERM "" -#define CONFIG_HLP_CALUERB "" -#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n" -#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n" -#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n" -#define CONFIG_HLP_SIML1 "activate RF simulator instead of HW\n" -#define CONFIG_HLP_NUMUE "number of UE instances\n" -#define CONFIG_HLP_UERXG "set UE RX gain\n" -#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n" -#define CONFIG_HLP_UETXG "set UE TX gain\n" -#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n" -#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n" -#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n" -#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n" -#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" -#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" -#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" -#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" -#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n" -#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" -#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" -#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" -#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" -#define CONFIG_HLP_TADV "Set timing_advance\n" -#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" -#define CONFIG_HLP_CHOFF "Channel id offset\n" -#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" -#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" -#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" -#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" -#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" -#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" -#define CONFIG_HLP_EMULIFACE "Set the interface name for the multicast transport for emulation mode (e.g. eth0, lo, etc.) \n" -//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation" -#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" -#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" -#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" -#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" -#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" -#define CONFIG_HLP_TPORT "tracer port\n" -#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" -#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" -#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" -#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" -#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" -#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" -#define CONFIG_HLP_NOS1 "Disable s1 interface\n" -#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n" -#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" -#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" - -#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument @@ -121,6 +65,31 @@ #define CMDLINE_MEMLOOP_IDX 6 #define CMDLINE_DUMPMEMORY_IDX 7 /*------------------------------------------------------------------------------------------------------------------------------------------*/ +/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ + + +#define CONFIG_HLP_SIML1 "activate RF simulator instead of HW\n" +#define CONFIG_HLP_NUMUE "number of UE instances\n" +#define CONFIG_HLP_UERXG "set UE RX gain\n" +#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n" +#define CONFIG_HLP_UETXG "set UE TX gain\n" +#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n" +#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n" +#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n" +#define CONFIG_HLP_EMULIFACE "Set the interface name for the multicast transport for emulation mode (e.g. eth0, lo, etc.) \n" +#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" +#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" +#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n" +#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" +#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" +#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" +#define CONFIG_HLP_TADV "Set timing_advance\n" + + + + + + /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -166,99 +135,7 @@ #define DEFAULT_DLF 2680000000 -/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define RF_CONFIG_FILE softmodem_params.rf_config_file -#define PHY_TEST softmodem_params.phy_test -#define WAIT_FOR_SYNC softmodem_params.wait_for_sync -#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag -#define CHAIN_OFFSET softmodem_params.chain_offset -#define NUMEROLOGY softmodem_params.numerology -#define EMULATE_RF softmodem_params.emulate_rf -#define CLOCK_SOURCE softmodem_params.clock_source -#define TIMING_SOURCE softmodem_params.timing_source -#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync -#define USIM_TEST softmodem_params.usim_test -#define CMDLINE_PARAMS_DESC { \ - {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ - {"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}, \ - {"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \ - {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ - {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \ - {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ - {"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \ - {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ - {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ - {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ - {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ - {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \ - {"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ - {"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \ - {"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \ - {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ - } -#define CONFIG_HLP_FLOG "Enable online log \n" -#define CONFIG_HLP_LOGL "Set the global log level, valid options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))\n" -#define CONFIG_HLP_LOGV "Set the global log verbosity \n" -#define CONFIG_HLP_TELN "Start embedded telnet server \n" -#define CONFIG_HLP_MSC "Enable the MSC tracing utility \n" -/*----------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters for LOG utility */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*----------------------------------------------------------------------------------------------------------------------------*/ -#define START_MSC softmodem_params.start_msc -#define CMDLINE_LOGPARAMS_DESC { \ - {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ - {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ - {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ - {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ - {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \ - } - -#define CMDLINE_ONLINELOG_IDX 0 -#define CMDLINE_GLOGLEVEL_IDX 1 -#define CMDLINE_GLOGVERBO_IDX 2 -#define CMDLINE_STARTTELN_IDX 3 - -/* check function for global log level */ -#define CMDLINE_LOGPARAMS_CHECK_DESC { \ - { .s5= {NULL} } , \ - { .s2= {config_check_intrange, {0,4}}}, \ - { .s5= {NULL} } , \ - { .s5= {NULL} } , \ - { .s5= {NULL} } , \ - } - -/***************************************************************************************************************************************/ - -#define SOFTMODEM_NOS1_BIT (1<<0) -#define SOFTMODEM_NOKRNMOD_BIT (1<<1) -#define SOFTMODEM_NONBIOT_BIT (1<<2) -#define SOFTMODEM_RFSIM_BIT (1<<10) -#define SOFTMODEM_BASICSIM_BIT (1<<11) -#define SOFTMODEM_SIML1_BIT (1<<12) -#define SOFTMODEM_DOFORMS_BIT (1<<15) - -#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) -#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) -#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) -#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) -#define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT) -#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) -#define IS_SOFTMODEM_DOFORMS ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT) -extern uint64_t get_softmodem_optmask(void); -extern uint64_t set_softmodem_optmask(uint64_t bitmask); -extern void get_common_options(void); -extern softmodem_params_t *get_softmodem_params(void); -extern unsigned int is_nos1exec(char *exepath) ; uint64_t get_pdcp_optmask(void); extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; @@ -268,7 +145,6 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int rx_input_level_dBm; -extern uint8_t exit_missed_slots; extern uint64_t num_missed_slots; // counter for the number of missed slots extern int oaisim_flag; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index cd96b8adf4..b468ff12d4 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -169,7 +169,6 @@ int rx_input_level_dBm; static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots // prototypes from function implemented in lte-ue.c, probably should be elsewhere in a include file. @@ -264,26 +263,6 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { } - -void signal_handler(int sig) { - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - char msg[64]; - sprintf(msg,"Received linux signal %s...\n",strsignal(sig)); - exit_function(__FILE__, __FUNCTION__, __LINE__,msg); - } -} - - void exit_function(const char *file, const char *function, const int line, const char *s) { int CC_id; logClean(); @@ -596,9 +575,6 @@ int main( int argc, char **argv ) { get_options (); - if (is_nos1exec(argv[0]) ) - set_softmodem_optmask(SOFTMODEM_NOS1_BIT); - EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; printf("Running with %d UE instances\n",NB_UE_INST); @@ -645,10 +621,7 @@ int main( int argc, char **argv ) { printf ("PDCP PC5S socket\n"); pdcp_pc5_socket_init(); // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); + set_softmodem_sighandler(); check_clock(); #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" From d8ee1189d617d88e698834fad454b5a130adbbbe Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 4 Feb 2020 17:23:17 +0100 Subject: [PATCH 215/343] More updates gNB and UE runs without crashing; PBCH not decoding though --- executables/nr-ru.c | 8 ++++---- executables/nr-ue.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ac94b8ae39..368817bf16 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -334,7 +334,7 @@ void fh_if5_south_in(RU_t *ru, recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL); proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe; - proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); + proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); if (proc->first_rx == 0) { if (proc->tti_rx != *tti) { @@ -506,7 +506,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { // printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); frame_tx = (timestamp_tx / (fp->samples_per_subframe*10))&1023; uint32_t idx_sf = timestamp_tx / fp->samples_per_subframe; - tti_tx = (idx_sf * fp->slots_per_subframe + (int)round((timestamp_tx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); + tti_tx = (idx_sf * fp->slots_per_subframe + (int)round((float)(timestamp_tx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); if (proc->first_tx != 0) { *slot = tti_tx; @@ -667,7 +667,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; } else { - if (proc->timestamp_rx - old_ts != samples_per_slot) { + if (proc->timestamp_rx - old_ts != fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp)) { LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot); proc->timestamp_rx = ts-ru->ts_offset; @@ -676,7 +676,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe; - proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); + proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); // synchronize first reception to frame 0 subframe 0 LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 681f1d9e67..710901509e 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -240,7 +240,7 @@ static void UE_synch(void *arg) { if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + - round(((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); + round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n", hw_slot_offset, freq_offset, From 607f561efafe1a3f4224d388f09df6ce0766fb59 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 5 Feb 2020 10:28:35 +0100 Subject: [PATCH 216/343] changes for no coreset0 k_ssb (ssb_SubcarrierOffset from config file not working) --- openair1/PHY/INIT/nr_parms.c | 7 ++++++- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 10 ++++++++-- openair2/GNB_APP/gnb_config.c | 3 +-- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index cfc96168c6..c4e36a18bf 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -337,7 +337,12 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; - fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + config->ssb_table.ssb_subcarrier_offset); + uint8_t sco = 0; + if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset<24)) || + ((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset<12)) ) + sco = config->ssb_table.ssb_subcarrier_offset; + + fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco); // definition of Lmax according to ts 38.213 section 4.1 if (fp->dl_CarrierFreq < 6e9) { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 19709cf148..9e17251088 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -54,8 +54,14 @@ uint8_t SSB_Table[38]={0,2,4,6,8,10,12,14,254,254,16,18,20,22,24,26,28,30,254,25 extern uint8_t nfapi_mode; void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp) { - fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + cfg->ssb_table.ssb_subcarrier_offset.value); - LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,cfg->ssb_table.ssb_subcarrier_offset.value); + + uint8_t sco = 0; + if (((fp->freq_range == nr_FR1) && (cfg->ssb_table.ssb_subcarrier_offset.value<24)) || + ((fp->freq_range == nr_FR2) && (cfg->ssb_table.ssb_subcarrier_offset.value<12)) ) + sco = cfg->ssb_table.ssb_subcarrier_offset.value; + + fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + sco); + LOG_I(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); } void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 520aa52b37..1e1a4ea15b 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -505,7 +505,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t)); - int ssb_SubcarrierOffset = 0; + int ssb_SubcarrierOffset = 31; int pdsch_AntennaPorts = 1; uint64_t ssb_bitmap=0xff; memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t)); @@ -585,7 +585,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { fix_scc(scc,ssb_bitmap); } printf("NRRRC %d: 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) { } else if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) { diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index e31944e6eb..c7b28f2125 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -202,7 +202,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { mib->message.choice.mib->spare.size = 1; mib->message.choice.mib->spare.bits_unused = 7; // This makes a spare of 1 bits - mib->message.choice.mib->ssb_SubcarrierOffset = carrier->ssb_SubcarrierOffset; + mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15; mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero; AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n"); From da71b979088d56d3308f0c9fa7557da2c407e903 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 5 Feb 2020 11:51:55 +0100 Subject: [PATCH 217/343] updated to slot_fep --- openair1/PHY/MODULATION/slot_fep_nr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index beb769c01e..4c4439d52d 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -109,7 +109,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (no_prefix) { slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns); } else { - slot_offset = frame_parms->get_samples_per_slot(Ns,frame_parms); + slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); } /*if (l<0 || l>=7-frame_parms->Ncp) { @@ -258,7 +258,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, break; } - slot_offset = frame_parms->get_samples_per_slot(Ns,frame_parms); + slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); if(symbol == 0) From 1905611d255748f6ea9746eb0830ea080466fea2 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 5 Feb 2020 15:02:05 +0100 Subject: [PATCH 218/343] making ulsim run again, nr_dlsim should run again in CI --- .../{rcc-files => rrc-files}/rbconfig.raw | 0 .../{rcc-files => rrc-files}/reconfig.raw | Bin ci-scripts/runTestOnVM.sh | 2 +- cmake_targets/CMakeLists.txt | 3 +- cmake_targets/autotests/test_case_list.xml | 30 +++-- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- openair1/SIMULATION/NR_PHY/dlsim.c | 15 +-- openair1/SIMULATION/NR_PHY/ulsim.c | 116 +++++++++++++++--- .../NR_MAC_UE/nr_ue_dci_configuration.c | 2 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 3 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 13 files changed, 136 insertions(+), 45 deletions(-) rename ci-scripts/{rcc-files => rrc-files}/rbconfig.raw (100%) rename ci-scripts/{rcc-files => rrc-files}/reconfig.raw (100%) diff --git a/ci-scripts/rcc-files/rbconfig.raw b/ci-scripts/rrc-files/rbconfig.raw similarity index 100% rename from ci-scripts/rcc-files/rbconfig.raw rename to ci-scripts/rrc-files/rbconfig.raw diff --git a/ci-scripts/rcc-files/reconfig.raw b/ci-scripts/rrc-files/reconfig.raw similarity index 100% rename from ci-scripts/rcc-files/reconfig.raw rename to ci-scripts/rrc-files/reconfig.raw diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 8efe6e3257..74cffeedd4 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1260,7 +1260,7 @@ function start_rf_sim_nr_ue { 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 --phy-test --rcc_config_path /home/ubuntu/tmp/ci-scripts/rcc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --numerology 1 -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --phy-test --rcc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --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 diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 356328d7dc..b84ffd38a0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -127,7 +127,7 @@ endfunction() #set(CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "Release") + set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() message("CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}") add_list_string_option(CMAKE_BUILD_TYPE "RelWithDebInfo" "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." Debug Release RelWithDebInfo MinSizeRel) @@ -2766,7 +2766,6 @@ target_link_libraries(nr_pucchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) -#PUCCH ---> Prashanth add_executable(nr_dlsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index c4f15c3a16..eea6c037ae 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1089,25 +1089,29 @@ (Test8: 217 PRB 100 PDSCH-PRBs), (Test9: 217 PRB 80 PDSCH-Offset), (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset), - (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28 + (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28) + (Test12: 106 PRBs 50 PDSCH-PRBs MCS Index 16) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15 - -n100 -R106 -b106 - -n100 -R217 -b217 - -n100 -R273 -b273 - -n100 -R106 -o12 - -n100 -R217 -o48 - -n100 -R106 -a25 - -n100 -R106 -a51 - -n100 -R217 -b100 - -n100 -R217 -a80 - -n100 -R217 -a110 -b100 - -n100 -e28 - nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 + + -n100 -R106 -b106 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R217 -b217 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R273 -b273 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R106 -o12 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R217 -o48 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R106 -a25 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R106 -a51 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R217 -b100 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R217 -a80 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R217 -a110 -s5 -b100 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -e28 -s20 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -e16 -s10 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + + nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 PDSCH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 737bd4d1ff..177640bacc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -546,7 +546,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)); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 19709cf148..cd19643bc4 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -408,8 +408,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); } - //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); - //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); + LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); + LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 5ce6f9e420..6ffb7d7e50 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -229,17 +229,18 @@ int main(int argc, char **argv) int mcsIndex_set=0,rbStart_set=0,rbSize_set=0; int print_perf = 0; + FILE *scg_fd=NULL; + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:")) != -1) { switch (c) { - /*case 'f': - write_output_file=1; - output_fd = fopen(optarg,"w"); + case 'f': + scg_fd = fopen(optarg,"r"); - if (output_fd==NULL) { + if (scg_fd==NULL) { printf("Error opening %s\n",optarg); exit(-1); } - break;*/ + break; /*case 'd': frame_type = 1; @@ -429,7 +430,7 @@ int main(int argc, char **argv) printf("-O oversampling factor (1,2,4,8,16)\n"); printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); - //printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-f raw file containing RRC configuration (generated by gNB)\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); printf("-E used CSS scheduler\n"); printf("-o CORESET offset\n"); @@ -470,8 +471,8 @@ int main(int argc, char **argv) gNB_mac = RC.nrmac[0]; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); + // read in SCGroupConfig - FILE *scg_fd = fopen("reconfig.raw","r"); AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); char buffer[1024]; int msg_len=fread(buffer,1,1024,scg_fd); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index dddddec465..5f2351968c 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -52,7 +52,6 @@ #include "openair1/SIMULATION/TOOLS/sim.h" #include "openair1/SIMULATION/RF/rf.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" -#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" @@ -63,6 +62,7 @@ PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int sf_ahead=4, phy_test = 0; double cpuf; uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; @@ -116,7 +116,10 @@ int generate_dlsch_header(unsigned char *mac_header, uint64_t get_softmodem_optmask(void) {return 0;} int rlc_module_init (int enb) {return(0);} void pdcp_layer_init (void) {} +void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} void nr_ip_over_LTE_DRB_preconfiguration(void){} +int rrc_init_nr_global_param(void){return(0);} + // needed for some functions uint16_t n_rnti = 0x1234; @@ -166,6 +169,7 @@ int main(int argc, char **argv) UE_nr_rxtx_proc_t UE_proc; + FILE *scg_fd=NULL; if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) { @@ -175,7 +179,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:L:")) != -1) { + while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:G:M:N:P:R:S:L:")) != -1) { switch (c) { /*case 'd': @@ -190,16 +194,15 @@ int main(int argc, char **argv) number_of_frames = atoi(optarg); break; - /*case 'f': - write_output_file = 1; - output_fd = fopen(optarg, "w"); + case 'G': + scg_fd = fopen(optarg, "r"); - if (output_fd == NULL) { + if (scg_fd == NULL) { printf("Error opening %s\n", optarg); exit(-1); } - break;*/ + break; case 'g': switch ((char) *optarg) { @@ -356,10 +359,10 @@ int main(int argc, char **argv) //printf("-x Transmission mode (1,2,6 for the moment)\n"); printf("-y Number of TX antennas used in eNB\n"); printf("-z Number of RX antennas used in UE\n"); - printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); + printf("-G raw file containing RRC configuration (generated by gNB)\n"); printf("-M Multiple SSB positions in burst\n"); printf("-N Nid_cell\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); @@ -403,12 +406,74 @@ int main(int argc, char **argv) frame_parms->N_RB_UL = N_RB_UL; frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; - crcTableInit(); + RC.nb_nr_macrlc_inst = 1; + RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); + for (i = 0; i < RC.nb_nr_macrlc_inst; i++) + RC.nb_nr_mac_CC[i] = 1; + mac_top_init_gNB(); + gNB_MAC_INST* gNB_mac = RC.nrmac[0]; + gNB_RRC_INST rrc; + memset((void*)&rrc,0,sizeof(rrc)); - nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions); + // read in SCGroupConfig + AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); + char buffer[1024]; + int msg_len=fread(buffer,1,1024,scg_fd); + NR_RRCReconfiguration_t *NR_RRCReconfiguration; - phy_init_nr_gNB(gNB, 0, 0); - //init_eNB_afterRU(); + printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len); + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_RRCReconfiguration, + (void **)&NR_RRCReconfiguration, + (uint8_t *)buffer, + msg_len); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"NR_RRCReConfiguration decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, NR_RRCReconfiguration, 1 ); + exit(-1); + } + fclose(scg_fd); + + AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n"); + + NR_RRCReconfiguration_IEs_t *reconfig_ies = NR_RRCReconfiguration->criticalExtensions.choice.rrcReconfiguration; + NR_CellGroupConfig_t *secondaryCellGroup; + dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&secondaryCellGroup, + (uint8_t *)reconfig_ies->secondaryCellGroup->buf, + reconfig_ies->secondaryCellGroup->size); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"NR_CellGroupConfig decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, secondaryCellGroup, 1 ); + exit(-1); + } + + NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); + + rrc.carrier.servingcellconfigcommon = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + printf("%p,%p\n", + secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon, + rrc.carrier.servingcellconfigcommon); + + AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); + gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; + // common configuration + rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL); + // UE dedicated configuration + rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + phy_init_nr_gNB(gNB,0,0); + N_RB_DL = gNB->frame_parms.N_RB_DL; + + //crcTableInit(); + + //nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions); frame_length_complex_samples = frame_parms->samples_per_subframe; frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; @@ -428,7 +493,9 @@ int main(int argc, char **argv) } //nr_init_frame_parms_ue(&UE->frame_parms); - //init_nr_ue_transport(UE, 0); + init_nr_ue_transport(UE, 0); + + /* for (sf = 0; sf < 2; sf++) { for (i = 0; i < 2; i++) { @@ -441,6 +508,27 @@ int main(int argc, char **argv) } } + */ + + nr_l2_init_ue(NULL); + NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0); + + UE->if_inst = nr_ue_if_module_init(0); + UE->if_inst->scheduled_response = nr_ue_scheduled_response; + UE->if_inst->phy_config_request = nr_ue_phy_config_request; + UE->if_inst->dl_indication = nr_ue_dl_indication; + UE->if_inst->ul_indication = nr_ue_ul_indication; + + UE_mac->if_module = nr_ue_if_module_init(0); + + //Configure UE + rrc.carrier.MIB = (uint8_t*) malloc(4); + rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0); + + nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup->spCellConfig); + + nr_ue_phy_config_request(&UE_mac->phy_config); + unsigned char harq_pid = 0; @@ -681,7 +769,7 @@ int main(int argc, char **argv) break; } // frame loop - if(is_frame_in_error == 0) + if(is_frame_in_error == 1) break; } // SNR loop diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 412fcf09e3..677a27fb3d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -57,7 +57,7 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot) { // check if DL slot - if (is_nr_DL_slot(mac->scc->tdd_UL_DL_ConfigurationCommon,slot)==1) { + if (is_nr_DL_slot(mac->scc,slot)==1) { // get BWP 1, Coreset 0, SearchSpace 0 if (mac->DLbwp[0]==NULL) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 3e57953082..8f29aa56a3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -505,7 +505,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[gNB_mac->TX_req[CC_id].Number_of_PDUs]; mac_rlc_status_resp_t rlc_status; - nfapi_nr_config_request_t *cfg = &gNB_mac->config[0]; NR_UE_list_t *UE_list = &gNB_mac->UE_list; @@ -835,4 +834,4 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize); fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types); -} \ No newline at end of file +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 5a04909e5f..4ae679b8f5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -69,4 +69,4 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (sduP != NULL) UE_scheduling_control->ta_update = timing_advance; } -} \ No newline at end of file +} diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index cbf36f8856..5bc320d5e2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -112,7 +112,7 @@ typedef struct { DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB]; /// scheduling control info - NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; + UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; int next[MAX_MOBILES_PER_GNB]; int head; int next_ul[MAX_MOBILES_PER_GNB]; From 16d8248c8b6fc42116d2df0a1e659b82248b4eaf Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 5 Feb 2020 15:09:32 +0100 Subject: [PATCH 219/343] removing logs --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 8c6e8c7f18..9e17251088 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -414,8 +414,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); } - LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); - LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); + //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); + //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0); From 4d33b341c2dce68833b465bee2591aa94a544e9e Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 5 Feb 2020 18:13:11 +0100 Subject: [PATCH 220/343] updated phy simulators --- executables/nr-ru.c | 2 +- openair1/SIMULATION/NR_PHY/dlsim.c | 12 +++++----- openair1/SIMULATION/NR_PHY/pbchsim.c | 4 ++-- openair1/SIMULATION/NR_PHY/prachsim.c | 34 +++++++++++++-------------- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 183beef73a..dcc662b4b0 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -720,7 +720,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { unsigned int txs; int i,txsymb; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), - T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe)); + T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4)); int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 5ce6f9e420..103c73b903 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -740,7 +740,7 @@ int main(int argc, char **argv) if (gNB->frame_parms.nb_antennas_tx>1) LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); } - int tx_offset = slot*frame_parms->samples_per_slot; + int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); if (n_trials==1) printf("samples_per_slot_wCP = %d\n", frame_parms->samples_per_slot_wCP); //TODO: loop over slots @@ -769,13 +769,13 @@ int main(int argc, char **argv) if (output_fd) fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd); - int txlev = signal_energy(&txdata[0][(slot*frame_parms->samples_per_slot)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev)); - for (i=(slot * frame_parms->samples_per_slot); - i<((slot+1) * frame_parms->samples_per_slot); + for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)); + i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0)); i++) { for (aa=0; aanb_antennas_tx; aa++) { r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); @@ -791,8 +791,8 @@ int main(int argc, char **argv) sigma2 = pow(10, sigma2_dB/10); if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15.rbSize)); - for (i=(slot * frame_parms->samples_per_slot); - i<((slot+1) * frame_parms->samples_per_slot); + for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); + iget_samples_slot_timestamp(slot+1,frame_parms,0); i++) { for (aa=0; aanb_antennas_rx; aa++) { ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 9afba02290..0adeda61bb 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -479,14 +479,14 @@ int main(int argc, char **argv) for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { if (cyclic_prefix_type == 1) { PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][slot*frame_parms->samples_per_slot], + &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], frame_parms->ofdm_symbol_size, 12, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); } else { nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][slot*frame_parms->samples_per_slot], + &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], 14, frame_parms); } diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 74a286863b..1ec18858dc 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) nsymb = (frame_parms->Ncp == 0) ? 14 : 12; printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d,Frame type %s, Frequency Range %s\n",NUMBER_OF_OFDM_CARRIERS, - frame_parms->Ncp,frame_parms->samples_per_slot<<1,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2"); + frame_parms->Ncp,frame_parms->samples_per_subframe,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2"); ru->nr_frame_parms=frame_parms; ru->if_south = LOCAL_RF; @@ -421,7 +421,7 @@ int main(int argc, char **argv) } txdata = UE->common_vars.txdata; - printf("txdata %p\n",&txdata[0][subframe*frame_parms->samples_per_slot<<1]); + printf("txdata %p\n",&txdata[0][subframe*frame_parms->samples_per_subframe]); double fs,bw; @@ -524,25 +524,25 @@ int main(int argc, char **argv) /* tx_lev_dB not used later, no need to set */ //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - LOG_M("txsig0.m","txs0", &txdata[0][subframe*frame_parms->samples_per_slot<<1],frame_parms->samples_per_slot<<1,1,1); + LOG_M("txsig0.m","txs0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1); //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); // multipath channel dump_nr_prach_config(&gNB->frame_parms,subframe); - for (i=0; i<2*frame_parms->samples_per_slot<<1; i++) { + for (i=0; i<2*frame_parms->samples_per_subframe; i++) { for (aa=0; aa<1; aa++) { if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_slot<<1]))[(i<<1)]); - s_im[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_slot<<1]))[(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]); + s_im[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]); } else { for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { if (aa==0) { - r_re[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_slot<<1]))[(i<<1)]); - r_im[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_slot<<1]))[(i<<1)+1]); + r_re[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]); + r_im[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]); } else { - r_re[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_slot<<1]))[(i<<1)]); - r_im[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_slot<<1]))[(i<<1)+1]); + r_re[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]); + r_im[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]); } } } @@ -573,7 +573,7 @@ int main(int argc, char **argv) if (awgn_flag == 0) { multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im, - 2*frame_parms->samples_per_slot<<1,0); + 2*frame_parms->samples_per_subframe,0); } if (n_frames==1) { @@ -582,11 +582,11 @@ int main(int argc, char **argv) 10*log10(tx_lev)); } - for (i=0; isamples_per_slot<<1; i++) { + for (i=0; isamples_per_subframe; i++) { for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { - ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_slot<<1)])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_slot<<1)])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } uint16_t preamble_rx; @@ -612,11 +612,11 @@ int main(int argc, char **argv) printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy_list[0],preamble_delay_list[0]); - LOG_M("prach0.m","prach0", &txdata[0][subframe*frame_parms->samples_per_slot<<1],frame_parms->samples_per_slot<<1,1,1); + LOG_M("prach0.m","prach0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1); LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0],24576,1,1); LOG_M("rxsig0.m","rxs0", - &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_slot<<1], - frame_parms->samples_per_slot<<1,1,1); + &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], + frame_parms->samples_per_subframe,1,1); LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0],839*4,1,1); LOG_M("prach_preamble.m","prachp",&gNB->X_u[0],839,1,1); } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index dddddec465..cfa834b876 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -594,7 +594,7 @@ int main(int argc, char **argv) /////////// //////////////////////////////////////////////////// - tx_offset = slot*frame_parms->samples_per_slot; + tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); From bb7a78880955a596c15f1ddc87789559d0270b51 Mon Sep 17 00:00:00 2001 From: matzakos Date: Wed, 5 Feb 2020 18:47:02 +0100 Subject: [PATCH 221/343] nr-ip-UL-nos1: Integrate NR MAC PDU structures for the Uplink. Currently supporting only data SDUs, Control Elements to be added. --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 1 + openair2/LAYER2/MAC/mac_proto.h | 11 - openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 138 ++++ openair2/LAYER2/NR_MAC_UE/mac_defs.h | 95 +++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 9 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 638 +++--------------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 223 +++++- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 26 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 2 +- 10 files changed, 549 insertions(+), 596 deletions(-) create mode 100644 openair2/LAYER2/NR_MAC_COMMON/nr_mac.h diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 1d4fdcd538..5717b32805 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -180,7 +180,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8); #ifdef DEBUG_MAC_PDU - LOG_I(PHY, "Printing MAC PDU to be encoded: \n"); + LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", harq_process_ul_ue->TBS/8); for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { printf("0x%02x",harq_process_ul_ue->a[i]); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 3c727738cf..4dd67d373f 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -316,6 +316,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list->rx_indication_rel8.length = gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->TBS>>3; pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 564899ddcc..476fb68584 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -1295,14 +1295,3 @@ uint8_t ul_subframe2_k_phich(COMMON_channels_t *cc, sub_frame_t ul_subframe); /* Main loop of MAC itti message handling */ void *mac_enb_task(void *arg); -unsigned char -nr_generate_ulsch_header(uint8_t *mac_header, - uint8_t num_sdus, - uint8_t short_padding, - uint16_t *sdu_lengths, - uint8_t *sdu_lcids, - POWER_HEADROOM_CMD *power_headroom, - uint16_t *crnti, - BSR_SHORT *truncated_bsr, - BSR_SHORT *short_bsr, - BSR_LONG *long_bsr, unsigned short post_padding); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h new file mode 100644 index 0000000000..cb004e0c23 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -0,0 +1,138 @@ +/* + * 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 nr_mac.h + * \brief common MAC data structures, constant, and function prototype + * \author R. Knopp, K.H. HSU, G. Casati + * \date 2019 + * \version 0.1 + * \company Eurecom / NTUST / Fraunhofer IIS + * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr, guido.casati@iis.fraunhofer.de + * \note + * \warning + */ + +#ifndef __LAYER2_NR_MAC_H__ +#define __LAYER2_NR_MAC_H__ + +#include +#include +#include + +#define NR_BCCH_DL_SCH 3 // SI + +#define NR_BCCH_BCH 5 // MIB + +// For both DL/UL-SCH +// Except: +// - UL/DL-SCH: fixed-size MAC CE(known by LCID) +// - UL/DL-SCH: padding +// - UL-SCH: MSG3 48-bits +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// | L | + +// For both DL/UL-SCH +// For: +// - UL/DL-SCH: fixed-size MAC CE(known by LCID) +// - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) +// - UL-SCH: MSG3 48-bits +// |0|1|2|3|4|5|6|7| bit-wise +// |R|R| LCID | +// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; +// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; +// F: lenght of L is 0:8 or 1:16 bits wide +// R: Reserved bit, set to zero. + +typedef struct { + uint8_t LCID:6; // octet 1 [5:0] + uint8_t F:1; // octet 1 [6] + uint8_t R:1; // octet 1 [7] + uint8_t L:8; // octet 2 [7:0] +} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT; + +typedef struct { + uint8_t LCID:6; // octet 1 [5:0] + uint8_t F:1; // octet 1 [6] + uint8_t R:1; // octet 1 [7] + uint8_t L1:8; // octet 2 [7:0] + uint8_t L2:8; // octet 3 [7:0] +} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG; + +typedef struct { + uint8_t LCID:6; // octet 1 [5:0] + uint8_t R:2; // octet 1 [7:6] +} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED; + +// 38.321 ch. 6.1.3.4 +typedef struct { + uint8_t TA_COMMAND:6; // octet 1 [5:0] + uint8_t TAGID:2; // octet 1 [7:6] +} __attribute__ ((__packed__)) NR_MAC_CE_TA; + +// 38.321 ch6.2.1, 38.331 +#define DL_SCH_LCID_CCCH 0x00 +#define DL_SCH_LCID_DCCH 0x01 +#define DL_SCH_LCID_DCCH1 0x02 +#define DL_SCH_LCID_DTCH 0x03 +#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F +#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30 +#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31 +#define DL_SCH_LCID_SP_SRS_ACTIVATION 0x32 +#define DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT 0x33 +#define DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH 0x34 +#define DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH 0x35 +#define DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL 0x36 +#define DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT 0X37 +#define DL_SCH_LCID_DUPLICATION_ACT 0X38 +#define DL_SCH_LCID_SCell_ACT_4_OCT 0X39 +#define DL_SCH_LCID_SCell_ACT_1_OCT 0X3A +#define DL_SCH_LCID_L_DRX 0x3B +#define DL_SCH_LCID_DRX 0x3C +#define DL_SCH_LCID_TA_COMMAND 0x3D +#define DL_SCH_LCID_CON_RES_ID 0x3E +#define DL_SCH_LCID_PADDING 0x3F + +#define UL_SCH_LCID_CCCH 0x00 +#define UL_SCH_LCID_SRB1 0x01 +#define UL_SCH_LCID_SRB2 0x02 +#define UL_SCH_LCID_DTCH 0x03 +#define UL_SCH_LCID_SRB3 0x04 +#define UL_SCH_LCID_CCCH_MSG3 0x21 +#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 +#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 +#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 +#define UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT 0x38 +#define UL_SCH_LCID_SINGLE_ENTRY_PHR 0x39 +#define UL_SCH_LCID_C_RNTI 0x3A +#define UL_SCH_LCID_S_TRUNCATED_BSR 0x3B +#define UL_SCH_LCID_L_TRUNCATED_BSR 0x3C +#define UL_SCH_LCID_S_BSR 0x3D +#define UL_SCH_LCID_L_BSR 0x3E +#define UL_SCH_LCID_PADDING 0x3F + + +#endif /*__LAYER2_MAC_H__ */ + diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 9d75b06fa5..534f3bf9c3 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -53,6 +53,13 @@ #include "PHY/defs_nr_common.h" #define NB_NR_UE_MAC_INST 1 +/*!\brief Maximum number of logical channl group IDs */ +#define MAX_NUM_LCGID 4 +/*!\brief Maximum number of logical chanels */ +#define MAX_NUM_LCID 11 + +/*!\brief value for indicating BSR Timer is not running */ +#define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) typedef enum { SFN_C_MOD_2_EQ_0, @@ -60,6 +67,86 @@ typedef enum { SFN_C_IMPOSSIBLE } SFN_C_TYPE; +#define UL_SCH_LCID_CCCH 0x00 +#define UL_SCH_LCID_SRB1 0x01 +#define UL_SCH_LCID_SRB2 0x02 +#define UL_SCH_LCID_DTCH 0x03 +#define UL_SCH_LCID_SRB3 0x04 +#define UL_SCH_LCID_CCCH_MSG3 0x21 +#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 +#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 +#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 +#define UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT 0x38 +#define UL_SCH_LCID_SINGLE_ENTRY_PHR 0x39 +#define UL_SCH_LCID_C_RNTI 0x3A +#define UL_SCH_LCID_S_TRUNCATED_BSR 0x3B +#define UL_SCH_LCID_L_TRUNCATED_BSR 0x3C +#define UL_SCH_LCID_S_BSR 0x3D +#define UL_SCH_LCID_L_BSR 0x3E +#define UL_SCH_LCID_PADDING 0x3F + +// LTE structure, might need to be adapted for NR +typedef struct { + /// buffer status for each lcgid + uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology + /// keep the number of bytes in rlc buffer for each lcgid + int32_t BSR_bytes[MAX_NUM_LCGID]; + /// after multiplexing buffer remain for each lcid + int32_t LCID_buffer_remain[MAX_NUM_LCID]; + /// sum of all lcid buffer size + uint16_t All_lcid_buffer_size_lastTTI; + /// buffer status for each lcid + uint8_t LCID_status[MAX_NUM_LCID]; + /// SR pending as defined in 36.321 + uint8_t SR_pending; + /// SR_COUNTER as defined in 36.321 + uint16_t SR_COUNTER; + /// logical channel group ide for each LCID + uint8_t LCGID[MAX_NUM_LCID]; + /// retxBSR-Timer, default value is sf2560 + uint16_t retxBSR_Timer; + /// retxBSR_SF, number of subframe before triggering a regular BSR + uint16_t retxBSR_SF; + /// periodicBSR-Timer, default to infinity + uint16_t periodicBSR_Timer; + /// periodicBSR_SF, number of subframe before triggering a periodic BSR + uint16_t periodicBSR_SF; + /// default value is 0: not configured + uint16_t sr_ProhibitTimer; + /// sr ProhibitTime running + uint8_t sr_ProhibitTimer_Running; + /// default value to n5 + uint16_t maxHARQ_Tx; + /// default value is false + uint16_t ttiBundling; + /// default value is release + struct DRX_Config *drx_config; + /// default value is release + struct MAC_MainConfig__phr_Config *phr_config; + ///timer before triggering a periodic PHR + uint16_t periodicPHR_Timer; + ///timer before triggering a prohibit PHR + uint16_t prohibitPHR_Timer; + ///DL Pathloss change value + uint16_t PathlossChange; + ///number of subframe before triggering a periodic PHR + int16_t periodicPHR_SF; + ///number of subframe before triggering a prohibit PHR + int16_t prohibitPHR_SF; + ///DL Pathloss Change in db + uint16_t PathlossChange_db; + + /// default value is false + uint16_t extendedBSR_Sizes_r10; + /// default value is false + uint16_t extendedPHR_r10; + + //Bj bucket usage per lcid + int16_t Bj[MAX_NUM_LCID]; + // Bucket size per lcid + int16_t bucket_size[MAX_NUM_LCID]; +} NR_UE_SCHEDULING_INFO; + /*!\brief Top level UE MAC structure */ typedef struct { @@ -82,6 +169,7 @@ typedef struct { /// Random access parameter uint16_t ra_rnti; + uint16_t crnti; //BWP params NR_BWP_PARMS initial_bwp_dl; @@ -96,6 +184,13 @@ typedef struct { nr_ue_if_module_t *if_module; nr_scheduled_response_t scheduled_response; nr_phy_config_t phy_config; + + /// BSR report flag management + uint8_t BSR_reporting_active; + NR_UE_SCHEDULING_INFO scheduling_info; + + /// PHR + uint8_t PHR_reporting_active; } NR_UE_MAC_INST_t; typedef enum seach_space_mask_e { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index c33d624469..9ddb47601d 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -140,5 +140,14 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode); +unsigned char +nr_generate_ulsch_pdu(uint8_t *mac_pdu, + uint8_t *sdus_payload, + uint8_t num_sdus, + uint16_t *sdu_lengths, + uint8_t *sdu_lcids, + uint16_t *crnti, + uint16_t buflen); + #endif /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 4b966fd7b1..ceff5baaa7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2319,282 +2319,63 @@ unsigned char *nr_parse_header(unsigned char *mac_header, } unsigned char -nr_generate_ulsch_header(uint8_t *mac_header, +nr_generate_ulsch_pdu(uint8_t *mac_pdu, + uint8_t *sdus_payload, uint8_t num_sdus, - uint8_t short_padding, uint16_t *sdu_lengths, uint8_t *sdu_lcids, - POWER_HEADROOM_CMD *power_headroom, uint16_t *crnti, - BSR_SHORT *truncated_bsr, - BSR_SHORT *short_bsr, - BSR_LONG *long_bsr, unsigned short post_padding) { - SCH_SUBHEADER_FIXED *mac_header_ptr = - (SCH_SUBHEADER_FIXED *) mac_header; - unsigned char first_element = 0, last_size = 0, i; - unsigned char mac_header_control_elements[16], *ce_ptr; - LOG_D(MAC, "[UE] Generate ULSCH : num_sdus %d\n", num_sdus); -#ifdef DEBUG_HEADER_PARSING + uint16_t buflen) { - for (i = 0; i < num_sdus; i++) { - LOG_T(MAC, "[UE] sdu %d : lcid %d length %d", i, sdu_lcids[i], - sdu_lengths[i]); - } + NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; + unsigned char * ulsch_buffer_ptr = sdus_payload; + uint8_t last_size=0; + uint16_t sdu_length_total; + int i; + int offset=0; - LOG_T(MAC, "\n"); -#endif - ce_ptr = &mac_header_control_elements[0]; + // 2) Generation of ULSCH MAC SDU subheaders + for (i = 0; i < num_sdus; i++) { + LOG_D(MAC, "[gNB] Generate ULSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]); - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element = 1; - last_size = 1; - } + if (sdu_lengths[i] < 128) { + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; + last_size = 2; + } else { + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; + last_size = 3; + } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size = 1; - } + mac_pdu_ptr += last_size; - if (power_headroom) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in + memcpy((void *) mac_pdu_ptr, (void *) ulsch_buffer_ptr, sdu_lengths[i]); + ulsch_buffer_ptr+= sdu_lengths[i]; + mac_pdu_ptr += sdu_lengths[i]; + } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = POWER_HEADROOM; - last_size = 1; - *((POWER_HEADROOM_CMD *) ce_ptr) = (*power_headroom); - ce_ptr += sizeof(POWER_HEADROOM_CMD); - LOG_D(MAC, "phr header size %zu\n", sizeof(POWER_HEADROOM_CMD)); - } + // 4) Compute final offset for padding + uint16_t padding_bytes = buflen - sdu_length_total; + if (padding_bytes > 0) { + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING; + mac_pdu_ptr++; - if (crnti) { -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] CRNTI : %x (first_element %d)\n", *crnti, - first_element); -#endif + } else { + // no MAC subPDU with padding + } - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = CRNTI; - last_size = 1; - *((uint16_t *) ce_ptr) = (*crnti); - ce_ptr += sizeof(uint16_t); - // printf("offset %d\n",ce_ptr-mac_header_control_elements); - } - if (truncated_bsr) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } - -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] Scheduler Truncated BSR Header\n"); -#endif - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = TRUNCATED_BSR; - last_size = 1; - *((BSR_TRUNCATED *) ce_ptr) = (*truncated_bsr); - ce_ptr += sizeof(BSR_TRUNCATED); - // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } else if (short_bsr) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } - -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] Scheduler SHORT BSR Header\n"); -#endif - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_BSR; - last_size = 1; - *((BSR_SHORT *) ce_ptr) = (*short_bsr); - ce_ptr += sizeof(BSR_SHORT); - // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } else if (long_bsr) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } - -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] Scheduler Long BSR Header\n"); -#endif - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = LONG_BSR; - last_size = 1; - *(ce_ptr) = - (long_bsr-> - Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4); - *(ce_ptr + 1) = - ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr-> - Buffer_size2 & 0x3C) - >> 2); - *(ce_ptr + 2) = - ((long_bsr-> - Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F); - ce_ptr += BSR_LONG_SIZE; - // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } - - // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - - for (i = 0; i < num_sdus; i++) { -#ifdef DEBUG_HEADER_PARSING - LOG_T(MAC, "[UE] sdu subheader %d (lcid %d, %d bytes)\n", i, - sdu_lcids[i], sdu_lengths[i]); -#endif - - if ((i == (num_sdus - 1)) - && ((short_padding) || (post_padding == 0))) { - if (first_element > 0) { - mac_header_ptr->E = 1; -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", - *(unsigned char *) mac_header_ptr, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); -#endif - mac_header_ptr += last_size; - } - - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = sdu_lcids[i]; - } else { - if ((first_element > 0)) { - mac_header_ptr->E = 1; -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", - *(unsigned char *) mac_header_ptr, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); -#endif - mac_header_ptr += last_size; - // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - } else { - first_element = 1; - } - - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; // 3 - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = - sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = - (unsigned char) sdu_lengths[i]; - last_size = 2; -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] short sdu\n"); - LOG_T(MAC, - "[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n", - ((uint16_t *) mac_header_ptr)[0], - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L); -#endif - } else { - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = - sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = - ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = - (unsigned short) sdu_lengths[i] & 0xff; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; - last_size = 3; -#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] long sdu\n"); -#endif - } - } - } - - if (post_padding > 0) { // we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr += last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; - //mac_header_ptr=last_size; // FIXME: should be ++ - } - - if ((ce_ptr - mac_header_control_elements) > 0) { - memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); - mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); - } - -#ifdef DEBUG_HEADER_PARSING - LOG_T(MAC, " [UE] header : "); - - for (i = 0; i < ((unsigned char *) mac_header_ptr - mac_header); i++) { - LOG_T(MAC, "%2x.", mac_header[i]); - } - - LOG_T(MAC, "\n"); -#endif - return ((unsigned char *) mac_header_ptr - mac_header); + return offset; } @@ -2694,93 +2475,68 @@ nr_ue_send_sdu(module_id_t module_idP, } -/* LTE based function to be substituted once NR version is ready */ + uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, - uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) - -{ + uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; uint16_t buflen_remain = 0; - uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; - uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; - uint8_t lcid = 0, lcid_rlc_pdu_count = 0; - boolean_t is_lcid_processed = FALSE; - boolean_t is_all_lcid_processed = FALSE; + uint8_t lcid = 0; uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t payload_offset = 0, num_sdus = 0; - uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; + uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; uint16_t sdu_length_total = 0; - BSR_SHORT bsr_short, bsr_truncated; - BSR_LONG bsr_long; - BSR_SHORT *bsr_s = &bsr_short; - BSR_LONG *bsr_l = &bsr_long; - BSR_SHORT *bsr_t = &bsr_truncated; - POWER_HEADROOM_CMD phr; - POWER_HEADROOM_CMD *phr_p = &phr; - unsigned short short_padding = 0, post_padding = 0, padding_len = 0; + unsigned short post_padding = 0, padding_len = 0; int j; // used for padding - // Compute header length - int lcg_id = 0; - int lcg_id_bsr_trunc = 0; - int highest_priority = 16; - int num_lcg_id_with_data = 0; + rlc_buffer_occupancy_t lcid_buffer_occupancy_old = 0, lcid_buffer_occupancy_new = 0; - - NR_UE_MAC_INST_t *nr_ue_mac_inst = get_mac_inst(0); - - LOG_D(MAC, "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", module_idP, frameP, subframe, buflen); AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); +#if UE_TIMING_TRACE + start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); +#endif - bsr_header_len = 0; - phr_header_len = 0; // 1; //sizeof(SCH_SUBHEADER_FIXED); - - rlc_buffer_occupancy_t buffer_occupancy = mac_rlc_get_buffer_occupancy_ind( module_idP, 0x1234, eNB_index, frameP, subframe,ENB_FLAG_NO,DTCH); + NR_UE_MAC_INST_t *nr_ue_mac_inst = get_mac_inst(0); // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization - for (lcid = DTCH; - (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE); lcid++) { - lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind( module_idP, 0x1234, eNB_index, frameP, subframe,ENB_FLAG_NO,lcid); - if (lcid_buffer_occupancy_old > 0) { - lcid_rlc_pdu_count = 0; - is_lcid_processed = FALSE; + for (lcid = DCCH; + lcid < MAX_NUM_LCID; lcid++) { + lcid_buffer_occupancy_old = + //TODO: Replace static value with CRNTI + mac_rlc_get_buffer_occupancy_ind(module_idP, + 0x1234, eNB_index, frameP, //nr_ue_mac_inst->crnti + subframe, ENB_FLAG_NO, + lcid); lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; - - //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data - //Adjust at the end of the loop - while ((!is_lcid_processed) && (lcid_buffer_occupancy_new) - && (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) { + if(lcid_buffer_occupancy_new){ buflen_remain = - buflen - (bsr_len + phr_len + - total_rlc_pdu_header_len + sdu_length_total + - 1); - LOG_I(MAC, + buflen - (total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE); + LOG_D(MAC, "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " - "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", + "send (Transport Block size %d SDU Length Total %d , mac header len %d )\n", //BSR byte before Tx=%d module_idP, frameP, lcid, lcid_buffer_occupancy_new, - buflen, bsr_len, phr_len, sdu_length_total, - total_rlc_pdu_header_len); + buflen, sdu_length_total, + total_rlc_pdu_header_len); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]] + //TODO: Replace static value with CRNTI sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - 0x1234, eNB_index, + 0x1234, eNB_index, //nr_ue_mac_inst->crnti frameP, ENB_FLAG_NO, MBMS_FLAG_NO, lcid, buflen_remain, - (char *)&ulsch_buff[sdu_length_total],0, + (char *)&ulsch_sdus[sdu_length_total],0, 0 ); AssertFatal(buflen_remain >= sdu_lengths[num_sdus], @@ -2790,247 +2546,58 @@ nr_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); - - if (buflen == - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1)) { - //No more remaining TBS after this PDU - //exit the function - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; - } else { - rlc_pdu_header_len_last = - (sdu_lengths[num_sdus] > 128) ? 3 : 2; - - //Change to 1 byte if it does not fit in the TBS, ie last PDU - if (buflen <= - (bsr_len + phr_len + total_rlc_pdu_header_len + - rlc_pdu_header_len_last + sdu_length_total)) { - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; - } - } + //LOG_I(MAC, + // "[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n", + // module_idP, sdu_lengths[num_sdus], lcid); //Update number of SDU num_sdus++; //Update total MAC Header size for RLC PDUs and save last one total_rlc_pdu_header_len += rlc_pdu_header_len_last; - lcid_rlc_pdu_count++; - } else { - /* avoid infinite loop ... */ - is_lcid_processed = TRUE; } /* Get updated BO after multiplexing this PDU */ - lcid_buffer_occupancy_new = - mac_rlc_get_buffer_occupancy_ind( module_idP, - 0x1234, - eNB_index, - frameP, - subframe, - ENB_FLAG_NO, - lcid); + //TODO: Replace static value with CRNTI + + /*lcid_buffer_occupancy_new = + mac_rlc_get_buffer_occupancy_ind(module_idP, + 0x1234, //nr_ue_mac_inst->crnti + eNB_index, frameP, + subframe, ENB_FLAG_NO, + lcid); is_lcid_processed = (is_lcid_processed) - || (lcid_buffer_occupancy_new <= 0); - } - - //Update Buffer remain and BSR bytes after transmission - AssertFatal(lcid_buffer_occupancy_new <= - lcid_buffer_occupancy_old, - "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n", - lcid_buffer_occupancy_new, - lcid_buffer_occupancy_old, lcid, - lcid_rlc_pdu_count, frameP, subframe); - } + || (lcid_buffer_occupancy_new <= 0);*/ } +} - // build PHR and update the timers - /*if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { - //Substitute with a static value for the MAC layer abstraction (phy_stub mode) - phr_p->PH = 40; - } else { - phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); - } - - phr_p->R = 0; - LOG_D(MAC, - "[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", - module_idP, frameP, get_PHR(module_idP, CC_id, eNB_index), - phr_p->PH, POWER_HEADROOM); - update_phr(module_idP, CC_id); - } else { - phr_p = NULL; - }*/ - - - // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order - // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 - /* For Padding BSR: - - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader: - - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission; - - else report Short BSR. - - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. - */ - if (sdu_length_total) { - padding_len = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - - rlc_pdu_header_len_last + sdu_length_total + 1); - } else { - padding_len = buflen - (bsr_len + phr_len); - } - - /* if ((padding_len) && (bsr_len == 0)) { - // if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR - if (padding_len >= (1 + BSR_LONG_SIZE)) { - bsr_ce_len = BSR_LONG_SIZE; - bsr_header_len = 1; - // Trigger BSR Padding - UE_mac_inst[module_idP].BSR_reporting_active |= - BSR_TRIGGER_PADDING; - } else if (padding_len >= (1 + sizeof(BSR_SHORT))) { - bsr_ce_len = sizeof(BSR_SHORT); - bsr_header_len = 1; - - if (num_lcg_id_with_data > 1) { - // REPORT TRUNCATED BSR - //Get LCGID of highest priority LCID with data - for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { - if (UE_mac_inst[module_idP]. - logicalChannelConfig[lcid] != NULL) { - lcg_id = - UE_mac_inst[module_idP].scheduling_info. - LCGID[lcid]; - - if ((lcg_id < MAX_NUM_LCGID) - && (UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[lcg_id]) - && - (UE_mac_inst[module_idP].logicalChannelConfig - [lcid]->ul_SpecificParameters->priority <= - highest_priority)) { - highest_priority = - UE_mac_inst[module_idP]. - logicalChannelConfig[lcid]-> - ul_SpecificParameters->priority; - lcg_id_bsr_trunc = lcg_id; - } - } - } - } else { - //Report SHORT BSR, clear bsr_t - bsr_t = NULL; - } - - // Trigger BSR Padding - UE_mac_inst[module_idP].BSR_reporting_active |= - BSR_TRIGGER_PADDING; - } - - bsr_len = bsr_header_len + bsr_ce_len; - }*/ - - //Fill BSR Infos - if (bsr_ce_len == 0) { - bsr_s = NULL; - bsr_l = NULL; - bsr_t = NULL; - } - else { - LOG_W(MAC, "BSR not null \n"); - } - - // 1-bit padding or 2-bit padding special padding subheader - // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 - if (sdu_length_total) { - padding_len = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - - rlc_pdu_header_len_last + sdu_length_total + 1); - } else { - padding_len = buflen - (bsr_len + phr_len); - } - - if (padding_len <= 2) { - short_padding = padding_len; - // only add padding header - post_padding = 0; - - //update total MAC Hdr size for RLC data - if (sdu_length_total) { - total_rlc_pdu_header_len = - total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1; - rlc_pdu_header_len_last = 1; - } - } else if (sdu_length_total) { - post_padding = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1); - - // If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding - if (post_padding == 0) { - total_rlc_pdu_header_len -= rlc_pdu_header_len_last; - padding_len = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1); - short_padding = padding_len; - total_rlc_pdu_header_len++; - } - } else { - if (padding_len == buflen) { // nona mac pdu - *access_mode = CANCELED_ACCESS; - } - - short_padding = 0; - post_padding = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1); - } - - // Generate header - // if (num_sdus>0) { - - // cycle through SDUs and place in ulsch_buffer - if (sdu_length_total) { - payload_offset = nr_generate_ulsch_header(ulsch_buffer, // mac header + // Generate ULSCH PDU + if (num_sdus>0) { + payload_offset = nr_generate_ulsch_pdu(ulsch_buffer, // mac header + ulsch_sdus, num_sdus, // num sdus - short_padding, // short pading sdu_lengths, // sdu length sdu_lcids, // sdu lcid - phr_p, // power headroom NULL, // crnti - bsr_t, // truncated bsr - bsr_s, // short bsr - bsr_l, post_padding); // long_bsr - LOG_D(MAC, - "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n", - module_idP, buflen, sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], payload_offset, total_rlc_pdu_header_len, - short_padding, post_padding, bsr_len, phr_len, - buflen - sdu_length_total - payload_offset); - - - memcpy(&ulsch_buffer[payload_offset], ulsch_buff, - sdu_length_total); + buflen); // long_bsr } else return 0; + LOG_D(MAC, + "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, post_padding %d, remainder %d \n", + module_idP, buflen, sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], payload_offset, total_rlc_pdu_header_len, + post_padding, buflen - sdu_length_total - payload_offset); - // fill remainder of DLSCH with random data - if (post_padding) { - for (j = 0; j < (buflen - sdu_length_total - payload_offset); j++) { - ulsch_buffer[payload_offset + sdu_length_total + j] = - (char) (taus() & 0xff); - } + // Padding: fill remainder of ULSCH with 0 + if (buflen - payload_offset > 0){ + for (int j = 0; j < (buflen - payload_offset); j++) + ulsch_buffer[payload_offset + j] = 0; } + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_D(MAC, "Printing UL MAC payload without the header UE side: \n"); - for (int i = payload_offset; i < sdu_length_total ; i++) { + LOG_I(MAC, "Printing UL MAC payload without the header UE side, payload_offset: %d \n", payload_offset); + for (int i = 0; i < sdu_length_total ; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); printf("%02x ",(unsigned char)ulsch_buffer[i]); @@ -3039,9 +2606,4 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, #endif return 1; - } - - - - diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 1615a8e687..a041f7cce3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -34,6 +34,7 @@ #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" #include "executables/nr-softmodem.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac.h" extern RAN_CONTEXT_t RC; //#define ENABLE_MAC_PAYLOAD_DEBUG 1 @@ -549,7 +550,185 @@ void nr_schedule_uss_ulsch_phytest(nfapi_nr_ul_tti_request_t *UL_tti_req, } } -void +void nr_process_mac_pdu( + module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t *pduP, + uint16_t mac_pdu_len) +{ + + // This function is adapting code from the old + // parse_header(...) and ue_send_sdu(...) functions of OAI LTE + + uint8_t *pdu_ptr = pduP, rx_lcid, done = 0, i; + int pdu_len = mac_pdu_len; + uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; + + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + + LOG_I(MAC, "LCID received at gNB side: %d \n", rx_lcid); + + // For both DL/UL-SCH + // Except: + // - UL/DL-SCH: fixed-size MAC CE(known by LCID) + // - UL/DL-SCH: padding + // - UL-SCH: MSG3 48-bits + // |0|1|2|3|4|5|6|7| bit-wise + // |R|F| LCID | + // | L | + // |0|1|2|3|4|5|6|7| bit-wise + // |R|F| LCID | + // | L | + // | L | + + // For both DL/UL-SCH + // For: + // - UL/DL-SCH: fixed-size MAC CE(known by LCID) + // - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) + // - UL-SCH: MSG3 48-bits + // |0|1|2|3|4|5|6|7| bit-wise + // |R|R| LCID | + // LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; + // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; + // F: lenght of L is 0:8 or 1:16 bits wide + // R: Reserved bit, set to zero. + + while (!done && pdu_len > 0){ + mac_ce_len = 0; + mac_subheader_len = 1; // default to fixed-length subheader = 1-oct + mac_sdu_len = 0; + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + + LOG_I(MAC, "LCID received at gNB side: %d \n", rx_lcid); + + switch(rx_lcid){ + // MAC CE + + /*#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); + #endif*/ + + case UL_SCH_LCID_PADDING: + done = 1; + // end of MAC PDU, can ignore the rest. + break; + + case UL_SCH_LCID_DTCH: + // check if LCID is valid at current time. + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); + + } else { + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + } + + LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); + + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + + for (i = 0; i < 32; i++) + LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); + + LOG_T(MAC, "\n"); + #endif + + if (IS_SOFTMODEM_NOS1){ + if (rx_lcid < NB_RB_MAX && rx_lcid >= UL_SCH_LCID_DTCH) { + + mac_rlc_data_ind(module_idP, + 0x1234, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + } else { + LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, module_idP); + } + } + + break; + + default: + return; + break; + } + pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + + AssertFatal(pdu_len >= 0, "[MAC] nr_process_mac_pdu, residual mac pdu length < 0!\n"); + } +} + +void nr_rx_sdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t ttiP, + const rnti_t rntiP, + uint8_t * pdu, + const uint16_t pdu_len, + const uint16_t timing_advance, + const uint8_t ul_cqi) +{ + + LOG_I(MAC, "Handling PDU frame %d slot %d pdu_len: %d \n", frameP, ttiP, pdu_len); + + uint8_t * pduP = pdu; + + + /*if (opt_enabled) { + trace_pdu(DIRECTION_DOWNLINK, pduP, pdu_len, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP + 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].cs_RNTI, pdu_len); + }*/ + + /* + #ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d gNB_index %d : num_ce %d num_sdu %d\n", + module_idP, frameP, gNB_index, num_ce, num_sdu); + #endif + */ + + /* + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + for (i = 0; i < 32; i++) { + LOG_T(MAC, "%x.", sdu[i]); + } + LOG_T(MAC, "\n"); + #endif + */ + + // Processing MAC PDU + // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs + if (pduP != NULL){ + LOG_I(MAC, "Received PDU at MAC gNB \n"); + nr_process_mac_pdu(module_idP, CC_id, frameP, pduP, pdu_len); + } + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); + + /* + #if UE_TIMING_TRACE + stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); + #endif + */ +} + + +/* LTE based function to be substituted once NR version is ready */ +/*void nr_rx_sdu(const module_id_t enb_mod_idP, const int CC_idP, const frame_t frameP, @@ -582,7 +761,7 @@ nr_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 */ + // Init current_rnti = rntiP; UE_id = 0; //find_UE_id(enb_mod_idP, current_rnti); //mac = RC.mac[enb_mod_idP]; @@ -604,7 +783,7 @@ nr_rx_sdu(const module_id_t enb_mod_idP, return; } - /* Control element */ + // Control element for (int i = 0; i < num_ce; i++) { switch (rx_ces[i]) { // implement and process PHR + CRNTI + BSR @@ -690,7 +869,7 @@ nr_rx_sdu(const module_id_t enb_mod_idP, rx_lcids[i]); if (UE_id != -1) { - /* Adjust buffer occupancy of the correponding logical channel group */ + // Adjust buffer occupancy of the correponding logical channel group LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d \n", enb_mod_idP, CC_idP, @@ -709,14 +888,15 @@ nr_rx_sdu(const module_id_t enb_mod_idP, pritnf("\n"); #endif 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+1, rx_lengths[i], 1, NULL); - } else { /* rx_length[i] Max size */ + } else { // rx_length[i] Max size //UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; - LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d. Size of received payload: %d \n", enb_mod_idP, CC_idP, frameP, rx_lcids[i], - UE_id); + UE_id, + rx_lengths[i]); } } else { // end if (UE_id != -1) LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", @@ -734,32 +914,5 @@ nr_rx_sdu(const module_id_t enb_mod_idP, payload_ptr += rx_lengths[i]; } - /* Program ACK for PHICH */ - - /*LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", - 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]; - memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; - hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;*/ - - /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ - -} +}*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 95abba549a..77d6053a35 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -145,15 +145,21 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); -void -nr_rx_sdu(const module_id_t enb_mod_idP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP, - uint8_t *sduP, - const uint16_t sdu_lenP, - const uint16_t timing_advance, - const uint8_t ul_cqi); +void nr_rx_sdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t ttiP, + const rnti_t rntiP, + uint8_t * pdu, + uint16_t pdu_len, + const uint16_t timing_advance, + const uint8_t ul_cqi); + +void nr_process_mac_pdu( + module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t *pduP, + uint16_t mac_pdu_len); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 2094b3517e..6a6dc74695 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -192,7 +192,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } else { - LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); + LOG_I(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok), received length: %d \n",UL_info->frame,UL_info->slot, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length); nr_rx_sdu(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, From e4d8dd1e66721a0c28614101502389bf33aeea8e Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 5 Feb 2020 22:57:24 +0100 Subject: [PATCH 222/343] ulsim working again. added error count and adapted test_case_list --- cmake_targets/autotests/test_case_list.xml | 10 +-- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 39 +++++---- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- openair1/SIMULATION/NR_PHY/ulsim.c | 83 +++++++++---------- 4 files changed, 64 insertions(+), 72 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index eea6c037ae..5227ed010e 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1253,11 +1253,11 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15 - -f100 -m9 -r106 -s10 - -f100 -m16 -s20 - -f100 -m28 -s30 - -f100 -m9 -R217 -r217 -s10 - -f100 -m9 -R273 -r273 -s10 + -n100 -m9 -r106 -s0 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -m16 -s10 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -m28 -s20 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -m9 -R217 -r217 -s0 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -m9 -R273 -r273 -s0 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 PUSCH test OK segmentation fault|assertion|exiting|fatal diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index a0fb8d7ed6..872342cd5b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -684,7 +684,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } harq_process->handled = 1; - return (ulsch->max_ldpc_iterations + 1); + ret = ulsch->max_ldpc_iterations + 1; } else { @@ -705,29 +705,28 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, { LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); } - } - - // Reassembly of Transport block here - offset = 0; - Kr = harq_process->K; - Kr_bytes = Kr>>3; - - for (r=0; rC; r++) { - - memcpy(harq_process->b+offset, - harq_process->c[r], - Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); - - offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); + // Reassembly of Transport block here + offset = 0; + Kr = harq_process->K; + Kr_bytes = Kr>>3; + + for (r=0; rC; r++) { + + memcpy(harq_process->b+offset, + harq_process->c[r], + Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + + offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); + #ifdef DEBUG_ULSCH_DECODING - 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", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]); + 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", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]); #endif - + + } } - ulsch->last_iteration_cnt = ret; return(ret); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9e17251088..f9c154ea29 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -279,9 +279,9 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH 0); if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations) - LOG_I(PHY, "ULSCH in error\n"); + LOG_I(PHY, "ULSCH %d in error\n",ULSCH_id); else - LOG_I(PHY, "ULSCH received ok\n"); + LOG_I(PHY, "ULSCH %d received ok\n",ULSCH_id); } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 5f2351968c..2c397090ba 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -131,9 +131,9 @@ int main(int argc, char **argv) int i,sf; double SNR, snr0 = -2.0, snr1 = 2.0; double sigma, sigma_dB; - double snr_step = 0.1; + double snr_step = 1; uint8_t snr1set = 0; - int slot = 0; + int slot = 0, frame = 0; FILE *output_fd = NULL; //uint8_t write_output_file = 0; int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0; @@ -147,13 +147,12 @@ int main(int argc, char **argv) SCM_t channel_model = AWGN; //Rayleigh1_anticorr; uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; //unsigned char frame_type = 0; - int number_of_frames = 1; int frame_length_complex_samples,frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; int loglvl = OAILOG_WARNING; uint64_t SSB_positions=0x01; uint16_t nb_symb_sch = 12; - int start_symbol = 2; + int start_symbol = 0; uint16_t nb_rb = 50; uint8_t Imcs = 9; uint8_t precod_nbr_layers = 1; @@ -164,7 +163,8 @@ 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) - + float target_error_rate = 0.01; + cpuf = get_cpu_freq_GHz(); @@ -179,7 +179,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:G:M:N:P:R:S:L:")) != -1) { + 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:L:")) != -1) { switch (c) { /*case 'd': @@ -191,10 +191,6 @@ int main(int argc, char **argv) break; case 'f': - number_of_frames = atoi(optarg); - break; - - case 'G': scg_fd = fopen(optarg, "r"); if (scg_fd == NULL) { @@ -505,7 +501,6 @@ int main(int argc, char **argv) printf("Can't get ue ulsch structures\n"); exit(-1); } - } } */ @@ -543,7 +538,6 @@ int main(int argc, char **argv) unsigned char *test_input_bit; uint32_t errors_decoding = 0; uint32_t errors_scrambling = 0; - uint32_t is_frame_in_error = 0; test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); @@ -581,13 +575,6 @@ int main(int argc, char **argv) for (SNR = snr0; SNR < snr1; SNR += snr_step) { - printf("-------------------\n"); - printf("SNR %f\n", SNR); - printf("-------------------\n"); - - is_frame_in_error = 0; - for (int frame = 0; frame < number_of_frames; frame++) { - UE_proc.nr_tti_tx = slot; UE_proc.frame_tx = frame; @@ -677,7 +664,7 @@ int main(int argc, char **argv) phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0); - if (number_of_frames==1) + if (n_trials==1) LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_length_complex_samples,1,1); /////////// @@ -717,12 +704,16 @@ int main(int argc, char **argv) //---------------------------------------------------------- phy_procedures_gNB_common_RX(gNB, frame, slot); - if (number_of_frames==1) + if (n_trials==1) LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],frame_length_complex_samples_no_prefix,1,1); phy_procedures_gNB_uespec_RX(gNB, frame, slot); //////////////////////////////////////////////////////////// + if (gNB->ulsch[0][0]->last_iteration_cnt >= + gNB->ulsch[0][0]->max_ldpc_iterations+1) + n_errors++; + //---------------------------------------------------------- //----------------- count and print errors ----------------- //---------------------------------------------------------- @@ -732,14 +723,15 @@ int main(int argc, char **argv) if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) || ((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0))) { - if(errors_scrambling == 0) - printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i); + /*if(errors_scrambling == 0) + printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/ errors_scrambling++; } } if (errors_scrambling > 0) { - printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %d\n" "\x1B[0m", frame, trial, errors_scrambling); + if (n_trials==1) + printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %d\n" "\x1B[0m", frame, trial, errors_scrambling); } for (i = 0; i < TBS; i++) { @@ -748,38 +740,39 @@ int main(int argc, char **argv) test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); if (estimated_output_bit[i] != test_input_bit[i]) { - if(errors_decoding == 0) - printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i); + /*if(errors_decoding == 0) + printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i);*/ errors_decoding++; } } if (errors_decoding > 0) { - is_frame_in_error = 1; n_false_positive++; - printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %d\n" "\x1B[0m", frame, trial, errors_decoding); - } else { - is_frame_in_error = 0; - break; - } - //////////////////////////////////////////////////////////// + if (n_trials==1) + printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %d\n" "\x1B[0m", frame, trial, errors_decoding); + } + } // trial loop - if (is_frame_in_error == 1) - break; - } // frame loop + printf("*****************************************\n"); + printf("SNR %f: n_errors (negative CRC) = %d/%d, false_positive %d/%d, errors_scrambling %d/%d\n", SNR, n_errors, n_trials, n_false_positive, n_trials, errors_scrambling, n_trials); + printf("\n"); + printf("SNR %f: Channel BLER %e, Channel BER %e\n", SNR,(double)n_errors/n_trials,(double)errors_scrambling/available_bits/n_trials); + printf("*****************************************\n"); + printf("\n"); - if(is_frame_in_error == 1) - break; + if(n_trials==1) + break; + + if ((float)n_errors/(float)n_trials <= target_error_rate) { + printf("*************\n"); + printf("PUSCH test OK\n"); + printf("*************\n"); + break; + } + } // SNR loop - if(is_frame_in_error == 0) { - printf("\n"); - printf("*************\n"); - printf("PUSCH test OK\n"); - printf("*************\n"); - } - printf("\n"); free(test_input_bit); From d22c0f720de0d5164cfe0298a06745756d5c5d5f Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 6 Feb 2020 14:33:38 +0100 Subject: [PATCH 223/343] fix for ssb bitmap endian (to be checked with FSW) --- openair1/PHY/INIT/nr_init.c | 11 ++++++++-- openair1/PHY/INIT/nr_parms.c | 20 +++++++++--------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 3 +-- openair1/SIMULATION/NR_PHY/pbchsim.c | 3 ++- openair2/GNB_APP/RRC_nr_paramsvalues.h | 2 +- openair2/GNB_APP/gnb_config.c | 25 +++++++++++++++++++---- openair2/LAYER2/NR_MAC_UE/config_ue.c | 9 ++++---- openair2/LAYER2/NR_MAC_gNB/config.c | 8 ++++---- 8 files changed, 53 insertions(+), 28 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 781e8129e0..df9747104a 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -360,12 +360,16 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config; //overwrite for new NR parameters + uint64_t rev_burst=0; + for (int i=0; i<64; i++) + rev_burst |= (((position_in_burst>>(63-i))&0x01)<cell_config.phy_cell_id.value = Nid_cell; gNB_config->ssb_config.scs_common.value = mu; gNB_config->ssb_table.ssb_subcarrier_offset.value = 0; gNB_config->ssb_table.ssb_offset_point_a.value = (N_RB_DL-20)>>1; - gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = position_in_burst; - gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = position_in_burst>>32; + gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = (rev_burst)&(0xFFFFFFFF); + gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = (rev_burst>>32)&(0xFFFFFFFF); gNB_config->cell_config.frame_duplex_type.value = TDD; gNB_config->ssb_table.ssb_period.value = 1; //10ms gNB_config->carrier_config.dl_grid_size[mu].value = N_RB_DL; @@ -381,6 +385,9 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->nr_band = 78; fp->threequarter_fs= 0; + + gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band); + nr_init_frame_parms(gNB_config, fp); gNB->configured = 1; LOG_I(PHY,"gNB configured\n"); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index c4e36a18bf..1ae0a47d59 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -99,12 +99,12 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) // selection of SS block pattern according to TS 38101-1 Table 5.4.3.3-1 for SCS 30kHz if (fp->nr_band == 5 || fp->nr_band == 66) - fp->ssb_type = nr_ssb_type_B; + fp->ssb_type = nr_ssb_type_B; else{ if (fp->nr_band == 41 || ( fp->nr_band > 76 && fp->nr_band < 80) ) - fp->ssb_type = nr_ssb_type_C; + fp->ssb_type = nr_ssb_type_C; else - AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu); + AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu); } switch(bw){ @@ -148,21 +148,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) break; case 90: - AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu); + AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu); fp->ofdm_symbol_size = 4096; fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 ) fp->nb_prefix_samples0 = 352; fp->nb_prefix_samples = 288; break; case 100: - AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu); + AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu); fp->ofdm_symbol_size = 4096; fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 ) fp->nb_prefix_samples0 = 352; fp->nb_prefix_samples = 288; break; default: - AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp); + AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); } break; @@ -184,7 +184,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) case 90: case 100: default: - AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp); + AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); } break; @@ -206,7 +206,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) fp->nb_prefix_samples = 36; break; default: - AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp); + AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); } break; @@ -227,7 +227,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, { fp->frame_type = cfg->cell_config.frame_duplex_type.value; - fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[1].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[0].ssb_mask.value ; + fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; @@ -354,7 +354,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Lmax = 64; } - fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[0].ssb_mask; + fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; fp->N_ssb = 0; for (int p=0; pLmax; p++) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9e17251088..3f7dff55aa 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -95,8 +95,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index - if ((ssb_index<64) && ((fp->L_ssb >> ssb_index) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1 - + if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1 fp->ssb_index = ssb_index; int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 9afba02290..d094b26238 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -589,7 +589,8 @@ int main(int argc, char **argv) while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb frame_parms->ssb_index = ssb_index; UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms); - int ssb_slot = (ssb_index/2)+(n_hf*frame_parms->slots_per_frame); + + int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { nr_slot_fep(UE, i%frame_parms->symbols_per_slot, diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 0b54b62e4a..82873f22b4 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -301,7 +301,7 @@ {GNB_CONFIG_STRING_PRACHMSG1FDM,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM,defint64val:NR_RACH_ConfigGeneric__msg1_FDM_one,TYPE_INT64,0/*72*/},\ {GNB_CONFIG_STRING_PRACHMSG1FREQUENCYSTART,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart,defint64val:0,TYPE_INT64,0/*73*/},\ {GNB_CONFIG_STRING_ZEROCORRELATIONZONECONFIG,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,defint64val:13,TYPE_INT64,0/*74*/},\ -{GNB_CONFIG_STRING_PREAMBLERECEIVEDTARGETPOWER,NULL,0,iptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower,defintval:-118,TYPE_INT32,0/*75*/},\ +{GNB_CONFIG_STRING_PREAMBLERECEIVEDTARGETPOWER,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower,defintval:-118,TYPE_INT64,0/*75*/},\ {GNB_CONFIG_STRING_PREAMBLETRANSMAX,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleTransMax,defint64val:NR_RACH_ConfigGeneric__preambleTransMax_n10,TYPE_INT64,0/*76*/},\ {GNB_CONFIG_STRING_POWERRAMPINGSTEP,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.powerRampingStep,defint64val:NR_RACH_ConfigGeneric__powerRampingStep_dB2,TYPE_INT64,0/*77*/},\ {GNB_CONFIG_STRING_RARESPONSEWINDOW,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow,defint64val:NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20,TYPE_INT64,0/*78*/},\ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 1e1a4ea15b..9845adbeaa 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -212,23 +212,40 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { int ssbmaplen = (int)scc->ssb_PositionsInBurst->present; + uint8_t curr_bit; + AssertFatal(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap || ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap || ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap, "illegal ssbmaplen %d\n",ssbmaplen); + + // changing endianicity of ssbmap and filling the ssb_PositionsInBurst buffers if(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap){ scc->ssb_PositionsInBurst->choice.shortBitmap.size = 1; scc->ssb_PositionsInBurst->choice.shortBitmap.bits_unused = 4; scc->ssb_PositionsInBurst->choice.shortBitmap.buf = CALLOC(1,1); - scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] = ssbmap; + scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] = 0; + for (int i=0; i<8; i++) { + if (issb_PositionsInBurst->choice.shortBitmap.bits_unused) + curr_bit = 0; + else + curr_bit = (ssbmap>>(7-i))&0x01; + scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] |= curr_bit<ssb_PositionsInBurst->choice.mediumBitmap.size = 1; scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0; scc->ssb_PositionsInBurst->choice.mediumBitmap.buf = CALLOC(1,1); - scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0] = ssbmap; + scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0] = 0; + for (int i=0; i<8; i++) + scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0] |= (((ssbmap>>(7-i))&0x01)<ssb_PositionsInBurst->choice.longBitmap.size = 8; scc->ssb_PositionsInBurst->choice.longBitmap.bits_unused = 0; scc->ssb_PositionsInBurst->choice.longBitmap.buf = CALLOC(1,8); - for (int i=0; i<8; i++) - scc->ssb_PositionsInBurst->choice.longBitmap.buf[i] = (ssbmap>>(i<<3))&(0xff); + for (int j=0; j<8; j++) { + scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] = 0; + curr_bit = (ssbmap>>(j<<3))&(0xff); + for (int i=0; i<8; i++) + scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] |= (((curr_bit>>(7-i))&0x01)<ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10; cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; cfg->ssb_table.ssb_subcarrier_offset = 0; // TODO currently not in RRC? + switch (scc->ssb_PositionsInBurst->present) { case 1 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]; + cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; break; case 2 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; + cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; break; case 3 : cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; for (i=0; i<4; i++) { - cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_PositionsInBurst->present) { case 1 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]; + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; break; case 2 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; break; case 3 : cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = 0; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; for (i=0; i<4; i++) { - cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]< Date: Thu, 6 Feb 2020 14:57:16 +0100 Subject: [PATCH 224/343] fixing a bad merge, removing a log, resetting MAX_LDPC_ITERATIONS=5 --- executables/nr-gnb.c | 2 -- openair1/PHY/CODING/coding_defs.h | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 3f1b95a793..0302697e5b 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -479,8 +479,6 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot } AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); - AssertFatal((ret=pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"mutex_lock returned %d\n",ret); - ru_proc->instance_cnt_gNBs = 0; ru_proc->timestamp_tx = timestamp_tx; ru_proc->tti_tx = slot_tx; diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 00708ed60c..9b111309cd 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -38,7 +38,7 @@ #define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS max_turbo_iterations -#define MAX_LDPC_ITERATIONS 10//5 +#define MAX_LDPC_ITERATIONS 5 #define MAX_LDPC_ITERATIONS_MBSFN 4 #define LTE_NULL 2 diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index f9c154ea29..025e92eb22 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -61,7 +61,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME sco = cfg->ssb_table.ssb_subcarrier_offset.value; fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + sco); - LOG_I(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); + LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); } void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { From 239c30d92a33861b8cf2b5b86d4d3b39d3fff93c Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 6 Feb 2020 10:48:53 +0100 Subject: [PATCH 225/343] updating gNB config file for CI --- .../gnb.band78.tm1.106PRB.usrpn300.conf | 339 ++++++++---------- 1 file changed, 156 insertions(+), 183 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index e71bb00ffb..4564907fa8 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -21,183 +21,166 @@ gNBs = ////////// Physical parameters: - component_carriers = ( - { - node_function = "3GPP_gNODEB"; - node_timing = "synch_to_ext_device"; - node_synch_ref = 0; - frame_type = "TDD"; - DL_prefix_type = "NORMAL"; - UL_prefix_type = "NORMAL"; - eutra_band = 78; - downlink_frequency = 3510000000L; - uplink_frequency_offset = -120000000; - Nid_cell = 0; - N_RB_DL = 106; - nb_antenna_ports = 1; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 90; - rx_gain = 125; - MIB_subCarrierSpacingCommon = 30; - MIB_ssb_SubcarrierOffset = 0; - MIB_dmrs_TypeA_Position = 2; - pdcch_ConfigSIB1 = 0; - SIB1_frequencyOffsetSSB = "khz5"; - SIB1_ssb_PeriodicityServingCell = 5; - SIB1_ss_PBCH_BlockPower = -60; - absoluteFrequencySSB = 0; - DL_FreqBandIndicatorNR = 15; - DL_absoluteFrequencyPointA = 15; - DL_offsetToCarrier = 15; - DL_SCS_SubcarrierSpacing = "kHz30"; - DL_SCS_SpecificCarrier_k0 = 0; - DL_carrierBandwidth = 15; - DL_locationAndBandwidth = 15; - DL_BWP_SubcarrierSpacing = "kHz30"; - DL_BWP_prefix_type = "NORMAL"; - UL_FreqBandIndicatorNR = 15; - UL_absoluteFrequencyPointA = 13; - UL_additionalSpectrumEmission = 3; - UL_p_Max = -1; - UL_frequencyShift7p5khz = "TRUE"; - UL_offsetToCarrier = 10; - UL_SCS_SubcarrierSpacing = "kHz30"; - UL_SCS_SpecificCarrier_k0 = 0; - UL_carrierBandwidth = 15; - UL_locationAndBandwidth = 15; - UL_BWP_SubcarrierSpacing = "kHz30"; - UL_BWP_prefix_type = "NORMAL"; - UL_timeAlignmentTimerCommon = "infinity"; - ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" - ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; - ServingCellConfigCommon_dmrs_TypeA_Position = 2; - NIA_SubcarrierSpacing = "kHz15"; - ServingCellConfigCommon_ss_PBCH_BlockPower = -60; - referenceSubcarrierSpacing = "kHz15"; - dl_UL_TransmissionPeriodicity = "ms0p5"; - nrofDownlinkSlots = 10; - nrofDownlinkSymbols = 10; - nrofUplinkSlots = 10; - nrofUplinkSymbols = 10; - rach_totalNumberOfRA_Preambles = 63; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth"; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2; - rach_groupBconfigured = "ENABLE"; - rach_ra_Msg3SizeGroupA = 56; - rach_messagePowerOffsetGroupB = "dB0"; - rach_numberOfRA_PreamblesGroupA = 32; - rach_ra_ContentionResolutionTimer = 8; - rsrp_ThresholdSSB = 64; - rsrp_ThresholdSSB_SUL = 64; - prach_RootSequenceIndex_choice = "l839"; - prach_RootSequenceIndex_l839 = 0; - prach_RootSequenceIndex_l139 = 0; - prach_msg1_SubcarrierSpacing = "kHz30"; - restrictedSetConfig = "unrestrictedSet"; - msg3_transformPrecoding = "ENABLE"; - prach_ConfigurationIndex = 10; - prach_msg1_FDM = "one"; - prach_msg1_FrequencyStart = 10; - zeroCorrelationZoneConfig = 10; - preambleReceivedTargetPower = -150; - preambleTransMax = 6; - powerRampingStep = "dB0"; - ra_ResponseWindow = 8; - groupHoppingEnabledTransformPrecoding = "ENABLE"; - msg3_DeltaPreamble = 0; - p0_NominalWithGrant = 0; - PUSCH_TimeDomainResourceAllocation_k2 = 0; - PUSCH_TimeDomainResourceAllocation_mappingType = "typeA"; - PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; - pucch_ResourceCommon = 0; - pucch_GroupHopping = "neither"; - hoppingId = 0; - p0_nominal = -30; - PDSCH_TimeDomainResourceAllocation_k0 = 2; - PDSCH_TimeDomainResourceAllocation_mappingType = "typeA"; - PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; - rateMatchPatternId = 0; - RateMatchPattern_patternType = "bitmaps"; - symbolsInResourceBlock = "oneSlot"; - periodicityAndPattern = 2; - RateMatchPattern_controlResourceSet = 5; - RateMatchPattern_subcarrierSpacing = "kHz30"; - RateMatchPattern_mode = "dynamic"; - controlResourceSetZero = 0; - searchSpaceZero = 0; - searchSpaceSIB1 = 10; - searchSpaceOtherSystemInformation = 10; - pagingSearchSpace = 10; - ra_SearchSpace = 10; - PDCCH_common_controlResourceSetId = 5; - PDCCH_common_ControlResourceSet_duration = 2; - PDCCH_cce_REG_MappingType = "nonInterleaved"; - PDCCH_reg_BundleSize = 3; - PDCCH_interleaverSize = 3; - PDCCH_shiftIndex = 10; - PDCCH_precoderGranularity = "sameAsREG-bundle"; - PDCCH_TCI_StateId = 32; - tci_PresentInDCI = "ENABLE"; - PDCCH_DMRS_ScramblingID = 0; - SearchSpaceId = 10; - commonSearchSpaces_controlResourceSetId = 5; - SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1"; - SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; - SearchSpace_duration = 2; - SearchSpace_nrofCandidates_aggregationLevel1 = 0; - SearchSpace_nrofCandidates_aggregationLevel2 = 0; - SearchSpace_nrofCandidates_aggregationLevel4 = 0; - SearchSpace_nrofCandidates_aggregationLevel8 = 0; - SearchSpace_nrofCandidates_aggregationLevel16 = 0; - SearchSpace_searchSpaceType = "common"; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1; - Common_dci_Format2_3_monitoringPeriodicity = 1; - Common_dci_Format2_3_nrofPDCCH_Candidates = 1; - ue_Specific__dci_Formats = "formats0-0-And-1-0"; - RateMatchPatternLTE_CRS_carrierFreqDL = 6; - RateMatchPatternLTE_CRS_carrierBandwidthDL = 6; - RateMatchPatternLTE_CRS_nrofCRS_Ports = 1; - RateMatchPatternLTE_CRS_v_Shift = 0; - RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1; - RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; - RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame"; - } - ); - - - srb1_parameters : + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( { - # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] - timer_poll_retransmit = 80; + #spCellConfigCommon - # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] - timer_reordering = 35; + physCellId = 0; - # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] - timer_status_prohibit = 0; +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=2,L=3 + initialDLBWPstartSymbolAndLength_0 = 40; - # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] - poll_pdu = 4; + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; - # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] - poll_byte = 99999; + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#0 = 839, 1 = 139 + prach_RootSequenceIndex_PR = 1; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 255; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); - # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] - max_retx_threshold = 4; - } # ------- SCTP definitions SCTP : @@ -254,8 +237,8 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "addr=192.168.20.2,second_addr=192.168.10.2,mgmt_addr=192.168.20.2,clock_source=external,time_source=external"; - + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2"; + clock_src = "external"; } ); @@ -268,16 +251,6 @@ THREAD_STRUCT = ( } ); -NETWORK_CONTROLLER : -{ - FLEXRAN_ENABLED = "no"; - FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; - FLEXRAN_PORT = 2210; - FLEXRAN_CACHE = "/mnt/oai_agent_cache"; - FLEXRAN_AWAIT_RECONF = "no"; -}; - log_config : { global_log_level ="info"; From 86670eccb40652e385239df33914afb434511c4d Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 6 Feb 2020 15:49:04 +0100 Subject: [PATCH 226/343] forcing rnti to 4660 in nr_dlsim, as otherwise CCE allocation does not work (to be fixed) --- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 6ffb7d7e50..473c86bed0 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -524,7 +524,7 @@ int main(int argc, char **argv) // common configuration rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,1,NULL,1,4660/*secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity*/,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; // stub to configure frame_parms From 93ac6bd4261b457ed8feb4d16477be90b3ae71b9 Mon Sep 17 00:00:00 2001 From: matzakos Date: Thu, 6 Feb 2020 18:21:12 +0100 Subject: [PATCH 227/343] nr-ip-UL-nos1: Substitute LTE macros in new NR functions and data structures + logs cleanup --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 4 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 3 + openair2/LAYER2/NR_MAC_UE/mac.h | 61 ------------------- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 37 +++-------- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 11 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 41 +------------ openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 2 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 2 +- 10 files changed, 27 insertions(+), 138 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 5717b32805..547dd523ca 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -192,7 +192,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid //and block this traffic from being forwarded to the upper layers at the gNB uint16_t payload_offset = 5; - LOG_E(PHY, "Random data to be tranmsitted: \n"); + LOG_D(PHY, "Random data to be tranmsitted: \n"); //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver for (i = 0; ia[i] = 0; @@ -426,7 +426,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// //////////////////////////////////////////////////////////////////////// - LOG_I(PHY, "Is data existing ?: %d \n", data_existing); + LOG_D(PHY, "Is data existing ?: %d \n", data_existing); return data_existing; } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 4dd67d373f..2d92f63e6b 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -288,7 +288,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id LOG_I(PHY, "ULSCH in error\n"); //gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b else if(gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->b!=NULL){ - LOG_D(PHY, "ULSCH received ok \n"); + LOG_I(PHY, "ULSCH received ok \n"); if(IS_SOFTMODEM_NOS1){ //&& gNB->ulsch[UE_id][0]->rnti == 0x1234 nr_fill_crc_indication (gNB, UE_id, frame_rx, slot_rx, 0); nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 568ef5f736..6282e81066 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2502,7 +2502,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } // UE_mode==PUSCH */ - LOG_I(PHY, "Sending data \n"); + LOG_D(PHY, "Sending data \n"); nr_ue_pusch_common_procedures(ue, harq_pid, slot_tx, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index cb004e0c23..80bfec6cf9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -133,6 +133,9 @@ typedef struct { #define UL_SCH_LCID_L_BSR 0x3E #define UL_SCH_LCID_PADDING 0x3F +#define NR_MAX_NUM_LCID 32 +#define NR_MAX_NUM_LCGID 8 + #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac.h b/openair2/LAYER2/NR_MAC_UE/mac.h index fe8e91500a..25e5ded996 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac.h +++ b/openair2/LAYER2/NR_MAC_UE/mac.h @@ -49,65 +49,4 @@ typedef enum { UE_PHY_HO_PRACH } NR_UE_L2_STATE_t; -typedef struct { - uint8_t LCID:6; // octet 1 [5:0] - uint8_t F:1; // octet 1 [6] - uint8_t R:1; // octet 1 [7] - uint8_t L:8; // octet 2 [7:0] -} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT; - -typedef struct { - uint8_t LCID:6; // octet 1 [5:0] - uint8_t F:1; // octet 1 [6] - uint8_t R:1; // octet 1 [7] - uint8_t L1:8; // octet 2 [7:0] - uint8_t L2:8; // octet 3 [7:0] -} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG; - -typedef struct { - uint8_t LCID:6; // octet 1 [5:0] - uint8_t R:2; // octet 1 [7:6] -} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED; - -// 38.321 ch6.2.1, 38.331 -#define DL_SCH_LCID_CCCH 0x00 -#define DL_SCH_LCID_SRB1 0x01 -#define DL_SCH_LCID_SRB2 0x02 -#define DL_SCH_LCID_SRB3 0x03 -#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F -#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30 -#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31 -#define DL_SCH_LCID_SP_SRS_ACTIVATION 0x32 -#define DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT 0x33 -#define DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH 0x34 -#define DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH 0x35 -#define DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL 0x36 -#define DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT 0X37 -#define DL_SCH_LCID_DUPLICATION_ACT 0X38 -#define DL_SCH_LCID_SCell_ACT_4_OCT 0X39 -#define DL_SCH_LCID_SCell_ACT_1_OCT 0X3A -#define DL_SCH_LCID_L_DRX 0x3B -#define DL_SCH_LCID_DRX 0x3C -#define DL_SCH_LCID_TA_COMMAND 0x3D -#define DL_SCH_LCID_CON_RES_ID 0x3E -#define DL_SCH_LCID_PADDING 0x3F - -#define UL_SCH_LCID_CCCH 0x00 -#define UL_SCH_LCID_SRB1 0x01 -#define UL_SCH_LCID_SRB2 0x02 -#define UL_SCH_LCID_SRB3 0x03 -#define UL_SCH_LCID_CCCH_MSG3 0x21 -#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 -#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 -#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 -#define UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT 0x38 -#define UL_SCH_LCID_SINGLE_ENTRY_PHR 0x39 -#define UL_SCH_LCID_C_RNTI 0x3A -#define UL_SCH_LCID_S_TRUNCATED_BSR 0x3B -#define UL_SCH_LCID_L_TRUNCATED_BSR 0x3C -#define UL_SCH_LCID_S_BSR 0x3D -#define UL_SCH_LCID_L_BSR 0x3E -#define UL_SCH_LCID_PADDING 0x3F - - #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 534f3bf9c3..b97d4696e7 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -51,12 +51,11 @@ #include "fapi_nr_ue_interface.h" #include "NR_IF_Module.h" #include "PHY/defs_nr_common.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #define NB_NR_UE_MAC_INST 1 /*!\brief Maximum number of logical channl group IDs */ -#define MAX_NUM_LCGID 4 -/*!\brief Maximum number of logical chanels */ -#define MAX_NUM_LCID 11 + /*!\brief value for indicating BSR Timer is not running */ #define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) @@ -67,42 +66,24 @@ typedef enum { SFN_C_IMPOSSIBLE } SFN_C_TYPE; -#define UL_SCH_LCID_CCCH 0x00 -#define UL_SCH_LCID_SRB1 0x01 -#define UL_SCH_LCID_SRB2 0x02 -#define UL_SCH_LCID_DTCH 0x03 -#define UL_SCH_LCID_SRB3 0x04 -#define UL_SCH_LCID_CCCH_MSG3 0x21 -#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 -#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 -#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37 -#define UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT 0x38 -#define UL_SCH_LCID_SINGLE_ENTRY_PHR 0x39 -#define UL_SCH_LCID_C_RNTI 0x3A -#define UL_SCH_LCID_S_TRUNCATED_BSR 0x3B -#define UL_SCH_LCID_L_TRUNCATED_BSR 0x3C -#define UL_SCH_LCID_S_BSR 0x3D -#define UL_SCH_LCID_L_BSR 0x3E -#define UL_SCH_LCID_PADDING 0x3F - // LTE structure, might need to be adapted for NR typedef struct { /// buffer status for each lcgid - uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology + uint8_t BSR[NR_MAX_NUM_LCGID]; // should be more for mesh topology /// keep the number of bytes in rlc buffer for each lcgid - int32_t BSR_bytes[MAX_NUM_LCGID]; + int32_t BSR_bytes[NR_MAX_NUM_LCGID]; /// after multiplexing buffer remain for each lcid - int32_t LCID_buffer_remain[MAX_NUM_LCID]; + int32_t LCID_buffer_remain[NR_MAX_NUM_LCID]; /// sum of all lcid buffer size uint16_t All_lcid_buffer_size_lastTTI; /// buffer status for each lcid - uint8_t LCID_status[MAX_NUM_LCID]; + uint8_t LCID_status[NR_MAX_NUM_LCID]; /// SR pending as defined in 36.321 uint8_t SR_pending; /// SR_COUNTER as defined in 36.321 uint16_t SR_COUNTER; /// logical channel group ide for each LCID - uint8_t LCGID[MAX_NUM_LCID]; + uint8_t LCGID[NR_MAX_NUM_LCID]; /// retxBSR-Timer, default value is sf2560 uint16_t retxBSR_Timer; /// retxBSR_SF, number of subframe before triggering a regular BSR @@ -142,9 +123,9 @@ typedef struct { uint16_t extendedPHR_r10; //Bj bucket usage per lcid - int16_t Bj[MAX_NUM_LCID]; + int16_t Bj[NR_MAX_NUM_LCID]; // Bucket size per lcid - int16_t bucket_size[MAX_NUM_LCID]; + int16_t bucket_size[NR_MAX_NUM_LCID]; } NR_UE_SCHEDULING_INFO; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index ceff5baaa7..df27f5b8db 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -36,9 +36,10 @@ #include "assertions.h" #include "PHY/defs_nr_UE.h" #include "common/utils/LOG/log.h" -#include "openair2/LAYER2/MAC/mac.h" -#include "openair2/LAYER2/RLC/rlc.h" +//#include "openair2/LAYER2/MAC/mac.h" +//#include "openair2/LAYER2/RLC/rlc.h" #include "SIMULATION/TOOLS/sim.h" // for taus +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #include #include @@ -2184,7 +2185,7 @@ void nr_ue_process_mac_pdu( break; // MAC SDU - case DL_SCH_LCID_SRB1: + case DL_SCH_LCID_DCCH: // check if LCID is valid at current time. case UL_SCH_LCID_SRB2: // check if LCID is valid at current time. @@ -2506,8 +2507,8 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization - for (lcid = DCCH; - lcid < MAX_NUM_LCID; lcid++) { + for (lcid = UL_SCH_LCID_SRB1; + lcid < NR_MAX_NUM_LCID; lcid++) { lcid_buffer_occupancy_old = //TODO: Replace static value with CRNTI diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index a041f7cce3..cabaee7b5c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -565,9 +565,6 @@ void nr_process_mac_pdu( int pdu_len = mac_pdu_len; uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; - rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; - - LOG_I(MAC, "LCID received at gNB side: %d \n", rx_lcid); // For both DL/UL-SCH // Except: @@ -600,7 +597,7 @@ void nr_process_mac_pdu( mac_sdu_len = 0; rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; - LOG_I(MAC, "LCID received at gNB side: %d \n", rx_lcid); + LOG_D(MAC, "LCID received at gNB side: %d \n", rx_lcid); switch(rx_lcid){ // MAC CE @@ -681,49 +678,17 @@ void nr_rx_sdu(module_id_t module_idP, const uint8_t ul_cqi) { - LOG_I(MAC, "Handling PDU frame %d slot %d pdu_len: %d \n", frameP, ttiP, pdu_len); + LOG_D(MAC, "Handling PDU frame %d slot %d pdu_len: %d \n", frameP, ttiP, pdu_len); uint8_t * pduP = pdu; - - /*if (opt_enabled) { - trace_pdu(DIRECTION_DOWNLINK, pduP, pdu_len, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].cs_RNTI, frameP, ttiP, 0, 0); //subframeP - 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].cs_RNTI, pdu_len); - }*/ - - /* - #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d gNB_index %d : num_ce %d num_sdu %d\n", - module_idP, frameP, gNB_index, num_ce, num_sdu); - #endif - */ - - /* - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - for (i = 0; i < 32; i++) { - LOG_T(MAC, "%x.", sdu[i]); - } - LOG_T(MAC, "\n"); - #endif - */ - // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs if (pduP != NULL){ - LOG_I(MAC, "Received PDU at MAC gNB \n"); + LOG_D(MAC, "Received PDU at MAC gNB \n"); nr_process_mac_pdu(module_idP, CC_id, frameP, pduP, pdu_len); } - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); - - /* - #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); - #endif - */ } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 5305dd6f50..84260acbd1 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -78,7 +78,7 @@ void mac_rlc_data_ind ( } if (rb != NULL) { - LOG_W(RLC, "RB found! (channel ID %d) \n", channel_idP); + LOG_D(RLC, "RB found! (channel ID %d) \n", channel_idP); rb->set_time(rb, nr_rlc_current_time); rb->recv_pdu(rb, buffer_pP, tb_sizeP); } else { diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 6a6dc74695..cc52648ff0 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -192,7 +192,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } else { - LOG_I(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok), received length: %d \n",UL_info->frame,UL_info->slot, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length); + LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok), received length: %d \n",UL_info->frame,UL_info->slot, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length); nr_rx_sdu(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, From b6a063a77bc63fe70a3231c70902d0b26c2fb5b5 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 7 Feb 2020 10:55:18 +0100 Subject: [PATCH 228/343] fixing a typo --- ci-scripts/runTestOnVM.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 74cffeedd4..be6ebda8a9 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1260,7 +1260,7 @@ function start_rf_sim_nr_ue { 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 --phy-test --rcc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --numerology 1 -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --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 From 7f4b6a2986894a8c6bdfe6304125cdaacf03a2f3 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 6 Feb 2020 14:22:20 +0100 Subject: [PATCH 229/343] updated slot fep for numerology 0 fixed a bug in UE --- executables/nr-ue.c | 4 ++-- openair1/PHY/INIT/nr_parms.c | 12 ++++++++---- openair1/PHY/MODULATION/slot_fep_nr.c | 17 ++++++++++++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 3bb7e9daa7..7ababdcf40 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -748,7 +748,7 @@ void *UE_thread(void *arg) { for (int i=0; iframe_parms.nb_antennas_rx; i++) rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ -- UE->frame_parms.nb_prefix_samples0+UE->frame_parms. + UE->frame_parms.nb_prefix_samples0+UE->frame_parms. get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)]; for (int i=0; iframe_parms.nb_antennas_tx; i++) @@ -893,4 +893,4 @@ int8_t find_dlsch(uint16_t rnti, abort(); } -void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {} \ No newline at end of file +void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {} diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 574c98663d..50a9291e33 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -184,7 +184,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) case 90: case 100: default: - AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp); + AssertFatal(1==0,"Bandwidth of %d MHz undefined for mu %d, frame parms = %p\n", bw, mu, fp); } break; @@ -223,10 +223,14 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) { - if(slot%(fp->slots_per_subframe/2)) - return fp->samples_per_slotN0; + uint32_t samp_count; + + if(fp->numerology_index == 0) + samp_count = fp->samples_per_subframe; else - return fp->samples_per_slot0; + samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0; + + return samp_count; } uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead) diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 4c4439d52d..1334c5c99e 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -46,6 +46,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, unsigned char aa; unsigned int nb_prefix_samples; unsigned int nb_prefix_samples0; + unsigned int abs_symbol; if (ue->is_synchronized) { nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); @@ -125,7 +126,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, for (aa=0; aanb_antennas_rx; aa++) { memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); - rx_offset = sample_offset + slot_offset + nb_prefix_samples0 - SOFFSET; + rx_offset = sample_offset + slot_offset - SOFFSET; // Align with 256 bit // rx_offset = rx_offset&0xfffffff8; @@ -135,8 +136,16 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); #endif - if (symbol==0) { + abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; + + for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++) + rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rx_offset += frame_parms->ofdm_symbol_size * symbol; + + if (abs_symbol%(0x7<numerology_index)) { + + rx_offset += nb_prefix_samples0; if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short*) &common_vars->rxdata[aa][frame_length_samples], (short*) &common_vars->rxdata[aa][0], @@ -161,9 +170,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } } else { - rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol; - // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); - + rx_offset += frame_parms->nb_prefix_samples; if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((void *) &common_vars->rxdata[aa][frame_length_samples], (void *) &common_vars->rxdata[aa][0], From 5f3b99778979e40b53203ad5a53e15502273f05b Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 7 Feb 2020 14:42:26 +0100 Subject: [PATCH 230/343] added assertion for absolutefrequencySSB --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 424da6b331..c911fbd56a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -207,6 +207,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) scs_scaling = scs_scaling>>2; uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); + uint16_t sco = absolute_diff%(12*scs_scaling); + AssertFatal(sco==0,"absoluteFrequencySSB has a subcarrier offset of %d while it should be alligned with CRBs\n",sco); cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scs_scaling) - 10; //absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total cfg->ssb_table.ssb_offset_point_a.tl.tag = NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG; cfg->num_tlv++; From 7134468cde2b0adb2f2c7903b72f0530d6c1b861 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 7 Feb 2020 15:46:32 +0100 Subject: [PATCH 231/343] adapting FR2 absolutefrequencySSB to new code --- .../GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 3eadc9af68..1f8317cf0e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -33,7 +33,7 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP) - absoluteFrequencySSB = 2077643; + absoluteFrequencySSB = 2077907; dl_frequencyBand = 257; # this is 27.900 GHz dl_absoluteFrequencyPointA = 2077499; @@ -152,7 +152,7 @@ gNBs = # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 - ssb_periodicityServingCell = 1; + ssb_periodicityServingCell = 2; # dmrs_TypeA_position # 0 = pos2, 1 = pos3 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index 1de784a73a..1fbc8e30ef 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -33,7 +33,7 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP) - absoluteFrequencySSB = 2078051; + absoluteFrequencySSB = 2078315; dl_frequencyBand = 257; # this is 27.900 GHz dl_absoluteFrequencyPointA = 2077499; From 12b38431dc08c24dab50e9f447bccb24af957061 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 7 Feb 2020 16:57:35 +0100 Subject: [PATCH 232/343] PUSCH start symbol should be 0 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 8f29aa56a3..55a7385143 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -774,7 +774,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, //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->start_symbol_index = 0; pusch_pdu->nr_of_symbols = 12; //Optional Data only included if indicated in pduBitmap pusch_pdu->pusch_data.rv_index = 0; From be09a9b0ba72c75bba7d6d4f291c6a6021303c49 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 7 Feb 2020 17:39:27 +0100 Subject: [PATCH 233/343] applying laurent's patch for rfsim. Missed in the RRC_FR2 branch 2 issues at this point: 1.rfsim for FR1 works sometimes. other times 100 consec PBCH errors.(this commit) 2.PDCCH and PDSCH are not transmitted in correct slots. problem might be with sf_ahead. --- executables/nr-ue.c | 73 +++++++++++++--------------- targets/ARCH/rfsimulator/simulator.c | 2 +- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 7ababdcf40..8a868b37ba 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -538,57 +538,54 @@ void UE_processing(void *arg) { } -void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { - void *rxp[NB_ANTENNAS_RX]; +void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) { void *dummy_tx[UE->frame_parms.nb_antennas_tx]; for (int i=0; iframe_parms.nb_antennas_tx; i++) - dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); + dummy_tx[i]=malloc16_clear(writeBlockSize*4); - for(int x=0; x<20; x++) { // two frames for initial sync - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; - - AssertFatal( UE->frame_parms.samples_per_subframe == - UE->rfdevice.trx_read_func(&UE->rfdevice, - timestamp, - rxp, - UE->frame_parms.samples_per_subframe, - UE->frame_parms.nb_antennas_rx), ""); - } + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp, + dummy_tx, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 4),""); for (int i=0; iframe_parms.nb_antennas_tx; i++) free(dummy_tx[i]); } -void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { - void *dummy_tx[UE->frame_parms.nb_antennas_tx]; +void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) { - for (int i=0; iframe_parms.nb_antennas_tx; i++) - dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); + void *rxp[NB_ANTENNAS_RX]; - void *dummy_rx[UE->frame_parms.nb_antennas_rx]; + for(int x=0; x<20; x++) { // two frames for initial sync + for (int slot=0; slotframe_parms.slots_per_subframe; slot ++ ) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) { + if (toTrash) + rxp[i]=malloc16(UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms)*4); + else + rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + + 4*((x*UE->frame_parms.samples_per_subframe)+ + UE->frame_parms.get_samples_slot_timestamp(slot,&UE->frame_parms,0)); + } + + AssertFatal( UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms) == + UE->rfdevice.trx_read_func(&UE->rfdevice, + timestamp, + rxp, + UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms), + UE->frame_parms.nb_antennas_rx), ""); - for (int i=0; iframe_parms.nb_antennas_rx; i++) - dummy_rx[i]=malloc16(UE->frame_parms.samples_per_subframe*4); - - for (int sf=0; sfrfdevice.trx_read_func(&UE->rfdevice, - timestamp, - dummy_rx, - UE->frame_parms.samples_per_subframe, - UE->frame_parms.nb_antennas_rx); - if (IS_SOFTMODEM_RFSIM ) { - usleep(1000); // slow down, as would do actual rf to let cpu for the synchro thread + if (IS_SOFTMODEM_RFSIM) + dummyWrite(UE,*timestamp, UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms)); + if (toTrash) + for (int i=0; iframe_parms.nb_antennas_rx; i++) + free(rxp[i]); } } - for (int i=0; iframe_parms.nb_antennas_tx; i++) - free(dummy_tx[i]); - - for (int i=0; iframe_parms.nb_antennas_rx; i++) - free(dummy_rx[i]); } void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { @@ -673,7 +670,7 @@ void *UE_thread(void *arg) { decoded_frame_rx=(tmp->proc.decoded_frame_rx+trashed_frames) % MAX_FRAME_NUMBER; delNotifiedFIFO_elt(res); } else { - trashFrame(UE, ×tamp); + readFrame(UE, ×tamp, true); trashed_frames++; continue; } @@ -682,7 +679,7 @@ void *UE_thread(void *arg) { AssertFatal( !syncRunning, "At this point synchronization can't be running\n"); if (!UE->is_synchronized) { - readFrame(UE, ×tamp); + readFrame(UE, ×tamp, false); notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch); syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg); syncMsg->UE=UE; diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 906314a67c..54dfd3b888 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -478,9 +478,9 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi } if ( b->headerMode==false ) { - LOG_D(HW,"UEsock: %d Set b->lastReceivedTS %ld\n", fd, b->lastReceivedTS); if ( ! b->trashingPacket ) { b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt); + LOG_D(HW,"UEsock: %d Set b->lastReceivedTS %ld\n", fd, b->lastReceivedTS); } if ( b->remainToTransfer==0) { From 626daecfa5acc6180fbc30e149e92aeda7a03967 Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 7 Feb 2020 19:51:19 +0100 Subject: [PATCH 234/343] nr-ip-UL-nos1: Fix packet corruption issue appearing with larger packet sizes based on iperf testing for the uplink --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 60 ++++++++++++-------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 80bfec6cf9..5801fabcfb 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -135,6 +135,7 @@ typedef struct { #define NR_MAX_NUM_LCID 32 #define NR_MAX_NUM_LCGID 8 +#define MAX_RLC_SDU_SUBHEADER_SIZE 3 #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9ddb47601d..ea9ead80c3 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -140,7 +140,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode); -unsigned char +uint16_t nr_generate_ulsch_pdu(uint8_t *mac_pdu, uint8_t *sdus_payload, uint8_t num_sdus, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index df27f5b8db..02749a70dd 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2319,7 +2319,7 @@ unsigned char *nr_parse_header(unsigned char *mac_header, return (mac_header_ptr); } -unsigned char +uint16_t nr_generate_ulsch_pdu(uint8_t *mac_pdu, uint8_t *sdus_payload, uint8_t num_sdus, @@ -2331,7 +2331,7 @@ nr_generate_ulsch_pdu(uint8_t *mac_pdu, NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; unsigned char * ulsch_buffer_ptr = sdus_payload; uint8_t last_size=0; - uint16_t sdu_length_total; + uint16_t sdu_length_total=0; int i; int offset=0; @@ -2359,11 +2359,15 @@ nr_generate_ulsch_pdu(uint8_t *mac_pdu, // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in memcpy((void *) mac_pdu_ptr, (void *) ulsch_buffer_ptr, sdu_lengths[i]); ulsch_buffer_ptr+= sdu_lengths[i]; + sdu_length_total+= sdu_lengths[i]; mac_pdu_ptr += sdu_lengths[i]; } + offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); + // 4) Compute final offset for padding - uint16_t padding_bytes = buflen - sdu_length_total; + uint16_t padding_bytes = buflen - offset; + LOG_D(MAC, "Number of padding bytes: %d \n", padding_bytes); if (padding_bytes > 0) { ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING; @@ -2373,9 +2377,6 @@ nr_generate_ulsch_pdu(uint8_t *mac_pdu, // no MAC subPDU with padding } - offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); - - return offset; } @@ -2482,11 +2483,11 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; - uint16_t buflen_remain = 0; + int16_t buflen_remain = 0; uint8_t lcid = 0; uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t payload_offset = 0, num_sdus = 0; + uint16_t payload_offset = 0, num_sdus = 0; uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; uint16_t sdu_length_total = 0; unsigned short post_padding = 0, padding_len = 0; @@ -2521,13 +2522,15 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, if(lcid_buffer_occupancy_new){ buflen_remain = - buflen - (total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE); + buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); LOG_D(MAC, - "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " - "send (Transport Block size %d SDU Length Total %d , mac header len %d )\n", //BSR byte before Tx=%d + "[UE %d] Frame %d : Before while loop UL-DXCH -> ULSCH, RLC %d has %d bytes to " + "send (Transport Block size %d SDU Length Total %d , mac header len %d, buflen_remain %d )\n", //BSR byte before Tx=%d module_idP, frameP, lcid, lcid_buffer_occupancy_new, buflen, sdu_length_total, - total_rlc_pdu_header_len); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]] + total_rlc_pdu_header_len, buflen_remain); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]] + + while(buflen_remain > 0 && lcid_buffer_occupancy_new){ //TODO: Replace static value with CRNTI sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, @@ -2547,27 +2550,38 @@ nr_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); + + + //Update total MAC Header size for RLC PDUs + /*if(sdu_lengths[num_sdus]<128) + total_rlc_pdu_header_len += 2; + else + total_rlc_pdu_header_len += 3;*/ + + total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last; //Update number of SDU num_sdus++; - //Update total MAC Header size for RLC PDUs and save last one - total_rlc_pdu_header_len += rlc_pdu_header_len_last; } /* Get updated BO after multiplexing this PDU */ //TODO: Replace static value with CRNTI - /*lcid_buffer_occupancy_new = + lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP, 0x1234, //nr_ue_mac_inst->crnti eNB_index, frameP, subframe, ENB_FLAG_NO, lcid); - is_lcid_processed = (is_lcid_processed) - || (lcid_buffer_occupancy_new <= 0);*/ + buflen_remain = + buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + LOG_D(MAC, + "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " + "send (Transport Block size %d SDU Length Total %d , mac header len %d, buflen_remain %d )\n", //BSR byte before Tx=%d + module_idP, frameP, lcid, lcid_buffer_occupancy_new, + buflen, sdu_length_total, + total_rlc_pdu_header_len, buflen_remain); + } } } @@ -2592,13 +2606,13 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Padding: fill remainder of ULSCH with 0 if (buflen - payload_offset > 0){ - for (int j = 0; j < (buflen - payload_offset); j++) - ulsch_buffer[payload_offset + j] = 0; + for (int j = payload_offset; j < buflen; j++) + ulsch_buffer[j] = 0; } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_I(MAC, "Printing UL MAC payload without the header UE side, payload_offset: %d \n", payload_offset); - for (int i = 0; i < sdu_length_total ; i++) { + for (int i = 0; i < buflen ; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); printf("%02x ",(unsigned char)ulsch_buffer[i]); From 2520a922112749ae43713895b8f63a0c07b45172 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 10 Feb 2020 08:59:16 +0100 Subject: [PATCH 235/343] modify telnet serveur build to support all exec's --- common/utils/telnetsrv/telnetsrv.c | 3 + .../utils/telnetsrv/telnetsrv_CMakeLists.txt | 26 +++- .../utils/telnetsrv/telnetsrv_measurements.c | 136 ++--------------- .../utils/telnetsrv/telnetsrv_measurements.h | 23 ++- common/utils/telnetsrv/telnetsrv_phycmd.c | 142 ------------------ 5 files changed, 55 insertions(+), 275 deletions(-) delete mode 100644 common/utils/telnetsrv/telnetsrv_phycmd.c diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 44ab07a49b..6626c8103b 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -709,6 +709,9 @@ int add_sharedmodules(void) { return ret; } +/* autoinit functions is called by the loader when the telnet shared library is + dynamically loaded +*/ int telnetsrv_autoinit(void) { memset(&telnetparams,0,sizeof(telnetparams)); config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),"telnetsrv"); diff --git a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt index 05c99aabb8..519a1a72ff 100644 --- a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt +++ b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt @@ -2,20 +2,32 @@ set(TELNETROOT ${OPENAIR_DIR}/common/utils/telnetsrv ) set(TELNETSRV_SOURCE ${TELNETROOT}/telnetsrv.c - ${TELNETROOT}/telnetsrv_phycmd.c ${TELNETROOT}/telnetsrv_proccmd.c ${TELNETROOT}/telnetsrv_loader.c ${TELNETROOT}/telnetsrv_measurements.c ) - -#set(TELNETSRV_ETHDEVCMD_SOURCE -# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c -# ) - + add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) -#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} ) target_link_libraries(telnetsrv PRIVATE history) +foreach(TELNETLIB enb gnb 4gUE 5gUE) + set(TELNETLIB_SRCS "") + foreach(TELNETLIB_ASRC measurements phycmd) + set(TELNETLIB_SRC ${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_${TELNETLIB}_${TELNETLIB_ASRC}.c) + if (EXISTS ${TELNETLIB_SRC}) + set( TELNETLIB_SRCS "${TELNETLIB_SRC};${TELNETLIB_SRCS}") + endif() + endforeach() + if(NOT "${TELNETLIB_SRCS}" STREQUAL "") + message("Add ${TELNETLIB} specific telnet functions in libtelnetsrv_${TELNETLIB}.so") + add_library(telnetsrv_${TELNETLIB} MODULE ${TELNETLIB_SRCS} ) + add_dependencies(telnetsrv telnetsrv_${TELNETLIB}) + install(TARGETS telnetsrv_${TELNETLIB} DESTINATION bin) + else() + message("No specific telnet functions for ${TELNETLIB}") + endif() +endforeach() + install(TARGETS telnetsrv DESTINATION bin) if (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build") diff --git a/common/utils/telnetsrv/telnetsrv_measurements.c b/common/utils/telnetsrv/telnetsrv_measurements.c index 7cfc656225..4a11e7c2dd 100644 --- a/common/utils/telnetsrv/telnetsrv_measurements.c +++ b/common/utils/telnetsrv/telnetsrv_measurements.c @@ -20,9 +20,9 @@ */ /*! \file common/utils/telnetsrv/telnetsrv_measurements.c - * \brief: implementation of telnet commands related to measurments + * \brief: implementation of telnet measurement functions common to all softmodems * \author Francois TABURET - * \date 2019 + * \date 2020 * \version 0.1 * \company NOKIA BellLabs France * \email: francois.taburet@nokia-bell-labs.com @@ -47,40 +47,18 @@ #include "common/utils/LOG/log.h" #include "common/config/config_userapi.h" #include "telnetsrv_measurements.h" -#include "telnetsrv_ltemeasur_def.h" -#include "telnetsrv_cpumeasur_def.h" -#include "openair2/LAYER2/MAC/mac.h" -#include "openair1/PHY/phy_extern.h" - -void measurcmd_display_macstats(telnet_printfunc_t prnt); -void measurcmd_display_macstats_ue(telnet_printfunc_t prnt); -void measurcmd_display_rlcstats(telnet_printfunc_t prnt); -void measurcmd_display_phycpu(telnet_printfunc_t prnt); -void measurcmd_display_maccpu(telnet_printfunc_t prnt); -void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt); -static telnet_measurgroupdef_t measurgroups[] = { - {"enb", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}}, - {"enbues",GROUP_LTESTATS,0, measurcmd_display_macstats_ue,{NULL}}, - {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}}, - {"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}}, - {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}}, - {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}}, -}; -#define TELNET_NUM_MEASURGROUPS (sizeof(measurgroups)/sizeof(telnet_measurgroupdef_t)) - -static int eNB_id =0; static char *grouptypes[] = {"ltestats","cpustats"}; static double cpufreq; #define TELNET_NUM_MEASURTYPES (sizeof(grouptypes)/sizeof(char *)) #define HDR "---------------------------------" -void measurcmd_display_groups(telnet_printfunc_t prnt) { +void measurcmd_display_groups(telnet_printfunc_t prnt,telnet_measurgroupdef_t *measurgroups,int groups_size) { prnt(" %*s %10s %s\n",TELNET_MAXMEASURNAME_LEN-1,"name","type","nombre de mesures"); - for(int i=0; iUE_list); - for (int UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - for (int i=0; inumactiveCCs[UE_id]; i++) { - int CC_id = UE_list->ordered_CCids[i][UE_id]; - prnt("%s UE %i Id %i CCid %i %s\n",HDR,i,UE_id,CC_id,HDR); - eNB_UE_STATS *macuestatptr = &(UE_list->eNB_UE_stats[CC_id][UE_id]); - telnet_ltemeasurdef_t statsptr[]=LTEMAC_UEMEASURE; - measurcmd_display_measures(prnt, statsptr, sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); - } - } -} /* measurcmd_display_macstats_ue */ - -void measurcmd_display_macstats(telnet_printfunc_t prnt) { - for (int CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) { - eNB_STATS *macstatptr=&(RC.mac[eNB_id]->eNB_stats[CC_id]); - telnet_ltemeasurdef_t statsptr[]=LTEMAC_MEASURE; - prnt("%s eNB %i mac stats CC %i frame %u %s\n", - HDR, eNB_id, CC_id, RC.mac[eNB_id]->frame,HDR); - measurcmd_display_measures(prnt,statsptr,sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); - } -} /* measurcmd_display_macstats */ - - -void measurcmd_display_one_rlcstat(telnet_printfunc_t prnt, int UE_id, telnet_ltemeasurdef_t *statsptr, int num_rlcmeasure, unsigned int *rlcstats, - char *rbid_str, protocol_ctxt_t *ctxt, const srb_flag_t srb_flagP, const rb_id_t rb_idP) - -{ - int rlc_status = rlc_stat_req(ctxt,srb_flagP,rb_idP, - rlcstats, rlcstats+1, rlcstats+2, rlcstats+3, rlcstats+4, rlcstats+5, - rlcstats+6, rlcstats+7, rlcstats+8, rlcstats+9, rlcstats+10, rlcstats+11, - rlcstats+12, rlcstats+13, rlcstats+14, rlcstats+15, rlcstats+16, rlcstats+17, - rlcstats+18, rlcstats+19, rlcstats+20, rlcstats+21, rlcstats+22, rlcstats+23, - rlcstats+24, rlcstats+25, rlcstats+26, rlcstats+27); - - if (rlc_status == RLC_OP_STATUS_OK) { - prnt("%s UE %i RLC %s mode %s %s\n",HDR,UE_id, rbid_str, - (rlcstats[0]==RLC_MODE_AM)? "AM": (rlcstats[0]==RLC_MODE_UM)?"UM":"NONE",HDR); - measurcmd_display_measures(prnt, statsptr, num_rlcmeasure); - } -} /* status measurcmd_rlc_stat_req */ - - -void measurcmd_display_rlcstats(telnet_printfunc_t prnt) { - protocol_ctxt_t ctxt; - UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list); - telnet_ltemeasurdef_t statsptr[]=LTE_RLCMEASURE; - int num_rlcmeasure = sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t ); - unsigned int *rlcstats = malloc(num_rlcmeasure*sizeof(unsigned int)); - eNB_MAC_INST *eNB = RC.mac[eNB_id]; - - for(int i=0; i head; UE_id>=0; UE_id=UE_list->next[UE_id]) { -#define NB_eNB_INST 1 - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_list->eNB_UE_stats[0][UE_id].crnti, - eNB->frame,eNB->subframe,eNB_id); - measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH); - measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DTCH", &ctxt, SRB_FLAG_NO, DTCH-2); - } -} /* measurcmd_display_macstats_ue */ /*------------------------------------------------------------------------------------------------------------------------*/ /* function called by the telnet server when measur command is entered */ @@ -238,20 +130,24 @@ int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt) { if (debug > 0) prnt(" measurcmd_show received %s\n",buf); - - // char tmp[20480]; - // dump_eNB_l2_stats(tmp, 0); - // prnt("%s\n",tmp); + int (*fptr)(telnet_measurgroupdef_t **) = dlsym(RTLD_DEFAULT,"get_measurgroups"); + if ( fptr == NULL) { + prnt("No measures available for this softmodem\n"); + return 0; + } + telnet_measurgroupdef_t *measurgroups; + int num_measurgroups = fptr( &measurgroups); + int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2); if (s>0) { if ( strcmp(subcmd,"groups") == 0) { - measurcmd_display_groups(prnt); + measurcmd_display_groups(prnt,measurgroups,num_measurgroups); badcmd=0; } else { for (int i=0; i #include "telnetsrv.h" #include "openair1/PHY/defs_eNB.h" -#ifdef TELNETSRV_MEASURMENTS_MAIN + #define TELNET_MAXMEASURNAME_LEN 30 #define TELNET_MAXMEASURGROUPS 10 -telnetshell_vardef_t measur_vardef[] = { - {"",0,NULL} -}; - +#define PRINT_CPUMEAS_STATE ((cpumeas(CPUMEAS_GETSTATE))?"enabled":"disabled") typedef struct cpumeasurdef { char statname[TELNET_MAXMEASURNAME_LEN]; time_stats_t *astatptr; @@ -75,6 +72,7 @@ typedef struct mesurgroupdef { #define LTEMAC_MEASURGROUP_NAME "ltemac" #define PHYCPU_MEASURGROUP_NAME "phycpu" +#ifdef TELNETSRV_MEASURMENTS_MAIN int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt); int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt); telnetshell_cmddef_t measur_cmdarray[] = { @@ -83,6 +81,19 @@ telnetshell_cmddef_t measur_cmdarray[] = { {"","",NULL} }; +telnetshell_vardef_t measur_vardef[] = { + {"",0,NULL} +}; +/* function to be implemented in any telnetsrv_xxx_measurements.c sources + to allow common measurment code to access measurments data */ +extern int get_measurgroups(telnet_measurgroupdef_t **measurgroups); +/* */ + #else -extern void add_measur_cmds(void); +extern void add_measur_cmds(void); +extern void measurcmd_display_groups(telnet_printfunc_t prnt,telnet_measurgroupdef_t *measurgroups,int groups_size); +extern void measurcmd_display_cpumeasures(telnet_printfunc_t prnt, telnet_cpumeasurdef_t *cpumeasure, int cpumeasure_size) ; +extern uint64_t measurcmd_getstatvalue(telnet_ltemeasurdef_t *measur,telnet_printfunc_t prnt); +extern void measurcmd_display_measures(telnet_printfunc_t prnt, telnet_ltemeasurdef_t *statsptr, int stats_size); + #endif /* TELNETSRV_MEASURCMD_MAIN */ diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c deleted file mode 100644 index c60126f1c7..0000000000 --- a/common/utils/telnetsrv/telnetsrv_phycmd.c +++ /dev/null @@ -1,142 +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 common/utils/telnetsrv/telnetsrv_phycmd.c - * \brief: implementation of telnet commands related to softmodem linux process - * \author Francois TABURET - * \date 2017 - * \version 0.1 - * \company NOKIA BellLabs France - * \email: francois.taburet@nokia-bell-labs.com - * \note - * \warning - */ -#define _GNU_SOURCE -#include -#include - - -#define TELNETSERVERCODE -#include "telnetsrv.h" -#define TELNETSRV_PHYCMD_MAIN -#include "telnetsrv_phycmd.h" -char *prnbuff; -extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length); - -void init_phytelnet(void) -{ -prnbuff=malloc(get_phybsize() ); -if (prnbuff == NULL) - { - fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno)); - } -} - -void display_uestatshead( telnet_printfunc_t prnt) -{ -prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n"); -} - -void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag) -{ - -int p; - - p=dump_eNB_l2_stats( prnbuff, 0); - if(prntflag>=1) - prnt("%s\n",prnbuff); - if(debug>=1) - prnt("%i bytes printed\n",p); - - -} - -void display_uestats(int debug, telnet_printfunc_t prnt, int ue) -{ - for (int cc=0; cc<1 ; cc++) - { - - - } -} - -void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt) -{ - prnt(" DLSCH kb DLSCH kb/s\n"); - - dump_uestats(debug, prnt,0); - -} - -int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) -{ - - - - if (debug > 0) - prnt("phy interface module received %s\n",buf); - if (strcasestr(buf,"phycnt") != NULL) - { - display_phycounters(buf, debug, prnt); - } - if (strcasestr(buf,"uestat") != NULL) - { - char *cptr=strcasestr(buf+sizeof("uestat"),"UE"); - display_uestatshead(prnt); - if (cptr != NULL) - { - int ueidx = strtol( cptr+sizeof("UE"), NULL, 10); - if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0) - { - display_uestats(debug, prnt,ueidx); - } - } /* if cptr != NULL */ - else - { - for (int ue=0; ue]", dump_phyvars}, - - {"","",NULL}, -}; - - -/*-------------------------------------------------------------------------------------*/ -void add_phy_cmds(void) -{ - - init_phytelnet(); - add_telnetcmd("phy", phy_vardef, phy_cmdarray); -} From 87d4443c0bbd22d9fdc9c8bbf6c918e93d1f0081 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Sun, 9 Feb 2020 21:32:14 +0100 Subject: [PATCH 236/343] adding support for beamforming (control of GPIO) for FR2 --- executables/nr-ru.c | 14 +++- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 65 +++++++++++++------ .../CONF/gnb.band257.tm1.32PRB.usrpx300.conf | 10 +-- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index a90bf9308a..42d7a2a48a 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -750,7 +750,19 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { nextslot_type == NR_UPLINK_SLOT) { flags = 3; // end of burst } - + + if (fp->freq_range==nr_FR2) { + // the beam index is written in bits 8-10 of the flags + // bit 11 enables the gpio programming + int beam=0; + if (slot==0 || slot==40) beam=0&8; + if (slot==10 || slot==50) beam=1&8; + if (slot==20 || slot==60) beam=2&8; + if (slot==30 || slot==70) beam=3&8; + + flags |= beam<<8; + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index eb8c6ec010..0b60a73c43 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -276,14 +276,17 @@ static int trx_usrp_start(openair0_device *device) { // 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); + s->usrp->set_gpio_attr("FP0", "DDR", 0xfff, 0xfff); + //set lower 7 bits to be controlled automatically by ATR (the rest 5 bits are controlled manually) + s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0xfff); //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); + // set the output pins to 0 + s->usrp->set_gpio_attr("FP0", "OUT", 7<<7, 0xf80); + // 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)); @@ -404,10 +407,19 @@ static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp ti @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(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { +static int trx_usrp_write(openair0_device *device, + openair0_timestamp timestamp, + void **buff, + int nsamps, + int cc, + int flags) { int ret=0; usrp_state_t *s = (usrp_state_t *)device->priv; int nsamps2; // aligned to upper 32 or 16 byte boundary + + int flags_lsb = flags&0xff; + int flags_msb = (flags>>8)&0xff; + #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -441,40 +453,51 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, boolean_t first_packet_state=false,last_packet_state=false; - if (flags == 2) { // start of burst + if (flags_lsb == 2) { // start of burst // s->tx_md.start_of_burst = true; // s->tx_md.end_of_burst = false; first_packet_state = true; last_packet_state = false; - } else if (flags == 3) { // end of burst + } else if (flags_lsb == 3) { // end of burst //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 == 4) { // start and end - // s->tx_md.start_of_burst = true; - // s->tx_md.end_of_burst = true; + } else if (flags_lsb == 4) { // start and end + // 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; + } else if (flags_lsb==1) { // middle of burst + // 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_lsb==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.end_of_burst = last_packet_state; s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); s->tx_count++; + // bit 3 enables gpio (for backward compatibility) + if (flags_msb&8) { + // push GPIO bits 7-9 from flags_msb + int gpio789=(flags_msb&7)<<7; + s->usrp->set_command_time(s->tx_md.time_spec); + s->usrp->set_gpio_attr("FP0", "OUT", gpio789, 0x380); + s->usrp->clear_command_time(); + } + if (cc>1) { std::vector buff_ptrs; @@ -482,7 +505,11 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0])); 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); + } + 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); return ret; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 1f8317cf0e..1363be3bce 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -148,7 +148,7 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 3; - ssb_PositionsInBurst_Bitmap = 1; + ssb_PositionsInBurst_Bitmap = 0x100000001L; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 @@ -170,8 +170,8 @@ gNBs = # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 6; - nrofDownlinkSlots = 30; + dl_UL_TransmissionPeriodicity = 5; + nrofDownlinkSlots = 10; nrofDownlinkSymbols = 0; nrofUplinkSlots = 10; nrofUplinkSymbols = 0; @@ -237,8 +237,8 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "type=x300"; - if_freq = 3000000000; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + if_freq = 5300000000; } ); From 69721198af3eb4ad1d93a49aacdbefac9fbf16ad Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 10 Feb 2020 12:54:00 +0100 Subject: [PATCH 237/343] nr MAC uplink: aDD identification of MAC uplink PDU CEs at gNB (receiver) side --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 94 ++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index cabaee7b5c..4a8602d272 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -606,10 +606,87 @@ void nr_process_mac_pdu( LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); #endif*/ + case UL_SCH_LCID_S_BSR: + //38.321 section 6.1.3.1 + //fixed length + mac_ce_len =1; + /* Extract short BSR value */ + break; + + case UL_SCH_LCID_S_TRUNCATED_BSR: + //38.321 section 6.1.3.1 + //fixed length + mac_ce_len =1; + /* Extract short truncated BSR value */ + break; + + case UL_SCH_LCID_L_BSR: + //38.321 section 6.1.3.1 + //variable length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract long BSR value */ + break; + + case UL_SCH_LCID_L_TRUNCATED_BSR: + //38.321 section 6.1.3.1 + //variable length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract long truncated BSR value */ + break; + + + case UL_SCH_LCID_C_RNTI: + //38.321 section 6.1.3.2 + //fixed length + mac_ce_len = 2; + /* Extract CRNTI value */ + break; + + case UL_SCH_LCID_SINGLE_ENTRY_PHR: + //38.321 section 6.1.3.8 + //fixed length + mac_ce_len = 2; + /* Extract SINGLE ENTRY PHR elements for PHR calculation */ + break; + + case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: + //38.321 section 6.1.3.9 + // varialbe length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */ + break; + + case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT: + //38.321 section 6.1.3.9 + // varialbe length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */ + break; + case UL_SCH_LCID_PADDING: - done = 1; - // end of MAC PDU, can ignore the rest. - break; + done = 1; + // end of MAC PDU, can ignore the rest. + break; case UL_SCH_LCID_DTCH: // check if LCID is valid at current time. @@ -682,6 +759,17 @@ void nr_rx_sdu(module_id_t module_idP, uint8_t * pduP = pdu; + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n"); + for (int i = 0; i < pdu_len ; i++) { + //harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + printf("%02x ",(unsigned char)pduP[i]); + } + printf("\n"); +#endif + // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs if (pduP != NULL){ From f1a862051564f745612a6b64434fb8b01c32177f Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 10 Feb 2020 13:29:32 +0100 Subject: [PATCH 238/343] CI: fixes in python framework -- fromdos was to be called from python executor and not from ADB server -- doing a power-cycle on CAT-M module at start of test Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d3027630b9..e122339269 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -248,6 +248,7 @@ class SSHConnection(): elif self.sshresponse == 1: logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m') logging.debug('Expected Line : ' + expectedline) + logging.debug(str(self.ssh.before)) sys.exit(self.sshresponse) elif self.sshresponse == 2: logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m') @@ -1213,6 +1214,11 @@ class SSHConnection(): # Calling twice AT to clear all buffers self.command('AT', 'OK|ERROR', 5) self.command('AT', 'OK', 5) + # Doing a power cycle + self.command('AT^RESET', 'SIMSTORE,READY', 15) + self.command('AT', 'OK|ERROR', 5) + self.command('AT', 'OK', 5) + self.command('ATE1', 'OK', 5) # Disabling the Radio self.command('AT+CFUN=0', 'OK', 5) logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') @@ -2763,7 +2769,9 @@ class SSHConnection(): self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') else: self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.command('fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + # fromdos has to be called on the python executor not on ADB server + cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log' + subprocess.run(cmd, shell=True) self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) # in case of OAI UE: From e1647ac620db5d65de3be65f2cd2465aa367dd27 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 10 Feb 2020 15:34:11 +0100 Subject: [PATCH 239/343] fixed the issue with wrong PDSCH slots --- executables/nr-gnb.c | 2 ++ executables/nr-ru.c | 1 + openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 13 +++++++------ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index f5c53dbc22..9c9a02c934 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -104,6 +104,7 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int transmission_mode; uint16_t sf_ahead=3; +uint16_t sl_ahead; //pthread_t main_gNB_thread; time_stats_t softmodem_stats_mt; // main thread @@ -398,6 +399,7 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_proc_t *ru_proc=&ru->proc; proc->frame_rx = frame_rx; proc->slot_rx = slot_rx; + sl_ahead = sf_ahead*fp->slots_per_subframe; if (!oai_exit) { T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx)); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index dcc662b4b0..a7e2c0f0d5 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -132,6 +132,7 @@ int attach_rru(RU_t *ru); int connect_rau(RU_t *ru); extern uint16_t sf_ahead; +extern uint16_t sl_ahead; extern int emulate_rf; extern int numerology; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 770e27dd60..91c75ac67f 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -51,6 +51,7 @@ extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); extern uint8_t nfapi_mode; extern uint16_t sf_ahead; +extern uint16_t sl_ahead; void handle_nr_rach(NR_UL_IND_t *UL_info) { if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { @@ -261,22 +262,22 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { if (ifi->CC_mask == ((1<frame+((UL_info->slot>(9-sf_ahead))?1:0)) % 1024, - (UL_info->slot+sf_ahead)%10); + (UL_info->frame+((UL_info->slot>(9-sl_ahead))?1:0)) % 1024, + (UL_info->slot+sl_ahead)%10); */ nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id]; int spf = get_spf(cfg); gNB_dlsch_ulsch_scheduler(module_id, UL_info->frame, UL_info->slot, - (UL_info->frame+((UL_info->slot>(spf-1-sf_ahead))?1:0)) % 1024, - (UL_info->slot+sf_ahead)%spf); + (UL_info->frame+((UL_info->slot>(spf-1-sl_ahead))?1:0)) % 1024, + (UL_info->slot+sl_ahead)%spf); ifi->CC_mask = 0; sched_info->module_id = module_id; sched_info->CC_id = CC_id; - sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-sf_ahead)) ? 1 : 0)) % 1024; - sched_info->slot = (UL_info->slot+sf_ahead)%spf; + sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-sl_ahead)) ? 1 : 0)) % 1024; + sched_info->slot = (UL_info->slot+sl_ahead)%spf; sched_info->DL_req = &mac->DL_req[CC_id]; sched_info->UL_dci_req = &mac->UL_dci_req[CC_id]; From 064b7f23aac41dfda5c91a00c0c3f570b7adafa8 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 10 Feb 2020 23:17:27 +0100 Subject: [PATCH 240/343] generation of CCEIndex > 0 in gNodeB and modification of unscrambling procedure for PDCCH in UE RX. --- openair1/PHY/NR_TRANSPORT/nr_dci.c | 9 ++-- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 47 +++++++++++++------ .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- .../NR_MAC_UE/nr_ue_dci_configuration.c | 7 ++- 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index c269618743..d62687bd9c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -166,7 +166,7 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, int k,l,k_prime,dci_idx, dmrs_idx; /*First iteration: single DCI*/ - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15=NULL; // find coreset descriptor @@ -243,8 +243,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); for (int i=0; i>5; i++) - printf("[%d]->0x%08x \t", i,encoder_output[i]); - + printf("[%d]->0x%08x \t", i,encoder_output[i]); + printf("\n"); #endif /// Scrambling @@ -273,9 +273,10 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, /*Reorder REG list for a freq first mapping*/ uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE; + uint8_t reg_idx0 = pdcch_pdu_rel15->CceIndex[d]*NR_NB_REG_PER_CCE; /*Mapping the encoded DCI along with the DMRS */ - for (int reg_idx=0; reg_idx= frame_parms.ofdm_symbol_size) diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 03f1425739..9921862c52 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -150,7 +150,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, for (int i=0; i<9; i++) { z[index_z + i] = llr[index_llr + i]; - LOG_DDD("[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", + LOG_D(PHY,"[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", reg,bundle_j,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]), f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i])); } @@ -678,7 +678,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, int n_rb,rb_offset; get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset); for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) { - LOG_DD("in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); + LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[slot]].rxdataF, pdcch_vars->dl_ch_estimates, @@ -690,8 +690,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, n_rb, rel15->BWPStart); - 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"); + LOG_D(PHY,"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_D(PHY,"in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); // compute channel level based on ofdm symbol 0 nr_pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext, frame_parms, @@ -710,8 +710,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot), T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); #endif - LOG_DD("we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); - LOG_DD("in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); + LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); + LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); // compute LLRs for ofdm symbol 0 only nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext, pdcch_vars->dl_ch_estimates_ext, @@ -722,12 +722,12 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, log2_maxh, n_rb); // log2_maxh+I0_shift if (frame_parms->nb_antennas_rx > 1) { - LOG_DD("we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx); + LOG_D(PHY,"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx); nr_pdcch_detection_mrc(frame_parms, pdcch_vars->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); - LOG_DD("in nr_pdcch_llr(rxdataF_comp -> llr)\n"); + LOG_D(PHY,"we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); + LOG_D(PHY,"in nr_pdcch_llr(rxdataF_comp -> llr)\n"); nr_pdcch_llr(frame_parms, pdcch_vars->rxdataF_comp, pdcch_vars->llr, @@ -745,7 +745,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif } - LOG_DD("we enter nr_pdcch_demapping_deinterleaving()\n"); + LOG_D(PHY,"we enter nr_pdcch_demapping_deinterleaving()\n"); nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr, (uint32_t *) pdcch_vars->e_rx, frame_parms, @@ -754,6 +754,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, rel15->coreset.RegBundleSize, rel15->coreset.InterleaverSize, rel15->coreset.ShiftIndex); + /* nr_pdcch_unscrambling(rel15->rnti, frame_parms, slot, @@ -761,8 +762,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, rel15->coreset.duration*n_rb*9*2, // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, rel15->coreset.pdcch_dmrs_scrambling_id); - LOG_DD("we end nr_pdcch_unscrambling()\n"); - LOG_DD("Ending nr_rx_pdcch() function\n"); + */ + LOG_D(PHY,"we end nr_pdcch_unscrambling()\n"); + LOG_D(PHY,"Ending nr_rx_pdcch() function\n"); } return (0); @@ -798,7 +800,7 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, #ifdef NR_PDCCH_DCI_RUN void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot, - int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id) { + int16_t *z, int16_t *z2,uint32_t length, uint16_t pdcch_DMRS_scrambling_id) { int i; uint8_t reset; uint32_t x1, x2, s = 0; @@ -818,7 +820,8 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 reset = 0; } - if (((s >> (i % 32)) & 1) == 1) z[i] = -z[i]; + if (((s >> (i % 32)) & 1) == 1) z2[i] = -z[i]; + else z2[i]=z[i]; } } @@ -837,15 +840,29 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, rel15 = &pdcch_vars->pdcch_config[i]; int dci_length = rel15->dci_length; + int16_t tmp_e[16*108]; + for (int j=0;jnumber_of_candidates;j++) { + LOG_D(PHY,"Trying DCI candidate %d, CCE %d (%d), L %d\n",j,rel15->CCE[j],rel15->CCE[j]*9*6*2,rel15->L[j]); int CCEind = rel15->CCE[j]; int L = rel15->L[j]; uint64_t dci_estimation[2]= {0}; const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, dci_length, L,1,&ue->polarList); - uint16_t crc = polar_decoder_int16(&pdcch_vars->e_rx[CCEind*9*6*2], + + nr_pdcch_unscrambling(rel15->rnti, + &ue->frame_parms, + slot, + &pdcch_vars->e_rx[CCEind*108], + tmp_e, + L*108, + // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, + rel15->coreset.pdcch_dmrs_scrambling_id); + + uint16_t crc = polar_decoder_int16(tmp_e, dci_estimation, 1, currentPtrDCI); + LOG_D(PHY,"Decoded crc %x\n",crc); if (crc == rel15->rnti) { dci_ind->SFN = frame; dci_ind->slot = slot; 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 e6b43c26ac..b5a5ecc4db 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1539,7 +1539,7 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi); void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot, - int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id); + int16_t *z, int16_t *z2,uint32_t length, uint16_t pdcch_DMRS_scrambling_id); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 473c86bed0..6ffb7d7e50 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -524,7 +524,7 @@ int main(int argc, char **argv) // common configuration rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,1,NULL,1,4660/*secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity*/,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; // stub to configure frame_parms diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 677a27fb3d..396e06ff09 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -49,9 +49,14 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd LOG_D(MAC,"Filling search candidates for DCI\n"); - rel15->number_of_candidates=1; + rel15->number_of_candidates=3; rel15->CCE[0]=0; rel15->L[0]=4; + rel15->CCE[1]=4; + rel15->L[1]=4; + rel15->CCE[2]=8; + rel15->L[2]=4; + } void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot) { From 9a7daded2e631987cacbb59f78e7ef6f3503fc57 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 11 Feb 2020 10:56:15 +0100 Subject: [PATCH 241/343] Updated ofdm fep in gNB --- openair1/SCHED_NR/nr_ru_procedures.c | 77 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index dea66cc791..1337214cf4 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -69,43 +69,74 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { slot_offset = fp->get_samples_slot_timestamp(slot,fp,0); slot_offsetF = first_symbol*fp->ofdm_symbol_size; + int abs_first_symbol = slot*fp->symbols_per_slot; - if (first_symbol>0) slot_offset += (fp->ofdm_symbol_size*first_symbol) + (fp->nb_prefix_samples0) + (fp->nb_prefix_samples*(first_symbol-1)); + for (uint16_t idx_sym=abs_first_symbol; idx_symnumerology_index)) ? fp->nb_prefix_samples0 : fp->nb_prefix_samples; + + slot_offset += fp->ofdm_symbol_size*first_symbol; LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d (first_symbol %d num_symbols %d)\n",ru->proc.frame_tx, ru->proc.tti_tx,slot,first_symbol,num_symbols); - - if (fp->Ncp == 1) { + + if (fp->Ncp == 1) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, num_symbols, fp->nb_prefix_samples, CYCLIC_PREFIX); - } else { - if (first_symbol==0) { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - 1, - fp->nb_prefix_samples0, - CYCLIC_PREFIX); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], - (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], - fp->ofdm_symbol_size, - num_symbols-1, - fp->nb_prefix_samples, - CYCLIC_PREFIX); + if (fp->numerology_index != 0) { + + if (slot%(fp->slots_per_subframe/2)) { + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + num_symbols, + fp->nb_prefix_samples, + CYCLIC_PREFIX); + } + else { + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + 1, + fp->nb_prefix_samples0, + CYCLIC_PREFIX); + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], + (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], + fp->ofdm_symbol_size, + num_symbols-1, + fp->nb_prefix_samples, + CYCLIC_PREFIX); + } } + else { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - num_symbols, - fp->nb_prefix_samples, - CYCLIC_PREFIX); + for (uint16_t idx_sym=abs_first_symbol; idx_symcommon.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + 1, + fp->nb_prefix_samples, + CYCLIC_PREFIX); + slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size; + } + else { + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + 1, + fp->nb_prefix_samples0, + CYCLIC_PREFIX); + slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size; + } + } } } + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); } From 3a10c5ca6594d9051ac3c2bfb6f758c44a081d24 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 6 Feb 2020 17:26:21 +0100 Subject: [PATCH 242/343] DOC: adding contributor and separate readme/changelog Signed-off-by: Raphael Defosseux --- CHANGELOG.md | 96 +++ CONTRIBUTING.md | 23 + NOTICE.md | 23 + NOTICE.txt | 21 - README.md | 59 ++ README.txt | 110 ---- .../d2d_emulator_setup.txt | 0 openair1/PHY/TOOLS/twiddle3072.h | 42 -- svn2git/README.txt | 64 -- svn2git/authors.txt | 86 --- svn2git/authors_original.txt | 45 -- svn2git/authors_original_java_output.txt | 86 --- svn2git/check_diff_author.sh | 8 - svn2git/git-author-rewrite.sh | 22 - ubl | 575 ------------------ 15 files changed, 201 insertions(+), 1059 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 NOTICE.md delete mode 100644 NOTICE.txt create mode 100644 README.md delete mode 100644 README.txt rename d2d_emulator_setup.txt => doc/d2d_emulator_setup.txt (100%) delete mode 100644 openair1/PHY/TOOLS/twiddle3072.h delete mode 100644 svn2git/README.txt delete mode 100644 svn2git/authors.txt delete mode 100644 svn2git/authors_original.txt delete mode 100644 svn2git/authors_original_java_output.txt delete mode 100755 svn2git/check_diff_author.sh delete mode 100755 svn2git/git-author-rewrite.sh delete mode 100644 ubl diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..7f095acc16 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,96 @@ +# RELEASE NOTES: # + +## [v1.2.1](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.2.1) -> February 2020. ## + +* Bug fix for mutex lock for wake-up signal + +## [v1.2.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/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) +* Experimental MCE - Multicast Coordination Entity +* 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](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.1.1) -> November 2019. ## + +- Bug fix in the TDD Fair Round-Robin scheduler + +## [v1.1.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/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 +* X2 interface and handover (also X2-U interface) + - In FDD and TDD +* CU/DU split (F1 interface) + - Tested only in FDD +* CDRX + - Tested only in FDD +* Experimental eMBMS support (only on UE side) +* Experimental multi-RRU support + - Tested only in TDD + +This version has an improved code quality: + +* Simplification of the Build System + - A single build includes all full-stack simulators, S1/noS1 modes and one HW platform (such as USRP, BladeRF, ...) +* TUN interface is now used as default for the data plane + - for UE, eNB-noS1 and UE-noS1 +* Code Cleanup +* Better Static Code Analysis: + - Limited number of errors in cppcheck + - Important Decrease on high Impact errors in CoverityScan +* Better Test Coverage in Continuous Integration: + - TM2, CDRX, IF4.5, F1 + - OAI UE is tested in S1 and noS1 modes with USRP board + - Multi-RRU TDD mode + - X2 Handover in FDD mode + +## [v1.0.3](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.3) -> June 2019. ## + +- Bug fix for LimeSuite v19.04.0 API + +## [v1.0.2](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.2) -> February 2019. ## + +- Full OAI support for 3.13.1 UHD + +## [v1.0.1](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.1) -> February 2019. ## + +- Bug fix for the UE L1 simulator. + +## [v1.0.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.0) -> January 2019. ## + +This version first implements the architectural split described in the following picture. + +![Block Diagram](./doc/images/oai_lte_enb_func_split_arch.png) + +* Only FAPI, nFAPI and IF4.5 interfaces are implemented. +* Repository tree structure prepares future integrations of features such as LTE-M, nbIOT or 5G-NR. +* Preliminary X2 support has been implemented. +* S1-flex has been introduced. +* New tools: config library, telnet server, ... +* A lot of bugfixes and a proper automated Continuous Integration process validates contributions. + +Old Releases: + +* v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI. +* v0.6 -> RRH functionality, UE greatly improved, better TDD support, a lot of bugs fixed. + - WARNING: oaisim in PHY abstraction mode does not work, you need to use v0.5.2 for that. +* v0.5.2 -> Last version with old code for oaisim (abstraction mode works) +* v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB +* v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support +* v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0 +* 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 + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..61e44bdd55 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing to OpenAirInterface # + +We want to make contributing to this project as easy and transparent as possible. + +Please refer to the steps described on our website: [How to contribute to OAI](https://www.openairinterface.org/?page_id=112) + +1. Sign and return a Contributor License Agreement to OAI team. +2. Create an account on [Eurecom GitLab Server](https://gitlab.eurecom.fr). +3. Provide the identifiant of this account to the OAI team (mailto:contact@openairinterface.org) so you have developer rights on this repository. +4. The policies are described in these wiki pages: [OAI Policies](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home) + - PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account. It just eats up space on our servers. + - You can fork onto another hosting system. But we will NOT accept a merge request from a forked repository. + * This decision was made for the license reasons. + * The Continuous Integration will reject your merge request. + - All merge requests SHALL have `develop` branch as target branch. + +## Coding Styles ## + +There are described [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/guidelines/guidelines-home) + +## License ## + +By contributing to OpenAirInterface, you agree that your contributions will be licensed under the LICENSE file in the root directory of this source tree. diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000000..65c6105660 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,23 @@ +The source code of openairinterface5g is distributed under **OAI Public License V1.1**. + +For more details of the license, refer to [LICENSE](LICENSE) file in the same directory. + +However, the source code also contains third party software that is acknowledged here for reference. + +## Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/liblfds6.1.1/ ## + +See on [liblfds website](https://liblfds.org/) the license section. + +
+"There is no license. You are free to use this software in any way, for any purpose. Go forth and create wealth!
+If however for legal reasons a licence is required, the license of your choice will be granted."
+
+ +## Credits for source code common/utils/collection/queue.h: ## + +The Regents of the University of California: BSD 3-Clause Licence. + +## Credits for source code common/utils/collection/tree.h: ## + +Niels Provos : BSD 2-Clause Licence. + diff --git a/NOTICE.txt b/NOTICE.txt deleted file mode 100644 index 38d493284a..0000000000 --- a/NOTICE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The source code of openairinterface5g is distributed under OAI Public License V1.0. -For more details of the license, refer to LICENSE file in the same directory. - -However, the source code also contains third party software that is acknowledged here for reference. - -Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/liblfds6.1.1/ -http://liblfds.org/. -Extract from http://liblfds.org/pages/downloads_and_license.html: -"There is no license. You are free to use this software in any way, for any purpose. Go forth and create wealth! -If however for legal reasons a licence is required, the license of your choice will be granted." - - -Credits for source code common/utils/collection/queue.h: -The Regents of the University of California: BSD 3-Clause Licence. - - -Credits for source code common/utils/collection/tree.h: -Niels Provos : BSD 2-Clause Licence. - - - diff --git a/README.md b/README.md new file mode 100644 index 0000000000..0a0f5dee32 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +# OpenAirInterface License # + +OpenAirInterface is under OpenAirInterface Software Alliance license. + + * [OAI License Model](http://www.openairinterface.org/?page_id=101) + * [OAI License v1.1 on our website](http://www.openairinterface.org/?page_id=698) + +It is distributed under **OAI Public License V1.1**. + +The license information is distributed under [LICENSE](LICENSE) file in the same directory. + +Please see [NOTICE](NOTICE.md) file for third party software that is included in the sources. + +# Where to Start # + + * [How to build](./doc/BUILD.md) + * [How to run the modems](./doc/RUNMODEM.md) + +# RAN repository structure # + +The OpenAirInterface (OAI) software is composed of the following parts: + +
+openairinterface5g
+├── ci-scripts: Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI.
+├── cmake_targets: Build utilities to compile (simulation, emulation and real-time platforms), and generated build files
+├── common : Some common OAI utilities, other tools can be found at openair2/UTILS
+├── doc : Contains an up-to-date feature set list
+├── LICENSE
+├── 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 + LTE Rel-14 M2AP implementation.
+    ├── COMMON
+    ├── DOCS
+    ├── ENB_APP
+    ├── LAYER2/RLC/ with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0. 
+    ├── LAYER2/PDCP/PDCP_v10.1.0.
+    ├── NETWORK_DRIVER
+    ├── PHY_INTERFACE
+    ├── 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
+    ├── UTILS
+└── targets: Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
+
+ diff --git a/README.txt b/README.txt deleted file mode 100644 index 579b084601..0000000000 --- a/README.txt +++ /dev/null @@ -1,110 +0,0 @@ -OpenAirInterface is under OpenAirInterface Software Alliance license. -├── http://www.openairinterface.org/?page_id=101 -├── http://www.openairinterface.org/?page_id=698 - -It is distributed under OAI Public License V1.1. -The license information is distributed under LICENSE file in the same directory. -Please see NOTICE.txt for third party software that is included in the sources. - -The OpenAirInterface (OAI) software is composed of the following parts: - -openairinterface5g -├── ci-scripts: Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI. -├── cmake_targets: Build utilities to compile (simulation, emulation and real-time platforms), and generated build files -├── common : Some common OAI utilities, other tools can be found at openair2/UTILS -├── doc : Contains an up-to-date feature set list -├── LICENSE -├── 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 + LTE Rel-14 M2AP implementation. - ├── COMMON - ├── DOCS - ├── ENB_APP - ├── LAYER2/RLC/ with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0. - ├── LAYER2/PDCP/PDCP_v10.1.0. - ├── NETWORK_DRIVER - ├── PHY_INTERFACE - ├── 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 - ├── UTILS -└── targets: Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW. - - -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) - * Experimental MCE - Multicast Coordination Entity - * 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 - - Single LTE-M UE attachment, legacy-LTE UE attachment is disabled - * X2 interface and handover (also X2-U interface) - - In FDD and TDD - * CU/DU split (F1 interface) - - Tested only in FDD - * CDRX - - Tested only in FDD - * Experimental eMBMS support (only on UE side) - * Experimental multi-RRU support - - Tested only in TDD - This version has an improved code quality: - * Simplification of the Build System - - A single build includes all full-stack simulators, S1/noS1 modes and one HW platform (such as USRP, BladeRF, ...) - * TUN interface is now used as default for the data plane - - for UE, eNB-noS1 and UE-noS1 - * Code Cleanup - * Better Static Code Analysis: - - Limited number of errors in cppcheck - - Important Decrease on high Impact errors in CoverityScan - * Better Test Coverage in Continuous Integration: - - TM2, CDRX, IF4.5, F1 - - OAI UE is tested in S1 and noS1 modes with USRP board - - Multi-RRU TDD mode - - X2 Handover in FDD mode - -v1.0.3 -> June 2019: Bug fix for LimeSuite v19.04.0 API -v1.0.2 -> February 2019: Full OAI support for 3.13.1 UHD -v1.0.1 -> February 2019: Bug fix for the UE L1 simulator. -v1.0.0 -> January 2019. This version first implements the architectural split described in doc/oai_lte_enb_func_split_arch.png picture. - Only FAPI, nFAPI and IF4.5 interfaces are implemented. - Repository tree structure prepares future integrations of features such as LTE-M, nbIOT or 5G-NR. - Preliminary X2 support has been implemented. - S1-flex has been introduced. - New tools: config library, telnet server, ... - A lot of bugfixes and a proper automated Continuous Integration process validates contributions. - -v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI. -v0.6 -> RRH functionality, UE greatly improved, better TDD support, - a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not - work, you need to use v0.5.2 for that. -v0.5.2 -> Last version with old code for oaisim (abstraction mode works) -v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB -v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support -v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0 -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 - diff --git a/d2d_emulator_setup.txt b/doc/d2d_emulator_setup.txt similarity index 100% rename from d2d_emulator_setup.txt rename to doc/d2d_emulator_setup.txt diff --git a/openair1/PHY/TOOLS/twiddle3072.h b/openair1/PHY/TOOLS/twiddle3072.h deleted file mode 100644 index 099ef57455..0000000000 --- a/openair1/PHY/TOOLS/twiddle3072.h +++ /dev/null @@ -1,42 +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 - */ - -/* Twiddles generated with -twa = floor(32767*exp(-sqrt(-1)*2*pi*(0:1023)/3072)); -twb = floor(32767*exp(-sqrt(-1)*2*pi*(0:2:2046)/3072)); -twa2 = zeros(1,2048); -twb2 = zeros(1,2048); -twa2(1:2:end) = real(twa); -twa2(2:2:end) = imag(twa); -twb2(1:2:end) = real(twb); -twb2(2:2:end) = imag(twb); -fd=fopen("twiddle_tmp.txt","w"); -fprintf(fd,"static int16_t twa3072[2048] = {"); -fprintf(fd,"%d,",twa2); -fprintf(fd,"};\n"); -fprintf(fd,"static int16_t twb3072[2048] = {"); -fprintf(fd,"%d,",twb2); -fprintf(fd,"};\n"); -fclose(fd); - */ - -static int16_t twa3072[2048] = {32767,0,32766,-68,32766,-135,32766,-202,32765,-269,32765,-336,32764,-403,32763,-470,32762,-537,32761,-604,32760,-671,32758,-738,32757,-805,32755,-872,32753,-939,32751,-1006,32749,-1073,32747,-1140,32744,-1207,32742,-1274,32739,-1340,32736,-1407,32733,-1474,32730,-1541,32727,-1608,32724,-1675,32720,-1742,32717,-1809,32713,-1876,32709,-1943,32705,-2010,32701,-2077,32696,-2144,32692,-2210,32687,-2277,32683,-2344,32678,-2411,32673,-2478,32668,-2545,32662,-2611,32657,-2678,32651,-2745,32646,-2812,32640,-2879,32634,-2945,32628,-3012,32622,-3079,32615,-3146,32609,-3212,32602,-3279,32595,-3346,32588,-3412,32581,-3479,32574,-3546,32567,-3612,32559,-3679,32552,-3745,32544,-3812,32536,-3878,32528,-3945,32520,-4012,32512,-4078,32503,-4145,32495,-4211,32486,-4277,32477,-4344,32468,-4410,32459,-4477,32450,-4543,32441,-4609,32431,-4676,32422,-4742,32412,-4808,32402,-4875,32392,-4941,32382,-5007,32371,-5073,32361,-5140,32350,-5206,32340,-5272,32329,-5338,32318,-5404,32307,-5470,32295,-5536,32284,-5602,32273,-5668,32261,-5734,32249,-5800,32237,-5866,32225,-5932,32213,-5998,32201,-6064,32188,-6130,32176,-6196,32163,-6262,32150,-6327,32137,-6393,32124,-6459,32110,-6524,32097,-6590,32084,-6656,32070,-6721,32056,-6787,32042,-6852,32028,-6918,32014,-6983,31999,-7049,31985,-7114,31970,-7180,31956,-7245,31941,-7311,31926,-7376,31911,-7441,31895,-7506,31880,-7572,31864,-7637,31849,-7702,31833,-7767,31817,-7832,31801,-7897,31785,-7962,31768,-8027,31752,-8092,31735,-8157,31718,-8222,31701,-8287,31684,-8352,31667,-8416,31650,-8481,31633,-8546,31615,-8611,31597,-8675,31580,-8740,31562,-8804,31544,-8869,31525,-8933,31507,-8998,31489,-9062,31470,-9127,31451,-9191,31432,-9255,31413,-9320,31394,-9384,31375,-9448,31356,-9512,31336,-9576,31316,-9640,31297,-9704,31277,-9768,31257,-9832,31236,-9896,31216,-9960,31196,-10024,31175,-10088,31154,-10152,31134,-10215,31113,-10279,31092,-10343,31070,-10406,31049,-10470,31028,-10533,31006,-10597,30984,-10660,30962,-10723,30940,-10787,30918,-10850,30896,-10913,30874,-10976,30851,-11039,30828,-11102,30806,-11165,30783,-11228,30760,-11291,30737,-11354,30713,-11417,30690,-11480,30666,-11543,30643,-11605,30619,-11668,30595,-11731,30571,-11793,30547,-11856,30522,-11918,30498,-11981,30473,-12043,30449,-12105,30424,-12167,30399,-12230,30374,-12292,30349,-12354,30323,-12416,30298,-12478,30272,-12540,30247,-12602,30221,-12664,30195,-12725,30169,-12787,30142,-12849,30116,-12910,30090,-12972,30063,-13034,30036,-13095,30009,-13156,29983,-13218,29955,-13279,29928,-13340,29901,-13401,29873,-13463,29846,-13524,29818,-13585,29790,-13646,29762,-13707,29734,-13767,29706,-13828,29678,-13889,29649,-13950,29621,-14010,29592,-14071,29563,-14131,29534,-14192,29505,-14252,29476,-14312,29446,-14373,29417,-14433,29387,-14493,29358,-14553,29328,-14613,29298,-14673,29268,-14733,29238,-14793,29207,-14853,29177,-14912,29146,-14972,29116,-15031,29085,-15091,29054,-15150,29023,-15210,28992,-15269,28960,-15328,28929,-15388,28897,-15447,28866,-15506,28834,-15565,28802,-15624,28770,-15683,28738,-15741,28706,-15800,28673,-15859,28641,-15918,28608,-15976,28575,-16035,28543,-16093,28510,-16151,28477,-16210,28443,-16268,28410,-16326,28377,-16384,28343,-16442,28309,-16500,28275,-16558,28242,-16616,28208,-16673,28173,-16731,28139,-16789,28105,-16846,28070,-16904,28036,-16961,28001,-17018,27966,-17075,27931,-17133,27896,-17190,27861,-17247,27825,-17304,27790,-17361,27754,-17417,27719,-17474,27683,-17531,27647,-17587,27611,-17644,27575,-17700,27538,-17757,27502,-17813,27466,-17869,27429,-17925,27392,-17981,27355,-18037,27319,-18093,27281,-18149,27244,-18205,27207,-18261,27170,-18316,27132,-18372,27094,-18427,27057,-18483,27019,-18538,26981,-18593,26943,-18648,26905,-18703,26866,-18758,26828,-18813,26789,-18868,26751,-18923,26712,-18977,26673,-19032,26634,-19087,26595,-19141,26556,-19195,26516,-19250,26477,-19304,26437,-19358,26398,-19412,26358,-19466,26318,-19520,26278,-19574,26238,-19627,26198,-19681,26158,-19734,26117,-19788,26077,-19841,26036,-19895,25995,-19948,25954,-20001,25913,-20054,25872,-20107,25831,-20160,25790,-20213,25749,-20265,25707,-20318,25665,-20370,25624,-20423,25582,-20475,25540,-20528,25498,-20580,25456,-20632,25414,-20684,25371,-20736,25329,-20788,25286,-20839,25243,-20891,25201,-20943,25158,-20994,25115,-21046,25072,-21097,25029,-21148,24985,-21199,24942,-21250,24898,-21301,24855,-21352,24811,-21403,24767,-21454,24723,-21504,24679,-21555,24635,-21605,24591,-21656,24546,-21706,24502,-21756,24457,-21806,24413,-21856,24368,-21906,24323,-21956,24278,-22005,24233,-22055,24188,-22105,24143,-22154,24097,-22203,24052,-22253,24006,-22302,23961,-22351,23915,-22400,23869,-22449,23823,-22497,23777,-22546,23731,-22595,23685,-22643,23638,-22692,23592,-22740,23545,-22788,23499,-22836,23452,-22884,23405,-22932,23358,-22980,23311,-23028,23264,-23075,23217,-23123,23169,-23170,23122,-23218,23074,-23265,23027,-23312,22979,-23359,22931,-23406,22883,-23453,22835,-23500,22787,-23546,22739,-23593,22691,-23639,22642,-23686,22594,-23732,22545,-23778,22496,-23824,22448,-23870,22399,-23916,22350,-23962,22301,-24007,22252,-24053,22202,-24098,22153,-24144,22104,-24189,22054,-24234,22004,-24279,21955,-24324,21905,-24369,21855,-24414,21805,-24458,21755,-24503,21705,-24547,21655,-24592,21604,-24636,21554,-24680,21503,-24724,21453,-24768,21402,-24812,21351,-24856,21300,-24899,21249,-24943,21198,-24986,21147,-25030,21096,-25073,21045,-25116,20993,-25159,20942,-25202,20890,-25244,20838,-25287,20787,-25330,20735,-25372,20683,-25415,20631,-25457,20579,-25499,20527,-25541,20474,-25583,20422,-25625,20369,-25666,20317,-25708,20264,-25750,20212,-25791,20159,-25832,20106,-25873,20053,-25914,20000,-25955,19947,-25996,19894,-26037,19840,-26078,19787,-26118,19733,-26159,19680,-26199,19626,-26239,19573,-26279,19519,-26319,19465,-26359,19411,-26399,19357,-26438,19303,-26478,19249,-26517,19194,-26557,19140,-26596,19086,-26635,19031,-26674,18976,-26713,18922,-26752,18867,-26790,18812,-26829,18757,-26867,18702,-26906,18647,-26944,18592,-26982,18537,-27020,18482,-27058,18426,-27095,18371,-27133,18315,-27171,18260,-27208,18204,-27245,18148,-27282,18092,-27320,18036,-27356,17980,-27393,17924,-27430,17868,-27467,17812,-27503,17756,-27539,17699,-27576,17643,-27612,17586,-27648,17530,-27684,17473,-27720,17416,-27755,17360,-27791,17303,-27826,17246,-27862,17189,-27897,17132,-27932,17074,-27967,17017,-28002,16960,-28037,16903,-28071,16845,-28106,16788,-28140,16730,-28174,16672,-28209,16615,-28243,16557,-28276,16499,-28310,16441,-28344,16383,-28378,16325,-28411,16267,-28444,16209,-28478,16150,-28511,16092,-28544,16034,-28576,15975,-28609,15917,-28642,15858,-28674,15799,-28707,15740,-28739,15682,-28771,15623,-28803,15564,-28835,15505,-28867,15446,-28898,15387,-28930,15327,-28961,15268,-28993,15209,-29024,15149,-29055,15090,-29086,15030,-29117,14971,-29147,14911,-29178,14852,-29208,14792,-29239,14732,-29269,14672,-29299,14612,-29329,14552,-29359,14492,-29388,14432,-29418,14372,-29447,14311,-29477,14251,-29506,14191,-29535,14130,-29564,14070,-29593,14009,-29622,13949,-29650,13888,-29679,13827,-29707,13766,-29735,13706,-29763,13645,-29791,13584,-29819,13523,-29847,13462,-29874,13400,-29902,13339,-29929,13278,-29956,13217,-29984,13155,-30010,13094,-30037,13033,-30064,12971,-30091,12909,-30117,12848,-30143,12786,-30170,12724,-30196,12663,-30222,12601,-30248,12539,-30273,12477,-30299,12415,-30324,12353,-30350,12291,-30375,12229,-30400,12166,-30425,12104,-30450,12042,-30474,11980,-30499,11917,-30523,11855,-30548,11792,-30572,11730,-30596,11667,-30620,11604,-30644,11542,-30667,11479,-30691,11416,-30714,11353,-30738,11290,-30761,11227,-30784,11164,-30807,11101,-30829,11038,-30852,10975,-30875,10912,-30897,10849,-30919,10786,-30941,10722,-30963,10659,-30985,10596,-31007,10532,-31029,10469,-31050,10405,-31071,10342,-31093,10278,-31114,10214,-31135,10151,-31155,10087,-31176,10023,-31197,9959,-31217,9895,-31237,9831,-31258,9767,-31278,9703,-31298,9639,-31317,9575,-31337,9511,-31357,9447,-31376,9383,-31395,9319,-31414,9254,-31433,9190,-31452,9126,-31471,9061,-31490,8997,-31508,8932,-31526,8868,-31545,8803,-31563,8739,-31581,8674,-31598,8610,-31616,8545,-31634,8480,-31651,8415,-31668,8351,-31685,8286,-31702,8221,-31719,8156,-31736,8091,-31753,8026,-31769,7961,-31786,7896,-31802,7831,-31818,7766,-31834,7701,-31850,7636,-31865,7571,-31881,7505,-31896,7440,-31912,7375,-31927,7310,-31942,7244,-31957,7179,-31971,7113,-31986,7048,-32000,6982,-32015,6917,-32029,6851,-32043,6786,-32057,6720,-32071,6655,-32085,6589,-32098,6523,-32111,6458,-32125,6392,-32138,6326,-32151,6261,-32164,6195,-32177,6129,-32189,6063,-32202,5997,-32214,5931,-32226,5865,-32238,5799,-32250,5733,-32262,5667,-32274,5601,-32285,5535,-32296,5469,-32308,5403,-32319,5337,-32330,5271,-32341,5205,-32351,5139,-32362,5072,-32372,5006,-32383,4940,-32393,4874,-32403,4807,-32413,4741,-32423,4675,-32432,4608,-32442,4542,-32451,4476,-32460,4409,-32469,4343,-32478,4276,-32487,4210,-32496,4144,-32504,4077,-32513,4011,-32521,3944,-32529,3877,-32537,3811,-32545,3744,-32553,3678,-32560,3611,-32568,3545,-32575,3478,-32582,3411,-32589,3345,-32596,3278,-32603,3211,-32610,3145,-32616,3078,-32623,3011,-32629,2944,-32635,2878,-32641,2811,-32647,2744,-32652,2677,-32658,2610,-32663,2544,-32669,2477,-32674,2410,-32679,2343,-32684,2276,-32688,2209,-32693,2143,-32697,2076,-32702,2009,-32706,1942,-32710,1875,-32714,1808,-32718,1741,-32721,1674,-32725,1607,-32728,1540,-32731,1473,-32734,1406,-32737,1339,-32740,1273,-32743,1206,-32745,1139,-32748,1072,-32750,1005,-32752,938,-32754,871,-32756,804,-32758,737,-32759,670,-32761,603,-32762,536,-32763,469,-32764,402,-32765,335,-32766,268,-32766,201,-32767,134,-32767,67,-32767,0,-32767,-68,-32767,-135,-32767,-202,-32767,-269,-32766,-336,-32766,-403,-32765,-470,-32764,-537,-32763,-604,-32762,-671,-32761,-738,-32759,-805,-32758,-872,-32756,-939,-32754,-1006,-32752,-1073,-32750,-1140,-32748,-1207,-32745,-1274,-32743,-1340,-32740,-1407,-32737,-1474,-32734,-1541,-32731,-1608,-32728,-1675,-32725,-1742,-32721,-1809,-32718,-1876,-32714,-1943,-32710,-2010,-32706,-2077,-32702,-2144,-32697,-2210,-32693,-2277,-32688,-2344,-32684,-2411,-32679,-2478,-32674,-2545,-32669,-2611,-32663,-2678,-32658,-2745,-32652,-2812,-32647,-2879,-32641,-2945,-32635,-3012,-32629,-3079,-32623,-3146,-32616,-3212,-32610,-3279,-32603,-3346,-32596,-3412,-32589,-3479,-32582,-3546,-32575,-3612,-32568,-3679,-32560,-3745,-32553,-3812,-32545,-3878,-32537,-3945,-32529,-4012,-32521,-4078,-32513,-4145,-32504,-4211,-32496,-4277,-32487,-4344,-32478,-4410,-32469,-4477,-32460,-4543,-32451,-4609,-32442,-4676,-32432,-4742,-32423,-4808,-32413,-4875,-32403,-4941,-32393,-5007,-32383,-5073,-32372,-5140,-32362,-5206,-32351,-5272,-32341,-5338,-32330,-5404,-32319,-5470,-32308,-5536,-32296,-5602,-32285,-5668,-32274,-5734,-32262,-5800,-32250,-5866,-32238,-5932,-32226,-5998,-32214,-6064,-32202,-6130,-32189,-6196,-32177,-6262,-32164,-6327,-32151,-6393,-32138,-6459,-32125,-6524,-32111,-6590,-32098,-6656,-32085,-6721,-32071,-6787,-32057,-6852,-32043,-6918,-32029,-6983,-32015,-7049,-32000,-7114,-31986,-7180,-31971,-7245,-31957,-7311,-31942,-7376,-31927,-7441,-31912,-7506,-31896,-7572,-31881,-7637,-31865,-7702,-31850,-7767,-31834,-7832,-31818,-7897,-31802,-7962,-31786,-8027,-31769,-8092,-31753,-8157,-31736,-8222,-31719,-8287,-31702,-8352,-31685,-8416,-31668,-8481,-31651,-8546,-31634,-8611,-31616,-8675,-31598,-8740,-31581,-8804,-31563,-8869,-31545,-8933,-31526,-8998,-31508,-9062,-31490,-9127,-31471,-9191,-31452,-9255,-31433,-9320,-31414,-9384,-31395,-9448,-31376,-9512,-31357,-9576,-31337,-9640,-31317,-9704,-31298,-9768,-31278,-9832,-31258,-9896,-31237,-9960,-31217,-10024,-31197,-10088,-31176,-10152,-31155,-10215,-31135,-10279,-31114,-10343,-31093,-10406,-31071,-10470,-31050,-10533,-31029,-10597,-31007,-10660,-30985,-10723,-30963,-10787,-30941,-10850,-30919,-10913,-30897,-10976,-30875,-11039,-30852,-11102,-30829,-11165,-30807,-11228,-30784,-11291,-30761,-11354,-30738,-11417,-30714,-11480,-30691,-11543,-30667,-11605,-30644,-11668,-30620,-11731,-30596,-11793,-30572,-11856,-30548,-11918,-30523,-11981,-30499,-12043,-30474,-12105,-30450,-12167,-30425,-12230,-30400,-12292,-30375,-12354,-30350,-12416,-30324,-12478,-30299,-12540,-30273,-12602,-30248,-12664,-30222,-12725,-30196,-12787,-30170,-12849,-30143,-12910,-30117,-12972,-30091,-13034,-30064,-13095,-30037,-13156,-30010,-13218,-29984,-13279,-29956,-13340,-29929,-13401,-29902,-13463,-29874,-13524,-29847,-13585,-29819,-13646,-29791,-13707,-29763,-13767,-29735,-13828,-29707,-13889,-29679,-13950,-29650,-14010,-29622,-14071,-29593,-14131,-29564,-14192,-29535,-14252,-29506,-14312,-29477,-14373,-29447,-14433,-29418,-14493,-29388,-14553,-29359,-14613,-29329,-14673,-29299,-14733,-29269,-14793,-29239,-14853,-29208,-14912,-29178,-14972,-29147,-15031,-29117,-15091,-29086,-15150,-29055,-15210,-29024,-15269,-28993,-15328,-28961,-15388,-28930,-15447,-28898,-15506,-28867,-15565,-28835,-15624,-28803,-15683,-28771,-15741,-28739,-15800,-28707,-15859,-28674,-15918,-28642,-15976,-28609,-16035,-28576,-16093,-28544,-16151,-28511,-16210,-28478,-16268,-28444,-16326,-28411,}; -static int16_t twb3072[2048] = {32767,0,32766,-135,32765,-269,32764,-403,32762,-537,32760,-671,32757,-805,32753,-939,32749,-1073,32744,-1207,32739,-1340,32733,-1474,32727,-1608,32720,-1742,32713,-1876,32705,-2010,32696,-2144,32687,-2277,32678,-2411,32668,-2545,32657,-2678,32646,-2812,32634,-2945,32622,-3079,32609,-3212,32595,-3346,32581,-3479,32567,-3612,32552,-3745,32536,-3878,32520,-4012,32503,-4145,32486,-4277,32468,-4410,32450,-4543,32431,-4676,32412,-4808,32392,-4941,32371,-5073,32350,-5206,32329,-5338,32307,-5470,32284,-5602,32261,-5734,32237,-5866,32213,-5998,32188,-6130,32163,-6262,32137,-6393,32110,-6524,32084,-6656,32056,-6787,32028,-6918,31999,-7049,31970,-7180,31941,-7311,31911,-7441,31880,-7572,31849,-7702,31817,-7832,31785,-7962,31752,-8092,31718,-8222,31684,-8352,31650,-8481,31615,-8611,31580,-8740,31544,-8869,31507,-8998,31470,-9127,31432,-9255,31394,-9384,31356,-9512,31316,-9640,31277,-9768,31236,-9896,31196,-10024,31154,-10152,31113,-10279,31070,-10406,31028,-10533,30984,-10660,30940,-10787,30896,-10913,30851,-11039,30806,-11165,30760,-11291,30713,-11417,30666,-11543,30619,-11668,30571,-11793,30522,-11918,30473,-12043,30424,-12167,30374,-12292,30323,-12416,30272,-12540,30221,-12664,30169,-12787,30116,-12910,30063,-13034,30009,-13156,29955,-13279,29901,-13401,29846,-13524,29790,-13646,29734,-13767,29678,-13889,29621,-14010,29563,-14131,29505,-14252,29446,-14373,29387,-14493,29328,-14613,29268,-14733,29207,-14853,29146,-14972,29085,-15091,29023,-15210,28960,-15328,28897,-15447,28834,-15565,28770,-15683,28706,-15800,28641,-15918,28575,-16035,28510,-16151,28443,-16268,28377,-16384,28309,-16500,28242,-16616,28173,-16731,28105,-16846,28036,-16961,27966,-17075,27896,-17190,27825,-17304,27754,-17417,27683,-17531,27611,-17644,27538,-17757,27466,-17869,27392,-17981,27319,-18093,27244,-18205,27170,-18316,27094,-18427,27019,-18538,26943,-18648,26866,-18758,26789,-18868,26712,-18977,26634,-19087,26556,-19195,26477,-19304,26398,-19412,26318,-19520,26238,-19627,26158,-19734,26077,-19841,25995,-19948,25913,-20054,25831,-20160,25749,-20265,25665,-20370,25582,-20475,25498,-20580,25414,-20684,25329,-20788,25243,-20891,25158,-20994,25072,-21097,24985,-21199,24898,-21301,24811,-21403,24723,-21504,24635,-21605,24546,-21706,24457,-21806,24368,-21906,24278,-22005,24188,-22105,24097,-22203,24006,-22302,23915,-22400,23823,-22497,23731,-22595,23638,-22692,23545,-22788,23452,-22884,23358,-22980,23264,-23075,23169,-23170,23074,-23265,22979,-23359,22883,-23453,22787,-23546,22691,-23639,22594,-23732,22496,-23824,22399,-23916,22301,-24007,22202,-24098,22104,-24189,22004,-24279,21905,-24369,21805,-24458,21705,-24547,21604,-24636,21503,-24724,21402,-24812,21300,-24899,21198,-24986,21096,-25073,20993,-25159,20890,-25244,20787,-25330,20683,-25415,20579,-25499,20474,-25583,20369,-25666,20264,-25750,20159,-25832,20053,-25914,19947,-25996,19840,-26078,19733,-26159,19626,-26239,19519,-26319,19411,-26399,19303,-26478,19194,-26557,19086,-26635,18976,-26713,18867,-26790,18757,-26867,18647,-26944,18537,-27020,18426,-27095,18315,-27171,18204,-27245,18092,-27320,17980,-27393,17868,-27467,17756,-27539,17643,-27612,17530,-27684,17416,-27755,17303,-27826,17189,-27897,17074,-27967,16960,-28037,16845,-28106,16730,-28174,16615,-28243,16499,-28310,16383,-28378,16267,-28444,16150,-28511,16034,-28576,15917,-28642,15799,-28707,15682,-28771,15564,-28835,15446,-28898,15327,-28961,15209,-29024,15090,-29086,14971,-29147,14852,-29208,14732,-29269,14612,-29329,14492,-29388,14372,-29447,14251,-29506,14130,-29564,14009,-29622,13888,-29679,13766,-29735,13645,-29791,13523,-29847,13400,-29902,13278,-29956,13155,-30010,13033,-30064,12909,-30117,12786,-30170,12663,-30222,12539,-30273,12415,-30324,12291,-30375,12166,-30425,12042,-30474,11917,-30523,11792,-30572,11667,-30620,11542,-30667,11416,-30714,11290,-30761,11164,-30807,11038,-30852,10912,-30897,10786,-30941,10659,-30985,10532,-31029,10405,-31071,10278,-31114,10151,-31155,10023,-31197,9895,-31237,9767,-31278,9639,-31317,9511,-31357,9383,-31395,9254,-31433,9126,-31471,8997,-31508,8868,-31545,8739,-31581,8610,-31616,8480,-31651,8351,-31685,8221,-31719,8091,-31753,7961,-31786,7831,-31818,7701,-31850,7571,-31881,7440,-31912,7310,-31942,7179,-31971,7048,-32000,6917,-32029,6786,-32057,6655,-32085,6523,-32111,6392,-32138,6261,-32164,6129,-32189,5997,-32214,5865,-32238,5733,-32262,5601,-32285,5469,-32308,5337,-32330,5205,-32351,5072,-32372,4940,-32393,4807,-32413,4675,-32432,4542,-32451,4409,-32469,4276,-32487,4144,-32504,4011,-32521,3877,-32537,3744,-32553,3611,-32568,3478,-32582,3345,-32596,3211,-32610,3078,-32623,2944,-32635,2811,-32647,2677,-32658,2544,-32669,2410,-32679,2276,-32688,2143,-32697,2009,-32706,1875,-32714,1741,-32721,1607,-32728,1473,-32734,1339,-32740,1206,-32745,1072,-32750,938,-32754,804,-32758,670,-32761,536,-32763,402,-32765,268,-32766,134,-32767,0,-32767,-135,-32767,-269,-32766,-403,-32765,-537,-32763,-671,-32761,-805,-32758,-939,-32754,-1073,-32750,-1207,-32745,-1340,-32740,-1474,-32734,-1608,-32728,-1742,-32721,-1876,-32714,-2010,-32706,-2144,-32697,-2277,-32688,-2411,-32679,-2545,-32669,-2678,-32658,-2812,-32647,-2945,-32635,-3079,-32623,-3212,-32610,-3346,-32596,-3479,-32582,-3612,-32568,-3745,-32553,-3878,-32537,-4012,-32521,-4145,-32504,-4277,-32487,-4410,-32469,-4543,-32451,-4676,-32432,-4808,-32413,-4941,-32393,-5073,-32372,-5206,-32351,-5338,-32330,-5470,-32308,-5602,-32285,-5734,-32262,-5866,-32238,-5998,-32214,-6130,-32189,-6262,-32164,-6393,-32138,-6524,-32111,-6656,-32085,-6787,-32057,-6918,-32029,-7049,-32000,-7180,-31971,-7311,-31942,-7441,-31912,-7572,-31881,-7702,-31850,-7832,-31818,-7962,-31786,-8092,-31753,-8222,-31719,-8352,-31685,-8481,-31651,-8611,-31616,-8740,-31581,-8869,-31545,-8998,-31508,-9127,-31471,-9255,-31433,-9384,-31395,-9512,-31357,-9640,-31317,-9768,-31278,-9896,-31237,-10024,-31197,-10152,-31155,-10279,-31114,-10406,-31071,-10533,-31029,-10660,-30985,-10787,-30941,-10913,-30897,-11039,-30852,-11165,-30807,-11291,-30761,-11417,-30714,-11543,-30667,-11668,-30620,-11793,-30572,-11918,-30523,-12043,-30474,-12167,-30425,-12292,-30375,-12416,-30324,-12540,-30273,-12664,-30222,-12787,-30170,-12910,-30117,-13034,-30064,-13156,-30010,-13279,-29956,-13401,-29902,-13524,-29847,-13646,-29791,-13767,-29735,-13889,-29679,-14010,-29622,-14131,-29564,-14252,-29506,-14373,-29447,-14493,-29388,-14613,-29329,-14733,-29269,-14853,-29208,-14972,-29147,-15091,-29086,-15210,-29024,-15328,-28961,-15447,-28898,-15565,-28835,-15683,-28771,-15800,-28707,-15918,-28642,-16035,-28576,-16151,-28511,-16268,-28444,-16384,-28378,-16500,-28310,-16616,-28243,-16731,-28174,-16846,-28106,-16961,-28037,-17075,-27967,-17190,-27897,-17304,-27826,-17417,-27755,-17531,-27684,-17644,-27612,-17757,-27539,-17869,-27467,-17981,-27393,-18093,-27320,-18205,-27245,-18316,-27171,-18427,-27095,-18538,-27020,-18648,-26944,-18758,-26867,-18868,-26790,-18977,-26713,-19087,-26635,-19195,-26557,-19304,-26478,-19412,-26399,-19520,-26319,-19627,-26239,-19734,-26159,-19841,-26078,-19948,-25996,-20054,-25914,-20160,-25832,-20265,-25750,-20370,-25666,-20475,-25583,-20580,-25499,-20684,-25415,-20788,-25330,-20891,-25244,-20994,-25159,-21097,-25073,-21199,-24986,-21301,-24899,-21403,-24812,-21504,-24724,-21605,-24636,-21706,-24547,-21806,-24458,-21906,-24369,-22005,-24279,-22105,-24189,-22203,-24098,-22302,-24007,-22400,-23916,-22497,-23824,-22595,-23732,-22692,-23639,-22788,-23546,-22884,-23453,-22980,-23359,-23075,-23265,-23170,-23170,-23265,-23075,-23359,-22980,-23453,-22884,-23546,-22788,-23639,-22692,-23732,-22595,-23824,-22497,-23916,-22400,-24007,-22302,-24098,-22203,-24189,-22105,-24279,-22005,-24369,-21906,-24458,-21806,-24547,-21706,-24636,-21605,-24724,-21504,-24812,-21403,-24899,-21301,-24986,-21199,-25073,-21097,-25159,-20994,-25244,-20891,-25330,-20788,-25415,-20684,-25499,-20580,-25583,-20475,-25666,-20370,-25750,-20265,-25832,-20160,-25914,-20054,-25996,-19948,-26078,-19841,-26159,-19734,-26239,-19627,-26319,-19520,-26399,-19412,-26478,-19304,-26557,-19195,-26635,-19087,-26713,-18977,-26790,-18868,-26867,-18758,-26944,-18648,-27020,-18538,-27095,-18427,-27171,-18316,-27245,-18205,-27320,-18093,-27393,-17981,-27467,-17869,-27539,-17757,-27612,-17644,-27684,-17531,-27755,-17417,-27826,-17304,-27897,-17190,-27967,-17075,-28037,-16961,-28106,-16846,-28174,-16731,-28243,-16616,-28310,-16500,-28378,-16384,-28444,-16268,-28511,-16151,-28576,-16035,-28642,-15918,-28707,-15800,-28771,-15683,-28835,-15565,-28898,-15447,-28961,-15328,-29024,-15210,-29086,-15091,-29147,-14972,-29208,-14853,-29269,-14733,-29329,-14613,-29388,-14493,-29447,-14373,-29506,-14252,-29564,-14131,-29622,-14010,-29679,-13889,-29735,-13767,-29791,-13646,-29847,-13524,-29902,-13401,-29956,-13279,-30010,-13156,-30064,-13034,-30117,-12910,-30170,-12787,-30222,-12664,-30273,-12540,-30324,-12416,-30375,-12292,-30425,-12167,-30474,-12043,-30523,-11918,-30572,-11793,-30620,-11668,-30667,-11543,-30714,-11417,-30761,-11291,-30807,-11165,-30852,-11039,-30897,-10913,-30941,-10787,-30985,-10660,-31029,-10533,-31071,-10406,-31114,-10279,-31155,-10152,-31197,-10024,-31237,-9896,-31278,-9768,-31317,-9640,-31357,-9512,-31395,-9384,-31433,-9255,-31471,-9127,-31508,-8998,-31545,-8869,-31581,-8740,-31616,-8611,-31651,-8481,-31685,-8352,-31719,-8222,-31753,-8092,-31786,-7962,-31818,-7832,-31850,-7702,-31881,-7572,-31912,-7441,-31942,-7311,-31971,-7180,-32000,-7049,-32029,-6918,-32057,-6787,-32085,-6656,-32111,-6524,-32138,-6393,-32164,-6262,-32189,-6130,-32214,-5998,-32238,-5866,-32262,-5734,-32285,-5602,-32308,-5470,-32330,-5338,-32351,-5206,-32372,-5073,-32393,-4941,-32413,-4808,-32432,-4676,-32451,-4543,-32469,-4410,-32487,-4277,-32504,-4145,-32521,-4012,-32537,-3878,-32553,-3745,-32568,-3612,-32582,-3479,-32596,-3346,-32610,-3212,-32623,-3079,-32635,-2945,-32647,-2812,-32658,-2678,-32669,-2545,-32679,-2411,-32688,-2277,-32697,-2144,-32706,-2010,-32714,-1876,-32721,-1742,-32728,-1608,-32734,-1474,-32740,-1340,-32745,-1207,-32750,-1073,-32754,-939,-32758,-805,-32761,-671,-32763,-537,-32765,-403,-32766,-269,-32767,-135,-32767,-1,-32767,134,-32766,268,-32765,402,-32763,536,-32761,670,-32758,804,-32754,938,-32750,1072,-32745,1206,-32740,1339,-32734,1473,-32728,1607,-32721,1741,-32714,1875,-32706,2009,-32697,2143,-32688,2276,-32679,2410,-32669,2544,-32658,2677,-32647,2811,-32635,2944,-32623,3078,-32610,3211,-32596,3345,-32582,3478,-32568,3611,-32553,3744,-32537,3877,-32521,4011,-32504,4144,-32487,4276,-32469,4409,-32451,4542,-32432,4675,-32413,4807,-32393,4940,-32372,5072,-32351,5205,-32330,5337,-32308,5469,-32285,5601,-32262,5733,-32238,5865,-32214,5997,-32189,6129,-32164,6261,-32138,6392,-32111,6523,-32085,6655,-32057,6786,-32029,6917,-32000,7048,-31971,7179,-31942,7310,-31912,7440,-31881,7571,-31850,7701,-31818,7831,-31786,7961,-31753,8091,-31719,8221,-31685,8351,-31651,8480,-31616,8610,-31581,8739,-31545,8868,-31508,8997,-31471,9126,-31433,9254,-31395,9383,-31357,9511,-31317,9639,-31278,9767,-31237,9895,-31197,10023,-31155,10151,-31114,10278,-31071,10405,-31029,10532,-30985,10659,-30941,10786,-30897,10912,-30852,11038,-30807,11164,-30761,11290,-30714,11416,-30667,11542,-30620,11667,-30572,11792,-30523,11917,-30474,12042,-30425,12166,-30375,12291,-30324,12415,-30273,12539,-30222,12663,-30170,12786,-30117,12909,-30064,13033,-30010,13155,-29956,13278,-29902,13400,-29847,13523,-29791,13645,-29735,13766,-29679,13888,-29622,14009,-29564,14130,-29506,14251,-29447,14372,-29388,14492,-29329,14612,-29269,14732,-29208,14852,-29147,14971,-29086,15090,-29024,15209,-28961,15327,-28898,15446,-28835,15564,-28771,15682,-28707,15799,-28642,15917,-28576,16034,-28511,16150,-28444,16267,-28378,16383,-28310,16499,-28243,16615,-28174,16730,-28106,16845,-28037,16960,-27967,17074,-27897,17189,-27826,17303,-27755,17416,-27684,17530,-27612,17643,-27539,17756,-27467,17868,-27393,17980,-27320,18092,-27245,18204,-27171,18315,-27095,18426,-27020,18537,-26944,18647,-26867,18757,-26790,18867,-26713,18976,-26635,19086,-26557,19194,-26478,19303,-26399,19411,-26319,19519,-26239,19626,-26159,19733,-26078,19840,-25996,19947,-25914,20053,-25832,20159,-25750,20264,-25666,20369,-25583,20474,-25499,20579,-25415,20683,-25330,20787,-25244,20890,-25159,20993,-25073,21096,-24986,21198,-24899,21300,-24812,21402,-24724,21503,-24636,21604,-24547,21705,-24458,21805,-24369,21905,-24279,22004,-24189,22104,-24098,22202,-24007,22301,-23916,22399,-23824,22496,-23732,22594,-23639,22691,-23546,22787,-23453,22883,-23359,22979,-23265,23074,-23170,23169,-23075,23264,-22980,23358,-22884,23452,-22788,23545,-22692,23638,-22595,23731,-22497,23823,-22400,23915,-22302,24006,-22203,24097,-22105,24188,-22005,24278,-21906,24368,-21806,24457,-21706,24546,-21605,24635,-21504,24723,-21403,24811,-21301,24898,-21199,24985,-21097,25072,-20994,25158,-20891,25243,-20788,25329,-20684,25414,-20580,25498,-20475,25582,-20370,25665,-20265,25749,-20160,25831,-20054,25913,-19948,25995,-19841,26077,-19734,26158,-19627,26238,-19520,26318,-19412,26398,-19304,26477,-19195,26556,-19087,26634,-18977,26712,-18868,26789,-18758,26866,-18648,26943,-18538,27019,-18427,27094,-18316,27170,-18205,27244,-18093,27319,-17981,27392,-17869,27466,-17757,27538,-17644,27611,-17531,27683,-17417,27754,-17304,27825,-17190,27896,-17075,27966,-16961,28036,-16846,28105,-16731,28173,-16616,28242,-16500,28309,}; diff --git a/svn2git/README.txt b/svn2git/README.txt deleted file mode 100644 index ef20ceebf0..0000000000 --- a/svn2git/README.txt +++ /dev/null @@ -1,64 +0,0 @@ -This file describes briefly the steps that were carried out to migrate from *PUBLIC* OAI SVN repo (http://svn.eurecom.fr/openair4G/trunk) to the gitlab repo (git@gitlab.eurecom.fr:oai/openairinterface5G.git). In order to reduce the size of repository, we have only included SVN commits from r4000 up till now. None of branches/tags are migrated from SVN Repository to Git. - -1. The steps to migrate from SVN to Git were carried out using the instructions/script here, https://www.atlassian.com/git/tutorials/migrating-overview - -2. Currently, the repository is public during the "transition period" for everyone to get used to the repository. During the "transition period", we will check in changes only to SVN and synchronize SVN to Git repository once everyday. At the end of "transition period", we will mark SVN repo as read-only and Git repository will be the default working repository. Currently, the "transition period" is set to 1 month until 15 July. However, this date might be changed based on the feedback from the community.There are brief instructions to explain this workflow here, https://www.atlassian.com/git/tutorials/migrating-overview/. - -3. The author list file is located in authors.txt in the main working directory. This file was extracted from SVN logs, but is modified for name and email addresses. - -4. Add a certificate from gitlab.eurecom.fr to your Ubuntu 14.04 installation (you need to be root user) - a) echo -n | openssl s_client -showcerts -connect gitlab.eurecom.fr:443 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /usr/local/share/ca-certificates/gitlab_eurecom_fr.crt - b)update-ca-certificates - -5. Git one time configuration with your name/email address. - git config --global user.name "Your Name" - git config --global user.email "Your email address" - -6. In order to checkout the Git repository (for OAI Users without login to gitlab server) - a) export GIT_SSL_NO_VERIFY=1; git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git (without certificate installation in step 4) - b) git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git (If certificate is installed in step 4) - -6. In order to checkout the Git repository (for OAI Developers/admins with login to gitlab server). Please send email to openair_tech@eurecom.fr to be added to the repository as a developer). If you do not have account on gitlab.eurecom.fr, please register yourself to gitlab.eurecom.fr. - - a) Checkout with using ssh keys: - You will need to put your ssh keys in https://gitlab.eurecom.fr/profile/keys to access to the git repo (only important for users who want to commit to the repository). Once that is done, checkout the git repository using: - git clone git@gitlab.eurecom.fr:oai/openairinterface5g.git - - b) Checkout with user name/password prompt: - - git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openairinterface5g.git - - - -Migration Instructions from SVN->Git in Detail (Not important for OAI Developer Community): -Assuming you are in svn2git directory. - -wget https://bitbucket.org/atlassian/svn-migration-scripts/downloads/svn-migration-scripts.jar -java -jar ./svn-migration-scripts.jar verify -java -jar ./svn-migration-scripts.jar authors http://svn.eurecom.fr/openair4G > authors.txt -git svn clone -r4000:HEAD --authors-file=./svn2git/authors.txt http://svn.eurecom.fr/openair4G/trunk oaiRepoData1 >& log_svn_clone1.out - -(Assuming you have added your ssh keys in https://gitlab.eurecom.fr/profile/keys) -//One time git configuration of user name/email address -git config --global user.name "Replace_With_Your_Name" -git config --global user.email "Replace_With_Your_Email_address" - -git remote add origin git@gitlab.eurecom.fr:oai/openairinterface5g.git - -git push -u origin --all -git push --tags - -Steps to synchronize on calisson (to be carried out periodically) -cd ~rohit/GitMigration/GitRepoNew/oaiRepoData1/svn2git -git config -l -git config --global user.name "Replace_With_Your_Name" -git config --global user.email "Replace_With_Your_Email_address" -./check_diff_author.sh #There should be no difference in author list file -git remote set-url origin https://kaltenbe@gitlab.eurecom.fr/oai/openairinterface5g.git -git svn fetch #--authors-file=./authors.txt (Make sure that there are no new authors since the last migration, else this will result in errors) -git svn rebase -git push -u origin --all -git push --tags - - - diff --git a/svn2git/authors.txt b/svn2git/authors.txt deleted file mode 100644 index 8bf7dbed0e..0000000000 --- a/svn2git/authors.txt +++ /dev/null @@ -1,86 +0,0 @@ -agostini = agostini -alexandr = alexandr -ambe = Anne Ambe -anouar = Hicham Anouar -antonb = antonb -apostolaras = Apostolos Apostolaras -arvanita = Arvanita -atsan = Emre Atsan -auberts = auberts -benromdh = benromdh -besnier = Joelle Besnier -bhamri = Bhamri -bohge = Mathias Bohge -brizzola = brizzola -byiringi = Byiringi -cerdan = Cerdan -cirkic = Cirkic -demiray = demiray -ferreira = Ferreira -fkalten = fkalten -fotimeli = Fotimeli -foubert = Philippe Foubert -gangakhe = Gangakhe -gangula = gangula -garcial = garcial -gauthier = Lionel Gauthier -ghaddab = ghaddab -ghaffar = ghaffar -guibene = guibene -guptar = Rohit Gupta -haerri = Haerri -hafsaoui = Hafsaoui -hao = hao -hashmat = hashmat -hrizi = hrizi -hu = hu -huang = Huang -iacobelli = Lorenzo Iacobelli -ihmig = ihmig -jdagres = jdagres -jiangx = jiangx -kaltenbe = Florian Kaltenberger -knopp = Raymond Knopp -kortke = kortke -kouassi = kouassi -laklii = laklii -latif = latif -libchaber = libchaber -linhuang = linhuang -lukashov = lukashov -maatalla = maatalla -maurel = maurel -mayani = mayani -merz = Ruben Merz -mlaner = mlaner -mosli = mosli -navid = Navid Nikaein -nguyenhn = nguyenhn -nguyennd = nguyennd -nikaeinn = Navid Nikaein < -oai_user1 = oai_user1 -ouni = ouni -paranche = paranche -pburlot = pburlot -qi = qi -renwanz = renwanz -roux = Cedric Roux -sait = sait -sorby = sorby -steinicke = steinicke -thomas = thomas -thomasl = thomasl -tonelli = tonelli -unlu = unlu -ustun = ustun -villa = villa -wagner = wagner -wangl = wangl -wetterwa = wetterwa -wewior = wewior -winckel = winckel -xuhl = xuhl -yannan = yannan -yilmaz = yilmaz -zayen = zayen -zhou = zhou diff --git a/svn2git/authors_original.txt b/svn2git/authors_original.txt deleted file mode 100644 index 7e239ce955..0000000000 --- a/svn2git/authors_original.txt +++ /dev/null @@ -1,45 +0,0 @@ -agostini = Agostini -alexandr = Alexandr -ambe = Anne Ambe -anouar = Hicham Anouar -apostolaras = Apostolos Apostolaras -arvanita = Arvanita -atsan = Emre Atsan -besnier = Joelle Besnier -bhamri = Bhamri -bohge = Mathias Bohge -byiringi = Byiringi -cerdan = Cerdan -cirkic = Cirkic -ferreira = Ferreira -fotimeli = Fotimeli -foubert = Philippe Foubert -gangakhe = Gangakhe -gangula = gangula -gauthier = Lionel Gauthier -haerri = Haerri -hafsaoui = Hafsaoui -huang = Huang -iacobelli = Lorenzo Iacobelli -ihmig = Ihmig -jiangx = Jiangx -kaltenbe = Florian Kaltenberger -knopp = Raymond Knopp -lukashov = Lukashov -navid = Navid Nikaein -nguyenhn = Nguyenhn -nguyennd = Nguyennd -nikaeinn = nikaeinn -oai_user1 = oai_user1 -ouni = Ouni -paranche = paranche -qi = qi -roux = Cedric Roux -sait = sait -sorby = sorby -thomas = thomas -unlu = unlu -wagner = wagner -yilmaz = yilmaz -zayen = zayen - diff --git a/svn2git/authors_original_java_output.txt b/svn2git/authors_original_java_output.txt deleted file mode 100644 index ca00a069c8..0000000000 --- a/svn2git/authors_original_java_output.txt +++ /dev/null @@ -1,86 +0,0 @@ -agostini = agostini -alexandr = alexandr -ambe = ambe -anouar = anouar -antonb = antonb -apostolaras = apostolaras -arvanita = arvanita -atsan = atsan -auberts = auberts -benromdh = benromdh -besnier = besnier -bhamri = bhamri -bohge = bohge -brizzola = brizzola -byiringi = byiringi -cerdan = cerdan -cirkic = cirkic -demiray = demiray -ferreira = ferreira -fkalten = fkalten -fotimeli = fotimeli -foubert = foubert -gangakhe = gangakhe -gangula = gangula -garcial = garcial -gauthier = gauthier -ghaddab = ghaddab -ghaffar = ghaffar -guibene = guibene -guptar = guptar -haerri = haerri -hafsaoui = hafsaoui -hao = hao -hashmat = hashmat -hrizi = hrizi -hu = hu -huang = huang -iacobelli = iacobelli -ihmig = ihmig -jdagres = jdagres -jiangx = jiangx -kaltenbe = kaltenbe -knopp = knopp -kortke = kortke -kouassi = kouassi -laklii = laklii -latif = latif -libchaber = libchaber -linhuang = linhuang -lukashov = lukashov -maatalla = maatalla -maurel = maurel -mayani = mayani -merz = merz -mlaner = mlaner -mosli = mosli -navid = navid -nguyenhn = nguyenhn -nguyennd = nguyennd -nikaeinn = nikaeinn -oai_user1 = oai_user1 -ouni = ouni -paranche = paranche -pburlot = pburlot -qi = qi -renwanz = renwanz -roux = roux -sait = sait -sorby = sorby -steinicke = steinicke -thomas = thomas -thomasl = thomasl -tonelli = tonelli -unlu = unlu -ustun = ustun -villa = villa -wagner = wagner -wangl = wangl -wetterwa = wetterwa -wewior = wewior -winckel = winckel -xuhl = xuhl -yannan = yannan -yilmaz = yilmaz -zayen = zayen -zhou = zhou diff --git a/svn2git/check_diff_author.sh b/svn2git/check_diff_author.sh deleted file mode 100755 index 7d55cfe9a5..0000000000 --- a/svn2git/check_diff_author.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -#The following script checks if the author list changed since the last commits in svn. If it finds difference in author names, then we need to add the author names manually in authors.txt - -wget https://bitbucket.org/atlassian/svn-migration-scripts/downloads/svn-migration-scripts.jar -java -jar ./svn-migration-scripts.jar verify -java -jar ./svn-migration-scripts.jar authors http://svn.eurecom.fr/openair4G > /tmp/authors.txt -diff /tmp/authors.txt ./authors_original_java_output.txt diff --git a/svn2git/git-author-rewrite.sh b/svn2git/git-author-rewrite.sh deleted file mode 100755 index b959db6b2e..0000000000 --- a/svn2git/git-author-rewrite.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -#Script to change author name/email address in git. It throws errors/warnings during the migration -#Copied from, https://help.github.com/articles/changing-author-info/ - -git filter-branch --env-filter ' - -OLD_EMAIL="your-old-email@example.com" -CORRECT_NAME="Your Correct Name" -CORRECT_EMAIL="your-correct-email@example.com" - -if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ] -then - export GIT_COMMITTER_NAME="$CORRECT_NAME" - export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" -fi -if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ] -then - export GIT_AUTHOR_NAME="$CORRECT_NAME" - export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL" -fi -' --tag-name-filter cat -- --branches --tags - diff --git a/ubl b/ubl deleted file mode 100644 index c03ed2e987..0000000000 --- a/ubl +++ /dev/null @@ -1,575 +0,0 @@ -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 0b4726751efb91ec382f2a0cae4da43a8c2b1090 Mon Sep 17 00:00:00 2001 From: Thomas Dreibholz Date: Mon, 10 Feb 2020 13:33:42 +0100 Subject: [PATCH 243/343] Added missing file targets/DOCS/openair_header.tex. --- targets/DOCS/openair_header.tex | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 targets/DOCS/openair_header.tex diff --git a/targets/DOCS/openair_header.tex b/targets/DOCS/openair_header.tex new file mode 100644 index 0000000000..14e1baee5a --- /dev/null +++ b/targets/DOCS/openair_header.tex @@ -0,0 +1,47 @@ +\documentclass[a4paper]{book} +\usepackage{a4wide} +\usepackage{makeidx} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{amsmath} +\usepackage{amssymb} +\ifx\pdfoutput\undefined +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\usepackage{pspicture} +\else +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue + ]{hyperref} +\fi +\usepackage{doxygen} +\usepackage{times} +\makeindex +\setcounter{tocdepth}{1} +\renewcommand{\footrulewidth}{0.4pt} +\begin{document} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Large openair Specifications }\\ +Phyiscal, Medium-Access, Radio-link Control, Packet Data Convergence Protocol and Radio Resource Control Layers\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.3.8}\\ +\vspace*{0.5cm} +{\small Sun Oct 31 19:27:37 2004}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} From ef0aad0de77f96174c2d0f312f2f8ef7e5669dce Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 11 Feb 2020 13:20:26 +0100 Subject: [PATCH 244/343] fixed bug from provious commits --- openair1/PHY/MODULATION/slot_fep_nr.c | 4 ++-- openair1/SCHED_NR/nr_ru_procedures.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 1334c5c99e..d312e78f13 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -145,7 +145,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (abs_symbol%(0x7<numerology_index)) { - rx_offset += nb_prefix_samples0; + rx_offset += nb_prefix_samples; if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short*) &common_vars->rxdata[aa][frame_length_samples], (short*) &common_vars->rxdata[aa][0], @@ -170,7 +170,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } } else { - rx_offset += frame_parms->nb_prefix_samples; + rx_offset += nb_prefix_samples0; if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((void *) &common_vars->rxdata[aa][frame_length_samples], (void *) &common_vars->rxdata[aa][0], diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 1337214cf4..aefeec43e2 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -72,7 +72,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { int abs_first_symbol = slot*fp->symbols_per_slot; for (uint16_t idx_sym=abs_first_symbol; idx_symnumerology_index)) ? fp->nb_prefix_samples0 : fp->nb_prefix_samples; + slot_offset += (idx_sym%(0x7<numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; slot_offset += fp->ofdm_symbol_size*first_symbol; @@ -88,15 +88,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { else { if (fp->numerology_index != 0) { - if (slot%(fp->slots_per_subframe/2)) { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - num_symbols, - fp->nb_prefix_samples, - CYCLIC_PREFIX); - } - else { + if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) { PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, @@ -110,6 +102,14 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { fp->nb_prefix_samples, CYCLIC_PREFIX); } + else { + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + num_symbols, + fp->nb_prefix_samples, + CYCLIC_PREFIX); + } } else { From f8037ab61ecc77a4ea48d9a06d0fd59fd205f777 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 11 Feb 2020 16:31:24 +0100 Subject: [PATCH 245/343] DOC: added link to feature list in README align folder structure in README w/ 5G-NR new folders Signed-off-by: Raphael Defosseux --- README.md | 82 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 0a0f5dee32..7651aea5c9 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Please see [NOTICE](NOTICE.md) file for third party software that is included in # Where to Start # + * [The implemented features](./doc/FEATURE_SET.md) * [How to build](./doc/BUILD.md) * [How to run the modems](./doc/RUNMODEM.md) @@ -22,38 +23,51 @@ The OpenAirInterface (OAI) software is composed of the following parts:
 openairinterface5g
-├── ci-scripts: Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI.
-├── cmake_targets: Build utilities to compile (simulation, emulation and real-time platforms), and generated build files
-├── common : Some common OAI utilities, other tools can be found at openair2/UTILS
-├── doc : Contains an up-to-date feature set list
-├── LICENSE
-├── 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 + LTE Rel-14 M2AP implementation.
-    ├── COMMON
-    ├── DOCS
-    ├── ENB_APP
-    ├── LAYER2/RLC/ with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0. 
-    ├── LAYER2/PDCP/PDCP_v10.1.0.
-    ├── NETWORK_DRIVER
-    ├── PHY_INTERFACE
-    ├── 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
-    ├── UTILS
-└── targets: Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
+├── ci-scripts        : Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI.
+├── cmake_targets     : Build utilities to compile (simulation, emulation and real-time platforms), and generated build files.
+├── common            : Some common OAI utilities, other tools can be found at openair2/UTILS.
+├── doc               : Contains an up-to-date feature set list and starting tutorials.
+├── executables       : Top-level executable source files.
+├── LICENSE           : License file.
+├── 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 / 3GPP NR Rel-15 layer. A local Readme file provides more details.
+│   ├── PHY
+│   ├── SCHED
+│   ├── SCHED_NBIOT
+│   ├── SCHED_NR
+│   ├── SCHED_NR_UE
+│   ├── SCHED_UE
+│   └── SIMULATION    : PHY RF simulation.
+├── openair2          : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP + LTE Rel-14 M2AP implementation. Also 3GPP NR Rel-15 RLC/MAC/PDCP/RRC/X2AP.
+│   ├── COMMON
+│   ├── DOCS
+│   ├── ENB_APP
+│   ├── F1AP
+│   ├── GNB_APP
+│   ├── LAYER2/RLC/   : with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0.
+│   ├── LAYER2/PDCP/PDCP_v10.1.0
+│   ├── M2AP
+│   ├── MCE_APP
+│   ├── NETWORK_DRIVER
+│   ├── NR_PHY_INTERFACE
+│   ├── NR_UE_PHY_INTERFACE
+│   ├── PHY_INTERFACE
+│   ├── RRC
+│   ├── UTIL
+│   └── X2AP
+├── openair3          : 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE.
+│   ├── COMMON
+│   ├── DOCS
+│   ├── GTPV1-U
+│   ├── M3AP
+│   ├── MME_APP
+│   ├── NAS
+│   ├── S1AP
+│   ├── SCTP
+│   ├── SECU
+│   ├── TEST
+│   ├── UDP
+│   └── UTILS
+└── targets           : Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
 
- From 9e6b6ef9650cb5b2a99a154f44a414847eac5e8e Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 11 Feb 2020 18:45:35 +0100 Subject: [PATCH 246/343] nr-ip-ul-nos1: Remove warnings --- cmake_targets/CMakeLists.txt | 1 - openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 8 ++++---- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 3 +-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 8 ++++---- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0699bb08c5..350a2a1f50 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1723,7 +1723,6 @@ 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 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 be504a1587..348774b08a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1076,7 +1076,7 @@ void nr_pusch_codeword_scrambling(uint8_t *in, - transform precoding */ -uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, +void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned char harq_pid, uint8_t frame, uint8_t slot, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 547dd523ca..4360149e60 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -42,6 +42,7 @@ #include "PHY/defs_nr_common.h" #include "PHY/TOOLS/tools_defs.h" #include "executables/nr-softmodem.h" +#include "LAYER2/NR_MAC_UE/mac_proto.h" //#define DEBUG_SCFDMA //#define DEBUG_PUSCH_MAPPING @@ -88,7 +89,7 @@ void nr_pusch_codeword_scrambling(uint8_t *in, } -uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, +void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned char harq_pid, uint8_t frame, uint8_t slot, @@ -205,7 +206,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } //else if(uplink_counter == 0){ //if(!IS_SOFTMODEM_NOS1){ else{ - LOG_E(PHY, "Random data to be tranmsitted: \n"); + LOG_D(PHY, "Random data to be tranmsitted: \n"); for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); @@ -214,7 +215,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } } else { LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); - return 0; + return; } //-----------------------------------------------------// @@ -427,7 +428,6 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, //////////////////////////////////////////////////////////////////////// LOG_D(PHY, "Is data existing ?: %d \n", data_existing); - return data_existing; } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 6282e81066..1b62cb8731 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2483,9 +2483,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, #endif uint8_t harq_pid = 0; //temporary implementation - uint8_t data_existing = 0; - data_existing = nr_ue_ulsch_procedures(ue, + nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 02749a70dd..bfbec72981 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -43,6 +43,7 @@ #include #include +//int mbms_rab_id = 2047; //#define ENABLE_MAC_PAYLOAD_DEBUG 1 @@ -2482,7 +2483,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { - uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; + uint8_t total_rlc_pdu_header_len = 0; int16_t buflen_remain = 0; uint8_t lcid = 0; uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -2490,8 +2491,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, uint16_t payload_offset = 0, num_sdus = 0; uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; uint16_t sdu_length_total = 0; - unsigned short post_padding = 0, padding_len = 0; - int j; // used for padding + unsigned short post_padding = 0; rlc_buffer_occupancy_t lcid_buffer_occupancy_old = 0, lcid_buffer_occupancy_new = 0; @@ -2504,7 +2504,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); #endif - NR_UE_MAC_INST_t *nr_ue_mac_inst = get_mac_inst(0); + //NR_UE_MAC_INST_t *nr_ue_mac_inst = get_mac_inst(0); // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 4a8602d272..99f893506f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -561,7 +561,7 @@ void nr_process_mac_pdu( // This function is adapting code from the old // parse_header(...) and ue_send_sdu(...) functions of OAI LTE - uint8_t *pdu_ptr = pduP, rx_lcid, done = 0, i; + uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; int pdu_len = mac_pdu_len; uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; From 9a91fe96c316a670974cf7cf9714eadd14c411b7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 12 Feb 2020 10:12:58 +0100 Subject: [PATCH 247/343] update configuration file for gnb band 78 106 PRBs --- .../gnb.band78.106PRB.30kHz,usrpb2x0.conf | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf index 033ceef40c..ff8e261783 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf @@ -21,19 +21,19 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; + ssb_SubcarrierOffset = 31; pdsch_AntennaPorts = 1; servingCellConfigCommon = ( { #spCellConfigCommon - physCellId = 0; + physCellId = 10; # downlinkConfigCommon #frequencyInfoDL # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) - absoluteFrequencySSB = 642016; + absoluteFrequencySSB = 641272; dl_frequencyBand = 78; # this is 3600 MHz dl_absoluteFrequencyPointA = 640000; @@ -46,12 +46,12 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 3384; + initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPcontrolResourceSetZero = 0; initialDLBWPsearchSpaceZero = 0; #pdsch-ConfigCommon #pdschTimeDomainAllocationList (up to 16 entries) @@ -83,7 +83,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 3384; + initialULBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -103,10 +103,10 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 5; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,9 +114,9 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; - prach_RootSequenceIndex = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 0; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # msg1_SubcarrierSpacing = 1, @@ -199,6 +199,17 @@ gNBs = } ); + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.12.196"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + NETWORK_INTERFACES : { @@ -207,6 +218,8 @@ gNBs = GNB_INTERFACE_NAME_FOR_S1U = "eth0"; GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); From 295923d540f0f303a5b528cd77496ea79d134bd3 Mon Sep 17 00:00:00 2001 From: matzakos Date: Wed, 12 Feb 2020 17:58:06 +0100 Subject: [PATCH 248/343] nr-ip-ul-nos1: Logs cleanup and some code rearrangement --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 11 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 229 ------------------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 196 +++++++++++++++ openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 2 +- 4 files changed, 199 insertions(+), 239 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 72daf0ee39..2df700e031 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -51,8 +51,6 @@ #include "executables/softmodem-common.h" /* log utils */ #include "common/utils/LOG/log.h" -//#include "openair2/LAYER2/MAC/mac.h" -//#include "openair2/LAYER2/RLC/rlc.h" #include "SIMULATION/TOOLS/sim.h" // for taus #include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -2426,7 +2424,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, uint16_t payload_offset = 0, num_sdus = 0; uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; uint16_t sdu_length_total = 0; - unsigned short post_padding = 0; + //unsigned short post_padding = 0; rlc_buffer_occupancy_t lcid_buffer_occupancy_old = 0, lcid_buffer_occupancy_new = 0; @@ -2527,11 +2525,6 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, } else return 0; - LOG_D(MAC, - "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, post_padding %d, remainder %d \n", - module_idP, buflen, sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], payload_offset, total_rlc_pdu_header_len, - post_padding, buflen - sdu_length_total - payload_offset); // Padding: fill remainder of ULSCH with 0 if (buflen - payload_offset > 0){ @@ -2540,7 +2533,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing UL MAC payload without the header UE side, payload_offset: %d \n", payload_offset); + LOG_I(MAC, "Printing UL MAC payload UE side, payload_offset: %d \n", payload_offset); for (int i = 0; i < buflen ; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 50de63c11c..03795a8c09 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -532,232 +532,3 @@ void nr_schedule_uss_ulsch_phytest(nfapi_nr_ul_tti_request_t *UL_tti_req, } } -void nr_process_mac_pdu( - module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - uint8_t *pduP, - uint16_t mac_pdu_len) -{ - - // This function is adapting code from the old - // parse_header(...) and ue_send_sdu(...) functions of OAI LTE - - uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; - int pdu_len = mac_pdu_len; - uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; - - - // For both DL/UL-SCH - // Except: - // - UL/DL-SCH: fixed-size MAC CE(known by LCID) - // - UL/DL-SCH: padding - // - UL-SCH: MSG3 48-bits - // |0|1|2|3|4|5|6|7| bit-wise - // |R|F| LCID | - // | L | - // |0|1|2|3|4|5|6|7| bit-wise - // |R|F| LCID | - // | L | - // | L | - - // For both DL/UL-SCH - // For: - // - UL/DL-SCH: fixed-size MAC CE(known by LCID) - // - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) - // - UL-SCH: MSG3 48-bits - // |0|1|2|3|4|5|6|7| bit-wise - // |R|R| LCID | - // LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; - // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; - // F: lenght of L is 0:8 or 1:16 bits wide - // R: Reserved bit, set to zero. - - while (!done && pdu_len > 0){ - mac_ce_len = 0; - mac_subheader_len = 1; // default to fixed-length subheader = 1-oct - mac_sdu_len = 0; - rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; - - LOG_D(MAC, "LCID received at gNB side: %d \n", rx_lcid); - - switch(rx_lcid){ - // MAC CE - - /*#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); - #endif*/ - - case UL_SCH_LCID_S_BSR: - //38.321 section 6.1.3.1 - //fixed length - mac_ce_len =1; - /* Extract short BSR value */ - break; - - case UL_SCH_LCID_S_TRUNCATED_BSR: - //38.321 section 6.1.3.1 - //fixed length - mac_ce_len =1; - /* Extract short truncated BSR value */ - break; - - case UL_SCH_LCID_L_BSR: - //38.321 section 6.1.3.1 - //variable length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - } - /* Extract long BSR value */ - break; - - case UL_SCH_LCID_L_TRUNCATED_BSR: - //38.321 section 6.1.3.1 - //variable length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - } - /* Extract long truncated BSR value */ - break; - - - case UL_SCH_LCID_C_RNTI: - //38.321 section 6.1.3.2 - //fixed length - mac_ce_len = 2; - /* Extract CRNTI value */ - break; - - case UL_SCH_LCID_SINGLE_ENTRY_PHR: - //38.321 section 6.1.3.8 - //fixed length - mac_ce_len = 2; - /* Extract SINGLE ENTRY PHR elements for PHR calculation */ - break; - - case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: - //38.321 section 6.1.3.9 - // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - } - /* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */ - break; - - case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT: - //38.321 section 6.1.3.9 - // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - } - /* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */ - break; - - case UL_SCH_LCID_PADDING: - done = 1; - // end of MAC PDU, can ignore the rest. - break; - - case UL_SCH_LCID_DTCH: - // check if LCID is valid at current time. - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) - | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); - - } else { - mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - } - - LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); - - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - - for (i = 0; i < 32; i++) - LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); - - LOG_T(MAC, "\n"); - #endif - - if (IS_SOFTMODEM_NOS1){ - if (rx_lcid < NB_RB_MAX && rx_lcid >= UL_SCH_LCID_DTCH) { - - mac_rlc_data_ind(module_idP, - 0x1234, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), - mac_sdu_len, - 1, - NULL); - } else { - LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, module_idP); - } - } - - break; - - default: - return; - break; - } - pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); - pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); - - AssertFatal(pdu_len >= 0, "[MAC] nr_process_mac_pdu, residual mac pdu length < 0!\n"); - } -} - -/*void nr_rx_sdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - uint8_t ttiP, - const rnti_t rntiP, - uint8_t * pdu, - const uint16_t pdu_len, - const uint16_t timing_advance, - const uint8_t ul_cqi) -{ - - LOG_D(MAC, "Handling PDU frame %d slot %d pdu_len: %d \n", frameP, ttiP, pdu_len); - - uint8_t * pduP = pdu; - - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n"); - for (int i = 0; i < pdu_len ; i++) { - //harq_process_ul_ue->a[i] = (unsigned char) rand(); - //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - printf("%02x ",(unsigned char)pduP[i]); - } - printf("\n"); -#endif - - // Processing MAC PDU - // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - if (pduP != NULL){ - LOG_D(MAC, "Received PDU at MAC gNB \n"); - nr_process_mac_pdu(module_idP, CC_id, frameP, pduP, pdu_len); - } - -}*/ - diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index c6f1520671..95ae4a8e30 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -29,6 +29,202 @@ */ #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "executables/softmodem-common.h" +//#define ENABLE_MAC_PAYLOAD_DEBUG 1 + +void nr_process_mac_pdu( + module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t *pduP, + uint16_t mac_pdu_len) +{ + + // This function is adapting code from the old + // parse_header(...) and ue_send_sdu(...) functions of OAI LTE + + uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; + int pdu_len = mac_pdu_len; + uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; + + + // For both DL/UL-SCH + // Except: + // - UL/DL-SCH: fixed-size MAC CE(known by LCID) + // - UL/DL-SCH: padding + // - UL-SCH: MSG3 48-bits + // |0|1|2|3|4|5|6|7| bit-wise + // |R|F| LCID | + // | L | + // |0|1|2|3|4|5|6|7| bit-wise + // |R|F| LCID | + // | L | + // | L | + + // For both DL/UL-SCH + // For: + // - UL/DL-SCH: fixed-size MAC CE(known by LCID) + // - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) + // - UL-SCH: MSG3 48-bits + // |0|1|2|3|4|5|6|7| bit-wise + // |R|R| LCID | + // LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; + // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; + // F: lenght of L is 0:8 or 1:16 bits wide + // R: Reserved bit, set to zero. + + while (!done && pdu_len > 0){ + mac_ce_len = 0; + mac_subheader_len = 1; // default to fixed-length subheader = 1-oct + mac_sdu_len = 0; + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + + LOG_D(MAC, "LCID received at gNB side: %d \n", rx_lcid); + + switch(rx_lcid){ + // MAC CE + + /*#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); + #endif*/ + + case UL_SCH_LCID_S_BSR: + //38.321 section 6.1.3.1 + //fixed length + mac_ce_len =1; + /* Extract short BSR value */ + break; + + case UL_SCH_LCID_S_TRUNCATED_BSR: + //38.321 section 6.1.3.1 + //fixed length + mac_ce_len =1; + /* Extract short truncated BSR value */ + break; + + case UL_SCH_LCID_L_BSR: + //38.321 section 6.1.3.1 + //variable length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract long BSR value */ + break; + + case UL_SCH_LCID_L_TRUNCATED_BSR: + //38.321 section 6.1.3.1 + //variable length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract long truncated BSR value */ + break; + + + case UL_SCH_LCID_C_RNTI: + //38.321 section 6.1.3.2 + //fixed length + mac_ce_len = 2; + /* Extract CRNTI value */ + break; + + case UL_SCH_LCID_SINGLE_ENTRY_PHR: + //38.321 section 6.1.3.8 + //fixed length + mac_ce_len = 2; + /* Extract SINGLE ENTRY PHR elements for PHR calculation */ + break; + + case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: + //38.321 section 6.1.3.9 + // varialbe length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */ + break; + + case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT: + //38.321 section 6.1.3.9 + // varialbe length + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + } + /* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */ + break; + + case UL_SCH_LCID_PADDING: + done = 1; + // end of MAC PDU, can ignore the rest. + break; + + case UL_SCH_LCID_DTCH: + // check if LCID is valid at current time. + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); + + } else { + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + } + + LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); + + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + + for (i = 0; i < 32; i++) + LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); + + LOG_T(MAC, "\n"); + #endif + + if (IS_SOFTMODEM_NOS1){ + if (rx_lcid < NB_RB_MAX && rx_lcid >= UL_SCH_LCID_DTCH) { + + mac_rlc_data_ind(module_idP, + 0x1234, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + } else { + LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, module_idP); + } + } + + break; + + default: + return; + break; + } + pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + + AssertFatal(pdu_len >= 0, "[MAC] nr_process_mac_pdu, residual mac pdu length < 0!\n"); + } +} /* diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 71fffa84fb..3ca64f9648 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -193,7 +193,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } else { - LOG_I(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok), received length: %d \n",UL_info->frame,UL_info->slot, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length); + LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok), received length: %d \n",UL_info->frame,UL_info->slot, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length); nr_rx_sdu(UL_info->module_id, UL_info->CC_id, NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, From 6014ca42ac136151d77787a1372fff84e651e0f5 Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 12 Feb 2020 19:05:44 +0100 Subject: [PATCH 249/343] ENABLE_ITTI macro removal, modified telnet server to support all executables, modified record player to finalize switch to run-time option and allow usage with any device --- cmake_targets/CMakeLists.txt | 26 +- common/utils/LOG/log.h | 10 - common/utils/LOG/vcd_signal_dumper.c | 5 - common/utils/T/local_tracer.c | 18 +- common/utils/telnetsrv/telnetsrv.c | 17 +- common/utils/telnetsrv/telnetsrv.h | 2 +- .../telnetsrv/telnetsrv_enb_measurements.c | 179 ++ common/utils/telnetsrv/telnetsrv_enb_phycmd.c | 123 ++ executables/nr-gnb.c | 8 +- executables/nr-softmodem-common.h | 6 +- executables/nr-softmodem.c | 32 +- executables/nr-uesoftmodem.c | 6 +- executables/softmodem-common.c | 25 +- executables/softmodem-common.h | 18 +- openair1/PHY/LTE_TRANSPORT/pucch.c | 21 +- openair1/SCHED/prach_procedures.c | 4 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 10 +- openair1/SCHED_UE/phy_procedures_lte_ue.c | 13 +- openair2/GNB_APP/gnb_paramdef.h | 2 - openair2/LAYER2/MAC/eNB_scheduler.c | 4 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 45 +- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 4 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 4 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 4 - .../LAYER2/MAC/eNB_scheduler_primitives.c | 11 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 4 +- openair2/LAYER2/MAC/ue_procedures.c | 9 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 - .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 2 - .../NR_MAC_gNB/gNB_scheduler_primitives.c | 2 - openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c | 40 +- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 4 +- openair2/RRC/LTE/L2_interface.c | 4 +- openair2/RRC/LTE/L2_interface_common.c | 12 +- openair2/RRC/LTE/L2_interface_ue.c | 66 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 398 +--- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 12 +- openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c | 64 +- openair2/RRC/LTE/rrc_eNB.c | 23 +- openair2/RRC/LTE/rrc_eNB_GTPV1U.c | 12 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 7 +- openair2/RRC/NR/L2_nr_interface.c | 4 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 46 +- openair2/RRC/NR/MESSAGES/asn1_msg.h | 8 +- openair2/RRC/NR/nr_rrc_config.c | 8 +- openair2/RRC/NR/nr_rrc_config.h | 8 +- openair2/RRC/NR/nr_rrc_defs.h | 12 +- openair2/RRC/NR/nr_rrc_proto.h | 2 - openair2/RRC/NR/rrc_gNB.c | 50 +- openair2/UTIL/LOG/log.c | 1832 ----------------- openair3/NAS/COMMON/UTIL/nas_timer.c | 121 +- openair3/NAS/UE/ESM/PdnConnectivity.c | 2 - openair3/NAS/UE/nas_ue_task.c | 2 - openair3/NAS/UE/nas_ue_task.h | 2 - targets/ARCH/COMMON/common_lib.c | 62 +- targets/ARCH/COMMON/common_lib.h | 37 +- targets/ARCH/COMMON/record_player.c | 115 ++ .../LIB/usrp_lib.h => COMMON/record_player.h} | 63 +- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 983 ++++----- .../ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c | 73 - targets/ARCH/iqplayer/iqplayer_lib.c | 307 +++ targets/COMMON/create_nr_tasks.h | 2 - targets/COMMON/create_tasks.h | 2 - targets/COMMON/create_tasks_mbms.h | 2 - targets/RT/USER/lte-softmodem.c | 2 +- targets/RT/USER/lte-uesoftmodem.c | 15 +- 67 files changed, 1408 insertions(+), 3614 deletions(-) create mode 100644 common/utils/telnetsrv/telnetsrv_enb_measurements.c create mode 100644 common/utils/telnetsrv/telnetsrv_enb_phycmd.c delete mode 100644 openair2/UTIL/LOG/log.c create mode 100644 targets/ARCH/COMMON/record_player.c rename targets/ARCH/{USRP/USERSPACE/LIB/usrp_lib.h => COMMON/record_player.h} (81%) delete mode 100644 targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c create mode 100644 targets/ARCH/iqplayer/iqplayer_lib.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index bb7cc25ec0..01b1d6c273 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -247,22 +247,18 @@ add_boolean_option(T_TRACER True "Activate the T tracer, a debugging add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs") add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") -add_boolean_option(USRP_REC_PLAY False "Enable USRP record playback mode") -add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the basic simulator, False otherwise") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") -add_boolean_option(ENABLE_ITTI True "ITTI is internal messaging, should remain enabled for most targets") set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) -if (${ENABLE_ITTI}) - add_library(ITTI - ${OCP_ITTI}/intertask_interface.cpp - ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/memory_pools.c - ) +add_library(ITTI + ${OCP_ITTI}/intertask_interface.cpp + ${OPENAIR_DIR}/common/utils/backtrace.c + ${OPENAIR_DIR}/common/utils/memory_pools.c + ) add_dependencies(ITTI rrc_flag) set(ITTI_LIB ITTI) set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c) -endif (${ENABLE_ITTI}) + ################################################## # ASN.1 grammar C code generation & dependencies # @@ -660,7 +656,6 @@ 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) @@ -2369,6 +2364,9 @@ add_library(rfsimulator MODULE ) target_link_libraries(rfsimulator SIMU ${ATLAS_LIBRARIES}) +add_library(oai_iqplayer MODULE + ${OPENAIR_TARGETS}/ARCH/iqplayer/iqplayer_lib.c + ) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") #include T directory even if the T is off because T macros are in the code @@ -2448,6 +2446,7 @@ add_executable(lte-softmodem ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2462,7 +2461,7 @@ add_executable(lte-softmodem ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} ) -add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) +add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) target_link_libraries (lte-softmodem -Wl,--start-group @@ -2517,6 +2516,7 @@ add_executable(lte-uesoftmodem ${OPENAIR_TARGETS}/RT/USER/rfsim.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2563,6 +2563,7 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2602,6 +2603,7 @@ add_executable(nr-uesoftmodem ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 6baec7dfeb..8e74f4148c 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -274,16 +274,6 @@ typedef struct { } log_t; -#if defined(ENABLE_ITTI) -typedef enum log_instance_type_e { - LOG_INSTANCE_UNKNOWN, - LOG_INSTANCE_ENB, - LOG_INSTANCE_UE, -} log_instance_type_t; - -void log_set_instance_type (log_instance_type_t instance); -#endif - #ifdef LOG_MAIN log_t *g_log; diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 103cf1cd94..9327b6e77a 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -633,9 +633,6 @@ inline static uint32_t vcd_get_write_index(void) return write_index; } -#if defined(ENABLE_ITTI) -int signal_mask(void); -#endif void *vcd_dumper_thread_rt(void *args) { @@ -644,9 +641,7 @@ void *vcd_dumper_thread_rt(void *args) struct sched_param sched_param; uint32_t data_ready_wait; -# if defined(ENABLE_ITTI) return 0; //signal_mask(); //function defined at common/utils/ocp_itti/intertask_interface.cpp -# endif sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1; sched_setscheduler(0, SCHED_FIFO, &sched_param); diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index 4be0b35d16..8cbd06490d 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -15,7 +15,7 @@ #include "T_messages.txt.h" #include "T_defs.h" #include "T_IDs.h" - +#include "softmodem-common.h" static T_cache_t *T_local_cache; static int T_busylist_head; @@ -357,24 +357,22 @@ static void forward(void *_forwarder, char *buf, int size) { if (f->tail != NULL) f->tail->next = new; f->tail = new; -#if BASIC_SIMULATOR - + if( IS_SOFTMODEM_BASICSIM){ /* When runnng the basic simulator, the tracer may be too slow. * Let's not take too much memory in the tracee and * wait if there is too much data to send. 200MB is * arbitrary. */ - while (f->memusage > 200 * 1024 * 1024) { - if (pthread_cond_signal(&f->cond)) abort(); + while (f->memusage > 200 * 1024 * 1024) { + if (pthread_cond_signal(&f->cond)) abort(); - if (pthread_mutex_unlock(&f->lock)) abort(); + if (pthread_mutex_unlock(&f->lock)) abort(); - usleep(1000); + usleep(1000); - if (pthread_mutex_lock(&f->lock)) abort(); + if (pthread_mutex_lock(&f->lock)) abort(); + } } - -#endif /* BASIC_SIMULATOR */ f->memusage += size+4; /* warn every 100MB */ diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 6626c8103b..10163b22b5 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -53,6 +53,7 @@ #include #include "common/utils/load_module_shlib.h" #include "common/config/config_userapi.h" +#include "executables/softmodem-common.h" #include @@ -546,6 +547,7 @@ void run_telnetsrv(void) { int readc, filled; int status; int optval = 1; + char prompt[sizeof(TELNET_PROMPT_PREFIX)+10]; pthread_setname_np(pthread_self(), "telnet"); set_sched(pthread_self(),0,telnetparams.priority); sock = socket(AF_INET, SOCK_STREAM, 0); @@ -570,6 +572,7 @@ void run_telnetsrv(void) { fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno)); using_history(); + int plen=sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL)); printf("\nInitializing telnet server...\n"); while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) { @@ -613,9 +616,9 @@ void run_telnetsrv(void) { HIST_ENTRY *hisentry = history_get(strtol(buf+1,NULL,0)); if (hisentry) { - char msg[TELNET_MAX_MSGLENGTH + sizeof(TELNET_PROMPT) +10]; + char msg[TELNET_MAX_MSGLENGTH + plen +10]; sprintf(buf,"%s",hisentry->line); - sprintf(msg,"%s %s\n",TELNET_PROMPT, hisentry->line); + sprintf(msg,"%s %s\n",prompt, hisentry->line); send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); } } @@ -635,7 +638,7 @@ void run_telnetsrv(void) { add_history(buf); } - send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL); + send(telnetparams.new_socket, prompt, strlen(prompt), MSG_NOSIGNAL); } else { printf ("[TELNETSRV] Closing telnet connection...\n"); break; @@ -653,7 +656,7 @@ void run_telnetsrv(void) { } /*------------------------------------------------------------------------------------------------*/ -/* set_telnetmodule loads the commands delivered with the telnet server +/* load the commands delivered with the telnet server * * * @@ -715,7 +718,11 @@ int add_sharedmodules(void) { int telnetsrv_autoinit(void) { memset(&telnetparams,0,sizeof(telnetparams)); config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),"telnetsrv"); - + /* possibly load a exec specific shared lib */ + char *execfunc=get_softmodem_function(NULL); + char libname[64]; + sprintf(libname,"telnetsrv_%s",execfunc); + load_module_shlib(libname,NULL,0,NULL); if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0) { fprintf(stderr,"[TELNETSRV] Error %s on pthread_create call\n",strerror(errno)); return -1; diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index 89f6a8dda1..debb9f02ec 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -35,7 +35,7 @@ #define TELNET_PORT 9090 #define TELNET_MAX_MSGLENGTH 2048 -#define TELNET_PROMPT "softmodem> " +#define TELNET_PROMPT_PREFIX "softmodem" #define TELNET_MAXCMD 20 #define TELNET_CMD_MAXSIZE 20 #define TELNET_HELPSTR_SIZE 80 diff --git a/common/utils/telnetsrv/telnetsrv_enb_measurements.c b/common/utils/telnetsrv/telnetsrv_enb_measurements.c new file mode 100644 index 0000000000..9c5c5b675b --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_enb_measurements.c @@ -0,0 +1,179 @@ +/* + * 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 common/utils/telnetsrv/telnetsrv_measurements.c + * \brief: implementation of telnet commands related to eNB measurments + * \author Francois TABURET + * \date 2019 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + + + + +#define TELNETSERVERCODE +#include "telnetsrv.h" + +#include "common/utils/LOG/log.h" +#include "common/config/config_userapi.h" +#include "telnetsrv_measurements.h" +#include "telnetsrv_ltemeasur_def.h" +#include "telnetsrv_cpumeasur_def.h" +#include "openair2/LAYER2/MAC/mac.h" +#include "openair1/PHY/phy_extern.h" + +void measurcmd_display_macstats(telnet_printfunc_t prnt); +void measurcmd_display_macstats_ue(telnet_printfunc_t prnt); +void measurcmd_display_rlcstats(telnet_printfunc_t prnt); +void measurcmd_display_phycpu(telnet_printfunc_t prnt); +void measurcmd_display_maccpu(telnet_printfunc_t prnt); +void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt); + + +static telnet_measurgroupdef_t enbmeasurgroups[] = { + {"enb", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}}, + {"enbues",GROUP_LTESTATS,0, measurcmd_display_macstats_ue,{NULL}}, + {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}}, + {"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}}, + {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}}, + {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}}, +}; +#define TELNET_NUM_ENBMEASURGROUPS (sizeof(enbmeasurgroups)/sizeof(telnet_measurgroupdef_t)) + +static int eNB_id =0; +static double cpufreq; + + +#define HDR "---------------------------------" + + +int get_measurgroups(telnet_measurgroupdef_t **measurgroups) { + *measurgroups = enbmeasurgroups; + return TELNET_NUM_ENBMEASURGROUPS; +} + + +void measurcmd_display_phycpu(telnet_printfunc_t prnt) { + PHY_VARS_eNB *phyvars = RC.eNB[eNB_id][0]; + telnet_cpumeasurdef_t cpumeasur[]=CPU_PHYENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: PHY (cpustats %s) %s\n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} + +void measurcmd_display_maccpu(telnet_printfunc_t prnt) { + eNB_MAC_INST *macvars = RC.mac[eNB_id]; + telnet_cpumeasurdef_t cpumeasur[]=CPU_MACENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: MAC (cpustats %s) %s\n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} + +void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt) { + pdcp_stats_t *pdcpvars = &(eNB_pdcp_stats[eNB_id]); + telnet_cpumeasurdef_t cpumeasur[]=CPU_PDCPENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: PDCP (cpustats %s) %s \n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} +/*----------------------------------------------------------------------------------------------------*/ + + +void measurcmd_display_macstats_ue(telnet_printfunc_t prnt) { + UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list); + + for (int UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + for (int i=0; inumactiveCCs[UE_id]; i++) { + int CC_id = UE_list->ordered_CCids[i][UE_id]; + prnt("%s UE %i Id %i CCid %i %s\n",HDR,i,UE_id,CC_id,HDR); + eNB_UE_STATS *macuestatptr = &(UE_list->eNB_UE_stats[CC_id][UE_id]); + telnet_ltemeasurdef_t statsptr[]=LTEMAC_UEMEASURE; + measurcmd_display_measures(prnt, statsptr, sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); + } + } +} /* measurcmd_display_macstats_ue */ + +void measurcmd_display_macstats(telnet_printfunc_t prnt) { + for (int CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) { + eNB_STATS *macstatptr=&(RC.mac[eNB_id]->eNB_stats[CC_id]); + telnet_ltemeasurdef_t statsptr[]=LTEMAC_MEASURE; + prnt("%s eNB %i mac stats CC %i frame %u %s\n", + HDR, eNB_id, CC_id, RC.mac[eNB_id]->frame,HDR); + measurcmd_display_measures(prnt,statsptr,sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); + } +} /* measurcmd_display_macstats */ + + +void measurcmd_display_one_rlcstat(telnet_printfunc_t prnt, int UE_id, telnet_ltemeasurdef_t *statsptr, int num_rlcmeasure, unsigned int *rlcstats, + char *rbid_str, protocol_ctxt_t *ctxt, const srb_flag_t srb_flagP, const rb_id_t rb_idP) + +{ + int rlc_status = rlc_stat_req(ctxt,srb_flagP,rb_idP, + rlcstats, rlcstats+1, rlcstats+2, rlcstats+3, rlcstats+4, rlcstats+5, + rlcstats+6, rlcstats+7, rlcstats+8, rlcstats+9, rlcstats+10, rlcstats+11, + rlcstats+12, rlcstats+13, rlcstats+14, rlcstats+15, rlcstats+16, rlcstats+17, + rlcstats+18, rlcstats+19, rlcstats+20, rlcstats+21, rlcstats+22, rlcstats+23, + rlcstats+24, rlcstats+25, rlcstats+26, rlcstats+27); + + if (rlc_status == RLC_OP_STATUS_OK) { + prnt("%s UE %i RLC %s mode %s %s\n",HDR,UE_id, rbid_str, + (rlcstats[0]==RLC_MODE_AM)? "AM": (rlcstats[0]==RLC_MODE_UM)?"UM":"NONE",HDR); + measurcmd_display_measures(prnt, statsptr, num_rlcmeasure); + } +} /* status measurcmd_rlc_stat_req */ + + +void measurcmd_display_rlcstats(telnet_printfunc_t prnt) { + protocol_ctxt_t ctxt; + UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list); + telnet_ltemeasurdef_t statsptr[]=LTE_RLCMEASURE; + int num_rlcmeasure = sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t ); + unsigned int *rlcstats = malloc(num_rlcmeasure*sizeof(unsigned int)); + eNB_MAC_INST *eNB = RC.mac[eNB_id]; + + for(int i=0; i head; UE_id>=0; UE_id=UE_list->next[UE_id]) { +#define NB_eNB_INST 1 + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_list->eNB_UE_stats[0][UE_id].crnti, + eNB->frame,eNB->subframe,eNB_id); + measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH); + measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DTCH", &ctxt, SRB_FLAG_NO, DTCH-2); + } +} /* measurcmd_display_macstats_ue */ + + + + diff --git a/common/utils/telnetsrv/telnetsrv_enb_phycmd.c b/common/utils/telnetsrv/telnetsrv_enb_phycmd.c new file mode 100644 index 0000000000..f7deec1801 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_enb_phycmd.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 common/utils/telnetsrv/telnetsrv_phycmd.c + * \brief: implementation of telnet commands related to softmodem linux process + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include +#include + + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_PHYCMD_MAIN +#include "telnetsrv_phycmd.h" +char *prnbuff; +extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char *buffer, int length); + +void init_phytelnet(void) { + prnbuff=malloc(get_phybsize() ); + + if (prnbuff == NULL) { + fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno)); + } +} + +void display_uestatshead( telnet_printfunc_t prnt) { + prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n"); +} + +void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag) { + int p; + p=dump_eNB_l2_stats( prnbuff, 0); + + if(prntflag>=1) + prnt("%s\n",prnbuff); + + if(debug>=1) + prnt("%i bytes printed\n",p); +} + +void display_uestats(int debug, telnet_printfunc_t prnt, int ue) { + for (int cc=0; cc<1 ; cc++) { + } +} + +void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt) { + prnt(" DLSCH kb DLSCH kb/s\n"); + dump_uestats(debug, prnt,0); +} + +int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) { + if (debug > 0) + prnt("phy interface module received %s\n",buf); + + if (strcasestr(buf,"phycnt") != NULL) { + display_phycounters(buf, debug, prnt); + } + + if (strcasestr(buf,"uestat") != NULL) { + char *cptr=strcasestr(buf+sizeof("uestat"),"UE"); + display_uestatshead(prnt); + + if (cptr != NULL) { + int ueidx = strtol( cptr+sizeof("UE"), NULL, 10); + + if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0) { + display_uestats(debug, prnt,ueidx); + } + } /* if cptr != NULL */ + else { + for (int ue=0; ue]", dump_phyvars}, + + {"","",NULL}, +}; + + +/*-------------------------------------------------------------------------------------*/ +void add_phy_cmds(void) { + init_phytelnet(); + add_telnetcmd("phy", phy_vardef, phy_cmdarray); +} diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 46689b137a..fc012b0ab2 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -93,10 +93,8 @@ // extern openair0_device openair0; -#if defined(ENABLE_ITTI) - extern volatile int start_gNB; - extern volatile int start_UE; -#endif +extern volatile int start_gNB; +extern volatile int start_UE; extern volatile int oai_exit; extern openair0_config_t openair0_cfg[MAX_CARDS]; @@ -360,7 +358,7 @@ static void *gNB_L1_thread( void *param ) { } -#if 0 //defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) +#if 0 // Wait for gNB application initialization to be complete (gNB registration to MME) static void wait_system_ready (char *message, volatile int *start_flag) { static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index e014eaf93f..e6aafafeb9 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -142,9 +142,7 @@ extern int sync_var; extern int transmission_mode; extern double cpuf; -#if defined(ENABLE_ITTI) - extern volatile int start_eNB; - extern volatile int start_UE; -#endif +extern volatile int start_eNB; +extern volatile int start_UE; #endif diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 6b72562033..d8cb4da267 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -71,9 +71,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "UTIL/OTG/otg_vars.h" #endif -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "PHY/INIT/phy_init.h" @@ -101,9 +99,7 @@ pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; -#if defined(ENABLE_ITTI) - volatile int start_gNB = 0; -#endif +volatile int start_gNB = 0; volatile int oai_exit = 0; static int wait_for_sync = 0; @@ -119,9 +115,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; //Temp fix for inexistent NR upper layer unsigned char NB_gNB_INST = 1; -#if defined(ENABLE_ITTI) - static char *itti_dump_file = NULL; -#endif +static char *itti_dump_file = NULL; int UE_scan = 1; int UE_scan_carrier = 0; @@ -302,7 +296,7 @@ void exit_function(const char *file, const char *function, const int line, const exit(1); } -#if defined(ENABLE_ITTI) + void *l2l1_task(void *arg) { MessageDef *message_p = NULL; int result; @@ -375,7 +369,6 @@ void *l2l1_task(void *arg) { */ return NULL; } -#endif int create_gNB_tasks(uint32_t gnb_nb) { LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); @@ -638,7 +631,6 @@ void wait_gNBs(void) { printf("gNB L1 are configured\n"); } -#if defined(ENABLE_ITTI) /* * helper function to terminate a certain ITTI task */ @@ -756,7 +748,6 @@ int restart_L1L2(module_id_t gnb_id) { pthread_mutex_unlock(&sync_mutex); return 0; } -#endif static void wait_nfapi_init(char *thread_name) { printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); @@ -814,7 +805,7 @@ int main( int argc, char **argv ) configure_linux(); printf("Reading in command-line options\n"); get_options (); - get_common_options(); + get_common_options(SOFTMODEM_GNB_BIT ); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); @@ -835,11 +826,10 @@ int main( int argc, char **argv ) } cpuf=get_cpu_freq_GHz(); -#if defined(ENABLE_ITTI) itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); // initialize mscgen log after ITTI MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); -#endif + init_opt(); @@ -859,8 +849,6 @@ init_opt(); if(IS_SOFTMODEM_NOS1) init_pdcp(); -#if defined(ENABLE_ITTI) - if (RC.nb_nr_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n"); @@ -869,7 +857,6 @@ init_opt(); RCconfig_L1(); } -#endif /* Start the agent. If it is turned off in the configuration, it won't start */ RCconfig_nr_flexran(); @@ -1004,19 +991,12 @@ init_opt(); // wait for end of program printf("TYPE TO TERMINATE\n"); //getchar(); -#if defined(ENABLE_ITTI) printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); printf("Returned from ITTI signal handler\n"); oai_exit=1; printf("oai_exit=%d\n",oai_exit); -#else - while (oai_exit==0) - sleep(1); - - printf("Terminating application - oai_exit=%d\n",oai_exit); -#endif // stop threads /*#ifdef XFORMS diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 1781ed0d8d..de01240537 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -332,8 +332,6 @@ void init_scope(void) { } - -#if defined(ENABLE_ITTI) void *l2l1_task(void *arg) { MessageDef *message_p = NULL; int result; @@ -373,7 +371,7 @@ void *l2l1_task(void *arg) { return NULL; } -#endif + int16_t dlsch_demod_shift; @@ -650,7 +648,7 @@ int main( int argc, char **argv ) { logInit(); // get options and fill parameters from configuration file get_options (); //Command-line options, enb_properties - get_common_options(); + get_common_options(SOFTMODEM_5GUE_BIT ); #if T_TRACER T_Config_Init(); #endif diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 00b974e3ae..0c4032c41b 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -37,6 +37,7 @@ #include "common/utils/load_module_shlib.h" #include "common/utils/telnetsrv/telnetsrv.h" #include "executables/thread-common.h" +#include "common/utils/LOG/log.h" #include "softmodem-common.h" static softmodem_params_t softmodem_params; @@ -44,7 +45,7 @@ char *parallel_config=NULL; char *worker_config=NULL; - +static mapping softmodem_funcs[] = MAPPING_SOFTMODEM_FUNCTIONS; static struct timespec start; uint64_t get_softmodem_optmask(void) { @@ -60,7 +61,26 @@ softmodem_params_t *get_softmodem_params(void) { return &softmodem_params; } -void get_common_options(void) { +int32_t check_execmask(uint64_t execmask) { + char *softmodemfunc=map_int_to_str(softmodem_funcs, execmask); + if (softmodemfunc != NULL) { + set_softmodem_optmask(execmask); + return 0; + } + return -1; +} +char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) { + uint64_t fmask=(get_softmodem_optmask()&SOFTMODEM_FUNC_BITS); + char *softmodemfunc=map_int_to_str(softmodem_funcs, fmask); + if (sofmodemfunc_mask_ptr != NULL) + *sofmodemfunc_mask_ptr=fmask; + if (softmodemfunc != NULL) { + return softmodemfunc; + } + return "???"; +} + +void get_common_options(uint32_t execmask) { uint32_t online_log_messages; uint32_t glog_level ; uint32_t start_telnetsrv = 0; @@ -70,6 +90,7 @@ void get_common_options(void) { paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC; + check_execmask(execmask); config_get( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams, sizeof(cmdline_logparams)/sizeof(paramdef_t)); diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 69ed98635b..c9a24577dc 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -31,6 +31,7 @@ */ #ifndef SOFTMODEM_COMMON_H #define SOFTMODEM_COMMON_H +#include "openair1/PHY/defs_common.h" #ifdef __cplusplus extern "C" { @@ -164,6 +165,14 @@ extern "C" #define SOFTMODEM_BASICSIM_BIT (1<<11) #define SOFTMODEM_SIML1_BIT (1<<12) #define SOFTMODEM_DOFORMS_BIT (1<<15) +#define SOFTMODEM_RECPLAY_BIT (1<<16) +#define SOFTMODEM_ENB_BIT (1<<20) +#define SOFTMODEM_GNB_BIT (1<<21) +#define SOFTMODEM_4GUE_BIT (1<<22) +#define SOFTMODEM_5GUE_BIT (1<<23) +#define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT) +#define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}} + #define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) #define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) @@ -172,7 +181,11 @@ extern "C" #define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT) #define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) #define IS_SOFTMODEM_DOFORMS ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT) - +#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT) +#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT) +#define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT) +#define IS_SOFTMODEM_4GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT) +#define IS_SOFTMODEM_5GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_5GUE_BIT) typedef struct { uint64_t optmask; @@ -195,7 +208,8 @@ typedef struct { extern uint64_t get_softmodem_optmask(void); extern uint64_t set_softmodem_optmask(uint64_t bitmask); extern softmodem_params_t *get_softmodem_params(void); -extern void get_common_options(void); +extern void get_common_options(uint32_t execmask); +extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); #define SOFTMODEM_RTSIGNAL (SIGRTMIN+1) extern void set_softmodem_sighandler(void); extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 8c19f44d2f..e142d2f29f 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -36,7 +36,7 @@ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" - +#include "executables/softmodem-common.h" //uint8_t ncs_cell[20][7]; //#define DEBUG_PUCCH_TXS @@ -801,9 +801,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, for (j=0; jpucch1_stats_cnt[j][i]=0; eNB->pucch1ab_stats_cnt[j][i]=0; -#if defined(USRP_REC_PLAY) // not 100% sure - eNB->pucch1_stats_thres[j][i]=0; -#endif + if ( IS_SOFTMODEM_IQPLAYER) + eNB->pucch1_stats_thres[j][i]=0; } } @@ -1193,15 +1192,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, stat_re=0; stat_im=0; // Do detection now -#if defined(USRP_REC_PLAY) - // It looks like the value is a bit messy when RF is replayed. + + // It looks like the pucch1_thres value is a bit messy when RF is replayed. // For instance i assume to skip pucch1_thres from the test below. // Not 100% sure - if (sigma2_dB<(dB_fixed(stat_max))) {// -#else - if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres)) {// -#endif + + if (sigma2_dB<(dB_fixed(stat_max) - (IS_SOFTMODEM_IQPLAYER?0:pucch1_thres)) ) {// chL = (nsymb>>1)-4; chest_mag=0; cfo = (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase_max] : &cfo_pucch_ep[12*phase_max]; @@ -1339,11 +1336,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, if (fmt==pucch_format1b) *(1+payload) = (stat_im<0) ? 1 : 2; } else { // insufficient energy on PUCCH so NAK -#if defined(USRP_REC_PLAY) - LOG_D(PHY,"PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); -#else LOG_D(PHY,"In pucch.c PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); -#endif *payload = 4; // DTX ((int16_t *)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re); ((int16_t *)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im); diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index 4f2d05ef50..eb9a2922c5 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -46,9 +46,7 @@ #include -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 1bb544d204..95dc539ef4 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -45,9 +45,7 @@ #include -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" extern uint8_t nfapi_mode; /* diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 0067efb4d9..430a3ee0b5 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -74,15 +74,7 @@ fifo_dump_emos_UE emos_dump_UE; #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" - -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - -//#include "PHY/defs.h" - -//#include "PHY/CODING/extern.h" - +#include "intertask_interface.h" #include "T.h" #define DLSCH_RB_ALLOC 0x1fbf // skip DC RB (total 23/25 RBs) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 8ca533c146..6d92beaddf 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -53,11 +53,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" - -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif - +#include "intertask_interface.h" #include "PHY/defs_UE.h" #include "PHY/CODING/coding_extern.h" @@ -4885,10 +4881,8 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue, uint8_t abstraction_flag, uint8_t do_pdcch_flag, runmode_t mode) { -#if defined(ENABLE_ITTI) MessageDef *msg_p; int result; -#endif int frame_rx = proc->frame_rx; int frame_tx = proc->frame_tx; int subframe_rx = proc->subframe_rx; @@ -4905,9 +4899,6 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue, if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); } - -#if defined(ENABLE_ITTI) - do { // Checks if a message has been sent to PHY sub-task itti_poll_msg (TASK_PHY_UE, &msg_p); @@ -4929,8 +4920,6 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue, } } while(msg_p != NULL); -#endif - for (slot=0; slot<2; slot++) { if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)|| (ue->frame_parms.frame_type == FDD)) { diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 76d24f75f3..5b97796f8a 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -45,10 +45,8 @@ #define GNB_CONF_STRING_OTG_APP_TYPE "app_type" #define GNB_CONF_STRING_OTG_BG_TRAFFIC "bg_traffic" -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) extern int asn_debug; extern int asn1_xer_print; -#endif #ifdef LIBCONFIG_LONG #define libconfig_int long diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 8d497c80d3..eef1f9c976 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -57,9 +57,7 @@ /* for fair round robin SCHED */ #include "eNB_scheduler_fairRR.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "assertions.h" diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index e85255e8ce..fb765e6dac 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -55,14 +55,12 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "SIMULATION/TOOLS/sim.h" // for taus #include "T.h" - +#include "executables/softmodem-common.h" #include "common/ran_context.h" #include "LAYER2/MAC/eNB_scheduler_fairRR.h" @@ -1353,28 +1351,31 @@ initiate_ra_proc(module_id_t module_idP, /* TODO: find better procedure to allocate RNTI */ do { -#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode - static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; - int j = 0; - int nb_ue = 0; + if (IS_SOFTMODEM_IQPLAYER) { /* iq player mode, use deterministic rnti */ + static int drnti[MAX_MOBILES_PER_ENB]; + static int drnti_def[]={ 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; + for (int j=0; j 0) { - nb_ue++; - } else { - break; + for (int j = 0; j < MAX_MOBILES_PER_ENB; j++) { + if (UE_RNTI(module_idP, j) > 0) { + nb_ue++; + } else { + break; + } } - } - if (nb_ue >= MAX_MOBILES_PER_ENB) { - printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n"); - abort(); - } + if (nb_ue >= MAX_MOBILES_PER_ENB || nb_ue >= (sizeof(drnti_def)/sizeof(int))) { + printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n"); + abort(); + } - ra[i].rnti = drnti[nb_ue]; -#else - ra[i].rnti = taus(); -#endif + ra[i].rnti = drnti[nb_ue]; + } else { + ra[i].rnti = taus(); + } loop++; } while (loop != 100 && /* TODO: this is not correct, the rnti may be in use without diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index f5cd3a0753..5b99578d57 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -44,9 +44,7 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 2a56c61a68..eba4bdcee9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -53,9 +53,7 @@ #include "assertions.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index e351b69bb0..2953c8e70b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -48,10 +48,6 @@ #include "pdcp.h" #include "assertions.h" -//#if defined(ENABLE_ITTI) -//#include "intertask_interface.h" -//#endif -// #include "SIMULATION/TOOLS/sim.h" // for taus #define ENABLE_MAC_PAYLOAD_DEBUG diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 5189e76975..e76e6b24ba 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -48,10 +48,8 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif - +#include "intertask_interface.h" +#include "executables/softmodem-common.h" #include "T.h" #define ENABLE_MAC_PAYLOAD_DEBUG @@ -2184,9 +2182,8 @@ add_new_ue(module_id_t mod_idP, UE_list->ordered_ULCCids[0][UE_id] = cc_idP; UE_list->num_UEs++; UE_list->active[UE_id] = TRUE; -#if defined(USRP_REC_PLAY) // not specific to record/playback ? - UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; -#endif + if (IS_SOFTMODEM_IQPLAYER)// not specific to record/playback ? + UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; UE_list->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type; memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 430f73cd9d..6c19ad6a46 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -48,9 +48,7 @@ #include "assertions.h" #include "pdcp.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "ENB_APP/flexran_agent_defs.h" #include "flexran_agent_ran_api.h" diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 1244125bb6..8518cba14c 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -56,9 +56,7 @@ #include "pdcp.h" #include "targets/RT/USER/lte-softmodem.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "assertions.h" @@ -2455,10 +2453,8 @@ ue_scheduler(const module_id_t module_idP, struct LTE_RACH_ConfigCommon *rach_ConfigCommon = (struct LTE_RACH_ConfigCommon *) NULL; protocol_ctxt_t ctxt; -#if defined(ENABLE_ITTI) MessageDef *msg_p; int result; -#endif #if UE_TIMING_TRACE start_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif @@ -2467,7 +2463,6 @@ ue_scheduler(const module_id_t module_idP, PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO, UE_mac_inst[module_idP].crnti, txFrameP, txSubframeP, eNB_indexP); -#if defined(ENABLE_ITTI) if(module_idP == 0) { do { @@ -2497,8 +2492,6 @@ ue_scheduler(const module_id_t module_idP, } while (msg_p != NULL); } -#endif - //Mac_rlc_xface->frameP=frameP; //Rrc_xface->Frame_index=Mac_rlc_xface->frameP; //if (subframe%5 == 0) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index ab7757164f..d08b8211ee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -55,9 +55,7 @@ #include "flexran_agent_extern.h" #include "flexran_agent_mac.h" -#if defined(ENABLE_ITTI) #include "intertask_interface.h" -#endif #include "assertions.h" #include diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index df3e04dccf..409ba1d6d2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -46,9 +46,7 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(ENABLE_ITTI) #include "intertask_interface.h" -#endif #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index f3a1b3e7fd..d95819d1e7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -50,9 +50,7 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(ENABLE_ITTI) #include "intertask_interface.h" -#endif #include "T.h" diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index 8f9ee0af18..cb108f5d26 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -33,7 +33,7 @@ #include "UTIL/OSA/osa_defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" - +#include "executables/softmodem-common.h" #include "LAYER2/MAC/mac_extern.h" #include "pdcp.h" @@ -213,28 +213,28 @@ pdcp_validate_security( stream_decrypt(pdcp_pP->cipheringAlgorithm, &decrypt_params, &buffer_decrypted); -#if !defined(USRP_REC_PLAY) - if (srb_flagP) { + if (!IS_SOFTMODEM_IQPLAYER) { + if (srb_flagP) { /* Now check the integrity of the complete PDU */ - decrypt_params.message = pdcp_pdu_buffer; - decrypt_params.blength = sdu_buffer_size << 3; - decrypt_params.key = pdcp_pP->kRRCint + 16;// 128; + decrypt_params.message = pdcp_pdu_buffer; + decrypt_params.blength = sdu_buffer_size << 3; + decrypt_params.key = pdcp_pP->kRRCint + 16;// 128; - if (stream_check_integrity(pdcp_pP->integrityProtAlgorithm, - &decrypt_params, - &pdcp_pdu_buffer[sdu_buffer_size]) != 0) { - MSC_LOG_EVENT( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - " Security: failed MAC-I Algo %X UE %"PRIx16" ", - pdcp_pP->integrityProtAlgorithm, - ctxt_pP->rnti); - LOG_E(PDCP, "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", - rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); - return -1; + if (stream_check_integrity(pdcp_pP->integrityProtAlgorithm, + &decrypt_params, + &pdcp_pdu_buffer[sdu_buffer_size]) != 0) { + MSC_LOG_EVENT( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + " Security: failed MAC-I Algo %X UE %"PRIx16" ", + pdcp_pP->integrityProtAlgorithm, + ctxt_pP->rnti); + LOG_E(PDCP, "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", + rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); + return -1; + } } - } -#endif + } /* !IQPLAYER */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); return 0; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index ddff2cc3d1..02a0247a03 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -26,9 +26,7 @@ //----------------------------------------------------------------------------- #include "platform_types.h" //----------------------------------------------------------------------------- -#if ENABLE_ITTI - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "assertions.h" #include "list.h" #include "rlc_am.h" diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 356dd2e481..68017be85b 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -37,9 +37,7 @@ #include "msc.h" #include "common/ran_context.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "flexran_agent_extern.h" #undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index 20df462938..fa332b5be1 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -37,9 +37,7 @@ #include "msc.h" #include "common/ran_context.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" //#define RRC_DATA_REQ_DEBUG //#define DEBUG_RRC 1 @@ -135,7 +133,6 @@ rrc_data_ind( ctxt_pP->rnti); } -#if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). @@ -152,11 +149,4 @@ rrc_data_ind( RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; itti_send_msg_to_task (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->instance, message_p); } -#else - rrc_eNB_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - sdu_sizeP); -#endif } diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index c9d4e61d0a..61ab63955d 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -37,9 +37,7 @@ #include "msc.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" //#define RRC_DATA_REQ_DEBUG @@ -76,7 +74,6 @@ mac_rrc_data_req_ue( LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { -#if defined(ENABLE_ITTI) { MessageDef *message_p; int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; @@ -96,7 +93,6 @@ mac_rrc_data_req_ue( itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } -#endif memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; @@ -138,7 +134,6 @@ mac_rrc_data_ind_ue( if(srb_idP == BCCH_SI_MBMS) { LOG_D(RRC,"[UE %d] Received SDU for BCCH on MBMS SRB %ld from eNB %d\n",module_idP,srb_idP,eNB_indexP); -#if defined(ENABLE_ITTI) { MessageDef *message_p; int msg_sdu_size = sizeof(RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sdu); @@ -161,14 +156,10 @@ mac_rrc_data_ind_ue( RRC_MAC_BCCH_MBMS_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } -#else - decode_BCCH_MBMS_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP, 0, 0); -#endif } if(srb_idP == BCCH) { LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %ld from eNB %d\n",module_idP,srb_idP,eNB_indexP); -#if defined(ENABLE_ITTI) { MessageDef *message_p; int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); @@ -191,9 +182,6 @@ mac_rrc_data_ind_ue( RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } -#else - decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP, 0, 0); -#endif } if(srb_idP == PCCH) { @@ -204,7 +192,6 @@ mac_rrc_data_ind_ue( if((srb_idP & RAB_OFFSET) == CCCH) { if (sdu_lenP>0) { LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %ld from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); -#if defined(ENABLE_ITTI) { MessageDef *message_p; int msg_sdu_size = CCCH_SDU_SIZE; @@ -226,20 +213,12 @@ mac_rrc_data_ind_ue( RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } -#else - SRB_INFO *Srb_info; - Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; - memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); - Srb_info->Rx_buffer.payload_size = sdu_lenP; - rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); -#endif } } if ((srb_idP & RAB_OFFSET) == MCCH) { LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); -#if defined(ENABLE_ITTI) { MessageDef *message_p; int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); @@ -259,9 +238,6 @@ mac_rrc_data_ind_ue( RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } -#else - decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); -#endif } //TTN (for D2D) @@ -297,7 +273,6 @@ rrc_data_req_ue( ctxt_pP->rnti, muiP, sdu_sizeP); -#if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). @@ -325,18 +300,6 @@ rrc_data_req_ue( message_p); return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } -#else - return pdcp_data_req ( - ctxt_pP, - SRB_FLAG_YES, - rb_idP, - muiP, - confirmP, - sdu_sizeP, - buffer_pP, - modeP,NULL, NULL - ); -#endif } //------------------------------------------------------------------------------ @@ -352,7 +315,6 @@ rrc_data_ind_ue( rb_id_t DCCH_index = Srb_id; LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %ld message on SRB %ld with Size %d from eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); -#if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). @@ -369,20 +331,11 @@ rrc_data_ind_ue( RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; itti_send_msg_to_task (TASK_RRC_UE, ctxt_pP->instance, message_p); } -#else - //#warning "LG put 0 to arg4 that is eNB index" - rrc_ue_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - 0); -#endif } //-------------------------------------------------------------------------------------------// void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { //-------------------------------------------------------------------------------------------// -#if defined(ENABLE_ITTI) { MessageDef *message_p; //LOG_I(RRC,"sending a message to task_mac_ue\n"); @@ -391,14 +344,6 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index; itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } -#else - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0; - - if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) { - UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++; - } - -#endif } //-------------------------------------------------------------------------------------------// @@ -412,7 +357,6 @@ void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); -#if defined(ENABLE_ITTI) { MessageDef *message_p; message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND); @@ -420,9 +364,6 @@ void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index; itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } -#else - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt++; -#endif } //------------------------------------------------------------------------------ @@ -442,16 +383,11 @@ mac_UE_get_rrc_status( //-------------------------------------------------------------------------------------------// int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) { //-------------------------------------------------------------------------------------------// -#if defined(ENABLE_ITTI) { MessageDef *message_p; message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF); RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index; itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } -#else - // reset the tx buffer to indicate RRC that ccch was successfully transmitted (for example if contention resolution succeeds) - UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size=0; -#endif return 0; } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index c9071806d2..d8f6ac145d 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -89,9 +89,9 @@ #include "LTE_MeasIdToAddModList.h" #include "enb_config.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif + +#include "intertask_interface.h" + #include "common/ran_context.h" #include "secu_defs.h" @@ -381,17 +381,12 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, } uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, - int Mod_id,int CC_id -#if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration -#endif + int Mod_id,int CC_id, + RrcConfigurationReq *configuration ) { // SystemInformation_t systemInformation; -#if defined(ENABLE_ITTI) int num_plmn = configuration->num_plmn; -#else - int num_plmn = 1; -#endif + LTE_PLMN_IdentityInfo_t *PLMN_identity_info; LTE_MCC_MNC_Digit_t *dummy_mcc_0; LTE_MCC_MNC_Digit_t *dummy_mcc_1; @@ -438,16 +433,10 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, if (dummy_mcc_0 == NULL || dummy_mcc_1 == NULL || dummy_mcc_2 == NULL) exit(1); - -#if defined(ENABLE_ITTI) *dummy_mcc_0 = (configuration->mcc[i] / 100) % 10; *dummy_mcc_1 = (configuration->mcc[i] / 10) % 10; *dummy_mcc_2 = (configuration->mcc[i] / 1) % 10; -#else - *dummy_mcc_0 = 0; - *dummy_mcc_1 = 0; - *dummy_mcc_2 = 1; -#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list, dummy_mcc_0); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list, dummy_mcc_1); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list, dummy_mcc_2); @@ -460,8 +449,6 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, if (dummy_mnc_0 == NULL || dummy_mnc_1 == NULL || dummy_mnc_2 == NULL) exit(1); -#if defined(ENABLE_ITTI) - if (configuration->mnc[i] >= 100) { *dummy_mnc_0 = (configuration->mnc[i] / 100) % 10; *dummy_mnc_1 = (configuration->mnc[i] / 10) % 10; @@ -478,11 +465,6 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, } } -#else - *dummy_mnc[i][0] = 0; - *dummy_mnc[i][1] = 1; - *dummy_mnc[i][2] = 0xf; -#endif ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list, dummy_mnc_0); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list, dummy_mnc_1); @@ -499,36 +481,20 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, // 16 bits (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf = MALLOC(2); -#if defined(ENABLE_ITTI) (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[0] = (configuration->tac >> 8) & 0xff; (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[1] = (configuration->tac >> 0) & 0xff; -#else - (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[0] = 0x00; - (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[1] = 0x01; -#endif (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.size=2; (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.bits_unused=0; // 28 bits (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf = MALLOC(8); -#if defined(ENABLE_ITTI) (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[0] = (configuration->cell_identity >> 20) & 0xff; (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[1] = (configuration->cell_identity >> 12) & 0xff; (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[2] = (configuration->cell_identity >> 4) & 0xff; (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[3] = (configuration->cell_identity << 4) & 0xf0; -#else - (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[0] = 0x00; - (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[1] = 0x00; - (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[2] = 0x00; - (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[3] = 0x10; -#endif (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.size=4; (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.bits_unused=4; - (*sib1_MBMS)->freqBandIndicator_r14 = -#if defined(ENABLE_ITTI) - configuration->eutra_band[CC_id]; -#else - 7; -#endif + (*sib1_MBMS)->freqBandIndicator_r14 = configuration->eutra_band[CC_id]; + schedulingInfo->si_Periodicity_r14=LTE_SchedulingInfo__si_Periodicity_rf16; *sib_type = LTE_SIB_Type_MBMS_r14_sibType13_v920; ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo_r14.list, sib_type); @@ -827,17 +793,11 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, } uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, - int Mod_id,int CC_id, BOOLEAN_t brOption -#if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration -#endif + int Mod_id,int CC_id, BOOLEAN_t brOption, + RrcConfigurationReq *configuration ) { // SystemInformation_t systemInformation; -#if defined(ENABLE_ITTI) int num_plmn = configuration->num_plmn; -#else - int num_plmn = 1; -#endif LTE_PLMN_IdentityInfo_t *PLMN_identity_info; LTE_MCC_MNC_Digit_t *dummy_mcc_0; LTE_MCC_MNC_Digit_t *dummy_mcc_1; @@ -892,15 +852,10 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, if (dummy_mcc_0 == NULL || dummy_mcc_1 == NULL || dummy_mcc_2 == NULL) exit(1); -#if defined(ENABLE_ITTI) + *dummy_mcc_0 = (configuration->mcc[i] / 100) % 10; *dummy_mcc_1 = (configuration->mcc[i] / 10) % 10; *dummy_mcc_2 = (configuration->mcc[i] / 1) % 10; -#else - *dummy_mcc_0 = 0; - *dummy_mcc_1 = 0; - *dummy_mcc_2 = 1; -#endif ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list, dummy_mcc_0); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list, dummy_mcc_1); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list, dummy_mcc_2); @@ -913,7 +868,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, if (dummy_mnc_0 == NULL || dummy_mnc_1 == NULL || dummy_mnc_2 == NULL) exit(1); -#if defined(ENABLE_ITTI) if (configuration->mnc[i] >= 100) { *dummy_mnc_0 = (configuration->mnc[i] / 100) % 10; @@ -930,12 +884,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, *dummy_mnc_2 = (configuration->mnc[i] / 1) % 10; } } - -#else - *dummy_mnc_0 = 0; - *dummy_mnc_1 = 1; - *dummy_mnc_2 = 0xf; -#endif ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list, dummy_mnc_0); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list, dummy_mnc_1); @@ -952,28 +900,16 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, // 16 bits (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf = MALLOC(2); -#if defined(ENABLE_ITTI) (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf[0] = (configuration->tac >> 8) & 0xff; (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf[1] = (configuration->tac >> 0) & 0xff; -#else - (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf[0] = 0x00; - (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf[1] = 0x01; -#endif (*sib1)->cellAccessRelatedInfo.trackingAreaCode.size = 2; (*sib1)->cellAccessRelatedInfo.trackingAreaCode.bits_unused = 0; // 28 bits (*sib1)->cellAccessRelatedInfo.cellIdentity.buf = MALLOC(8); -#if defined(ENABLE_ITTI) (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[0] = (configuration->cell_identity >> 20) & 0xff; (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[1] = (configuration->cell_identity >> 12) & 0xff; (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[2] = (configuration->cell_identity >> 4) & 0xff; (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[3] = (configuration->cell_identity << 4) & 0xf0; -#else - (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[0] = 0x00; - (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[1] = 0x00; - (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[2] = 0x00; - (*sib1)->cellAccessRelatedInfo.cellIdentity.buf[3] = 0x10; -#endif (*sib1)->cellAccessRelatedInfo.cellIdentity.size=4; (*sib1)->cellAccessRelatedInfo.cellIdentity.bits_unused=4; // assign_enum(&(*sib1)->cellAccessRelatedInfo.cellBarred,SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred); @@ -985,12 +921,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, (*sib1)->cellSelectionInfo.q_RxLevMinOffset=NULL; //(*sib1)->p_Max = CALLOC(1, sizeof(P_Max_t)); // *((*sib1)->p_Max) = 23; - (*sib1)->freqBandIndicator = -#if defined(ENABLE_ITTI) - configuration->eutra_band[CC_id]; -#else - 7; -#endif + (*sib1)->freqBandIndicator = configuration->eutra_band[CC_id]; schedulingInfo.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; if(configuration->eMBMS_M2_configured){ schedulingInfo2.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; @@ -1005,24 +936,12 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo2); } // ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,NULL); -#if defined(ENABLE_ITTI) if (configuration->frame_type[CC_id] == TDD) -#endif { (*sib1)->tdd_Config = CALLOC(1,sizeof(struct LTE_TDD_Config)); - (*sib1)->tdd_Config->subframeAssignment = -#if defined(ENABLE_ITTI) - configuration->tdd_config[CC_id]; -#else - 3; // +kogo this was frame_parms->tdd_config -#endif - (*sib1)->tdd_Config->specialSubframePatterns = -#if defined(ENABLE_ITTI) - configuration->tdd_config_s[CC_id]; -#else - 0; -#endif + (*sib1)->tdd_Config->subframeAssignment = configuration->tdd_config[CC_id]; + (*sib1)->tdd_Config->specialSubframePatterns = configuration->tdd_config_s[CC_id]; } (*sib1)->si_WindowLength = LTE_SystemInformationBlockType1__si_WindowLength_ms20; @@ -1050,8 +969,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, sib1_1250->freqBandIndicatorPriority_r12 = 0; // long* // FIXME sib1_1250->nonCriticalExtension = NULL; ////Rel1310 -#if defined(ENABLE_ITTI) - if ((configuration->schedulingInfoSIB1_BR_r13[CC_id] != 0) && (brOption==TRUE)) { sib1_1250->nonCriticalExtension = calloc(1, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); @@ -1245,89 +1162,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, sib1_1320->nonCriticalExtension = NULL; } -#else - sib1_1250->nonCriticalExtension = calloc(1, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); - memset(sib1_1250->nonCriticalExtension, 0, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); - SystemInformationBlockType1_v1310_IEs_t *sib1_1310 = sib1_1250->nonCriticalExtension; - sib1_1310->hyperSFN_r13 = calloc(1, sizeof(BIT_STRING_t)); // type - memset(sib1_1310->hyperSFN_r13, 0, sizeof(BIT_STRING_t)); - sib1_1310->hyperSFN_r13->buf = calloc(2, sizeof(uint8_t)); - memset(sib1_1310->hyperSFN_r13->buf, 0, 2*sizeof(uint8_t)); - sib1_1310->hyperSFN_r13->size = 2; - sib1_1310->hyperSFN_r13->bits_unused = 6; - sib1_1310->eDRX_Allowed_r13 = NULL; // long* - sib1_1310->cellSelectionInfoCE_r13 = calloc(1, sizeof(LTE_CellSelectionInfoCE_r13_t)); - memset(sib1_1310->cellSelectionInfoCE_r13, 0, sizeof(LTE_CellSelectionInfoCE_r13_t)); - sib1_1310->cellSelectionInfoCE_r13->q_RxLevMinCE_r13 = -70; // (Q_RxLevMin_t) long - sib1_1310->cellSelectionInfoCE_r13->q_QualMinRSRQ_CE_r13 = NULL; // (Q_RxLevMin_t) *long - sib1_1310->bandwidthReducedAccessRelatedInfo_r13 - = calloc(1, sizeof(struct LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13)); - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13 - = LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms20; // 0 - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13 - = LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_everyRF; // 0 - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13 = calloc(1, sizeof(LTE_SchedulingInfoList_BR_r13_t)); - SchedulingInfo_BR_r13_t *schedulinginfo_br_13 = calloc(1, sizeof(LTE_SchedulingInfo_BR_r13_t)); - memset(schedulinginfo_br_13, 0, sizeof(LTE_SchedulingInfo_BR_r13_t)); - schedulinginfo_br_13->si_Narrowband_r13 = 1; - schedulinginfo_br_13->si_TBS_r13 = LTE_SchedulingInfo_BR_r13__si_TBS_r13_b152; - ASN_SEQUENCE_ADD(&sib1_1310->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13->list, schedulinginfo_br_13); - 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(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)); - memset(sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13->choice.subframePattern10_r13.buf, 0, 2 * sizeof(uint8_t)); - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13->choice.subframePattern10_r13.size = 2; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_DownlinkOrTddSubframeBitmapBR_r13->choice.subframePattern10_r13.bits_unused = 6; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_UplinkSubframeBitmapBR_r13 = calloc(1, sizeof(BIT_STRING_t)); - memset(sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_UplinkSubframeBitmapBR_r13, 0, sizeof(BIT_STRING_t)); - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_UplinkSubframeBitmapBR_r13->buf = calloc(2, sizeof(uint8_t)); - memset(sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_UplinkSubframeBitmapBR_r13->buf, 0, - 2 * sizeof(uint8_t)); - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_UplinkSubframeBitmapBR_r13->size = 2; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->fdd_UplinkSubframeBitmapBR_r13->bits_unused = 6; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13 = 1; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 - = LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_on; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->si_ValidityTime_r13 = calloc(1, sizeof(long)); - memset(sib1_1310->bandwidthReducedAccessRelatedInfo_r13->si_ValidityTime_r13, 0, sizeof(long)); - *sib1_1310->bandwidthReducedAccessRelatedInfo_r13->si_ValidityTime_r13 - = LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_ValidityTime_r13_true; - sib1_1310->bandwidthReducedAccessRelatedInfo_r13->systemInfoValueTagList_r13 = calloc(1, sizeof(LTE_SystemInfoValueTagList_r13_t)); - LTE_SystemInfoValueTagSI_r13_t *systemInfoValueTagSi_r13 = CALLOC(1, sizeof(LTE_SystemInfoValueTagSI_r13_t)); - *systemInfoValueTagSi_r13 = 0; - ASN_SEQUENCE_ADD(&sib1_1310->bandwidthReducedAccessRelatedInfo_r13->systemInfoValueTagList_r13->list, systemInfoValueTagSi_r13); - sib1_1310->nonCriticalExtension = calloc(1, sizeof(LTE_SystemInformationBlockType1_v1320_IEs_t)); - memset(sib1_1310->nonCriticalExtension, 0, sizeof(LTE_SystemInformationBlockType1_v1320_IEs_t)); - /////Rel1320 - LTE_SystemInformationBlockType1_v1320_IEs_t *sib1_1320 = sib1_1310->nonCriticalExtension; - sib1_1320->freqHoppingParametersDL_r13 = calloc(1, sizeof(struct LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13)); - memset(sib1_1320->freqHoppingParametersDL_r13, 0, sizeof(struct LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13)); - sib1_1320->freqHoppingParametersDL_r13->mpdcch_pdsch_HoppingNB_r13 = calloc(1, sizeof(long)); - *sib1_1320->freqHoppingParametersDL_r13->mpdcch_pdsch_HoppingNB_r13 = LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__mpdcch_pdsch_HoppingNB_r13_nb2; - sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeA_r13 = calloc(1, - sizeof(struct LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeA_r13)); - memset(sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeA_r13, 0, - sizeof(struct LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeA_r13)); - sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeA_r13->present = - LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeA_r13_PR_interval_FDD_r13; - sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeA_r13->choice.interval_FDD_r13 = - LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeA_r13__interval_FDD_r13_int1; - sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeB_r13 = calloc(1, - sizeof(struct LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeB_r13)); - memset(sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeB_r13, 0, - sizeof(struct LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeB_r13)); - sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeB_r13->present = - LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeB_r13_PR_interval_FDD_r13; - sib1_1320->freqHoppingParametersDL_r13->interval_DLHoppingConfigCommonModeB_r13->choice.interval_FDD_r13 = - LTE_SystemInformationBlockType1_v1320_IEs__freqHoppingParametersDL_r13__interval_DLHoppingConfigCommonModeB_r13__interval_FDD_r13_int2; - sib1_1320->freqHoppingParametersDL_r13->mpdcch_pdsch_HoppingOffset_r13 = calloc(1, sizeof(long)); - *sib1_1320->freqHoppingParametersDL_r13->mpdcch_pdsch_HoppingOffset_r13 = 1; - sib1_1320->nonCriticalExtension = NULL; -#endif (*sib1)->si_WindowLength=LTE_SystemInformationBlockType1__si_WindowLength_ms20; (*sib1)->systemInfoValueTag=0; // (*sib1).nonCriticalExtension = calloc(1,sizeof(*(*sib1).nonCriticalExtension)); @@ -1358,10 +1192,8 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, uint8_t do_SIB23(uint8_t Mod_id, - int CC_id, BOOLEAN_t brOption -#if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration -#endif + int CC_id, BOOLEAN_t brOption, + RrcConfigurationReq *configuration ) { struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; int eMTC_configured = configuration->eMTC_configured; @@ -1455,7 +1287,6 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->ac_BarringInfo = NULL; (*sib2)->ext1 = NULL; (*sib2)->ext2 = NULL; -#if defined(ENABLE_ITTI) (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles = rrconfig->rach_numberOfRA_Preambles; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL; @@ -1846,121 +1677,7 @@ uint8_t do_SIB23(uint8_t Mod_id, = rrconfig->ue_TimersAndConstants_t311; (*sib2)->ue_TimersAndConstants.n311 = rrconfig->ue_TimersAndConstants_n311; -#else - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles=LTE_RACH_ConfigCommon__preambleInfo__numberOfRA_Preambles_n64; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep=LTE_RACH_ConfigCommon__powerRampingParameters__powerRampingStep_dB2; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower= - RACH_ConfigCommon__powerRampingParameters__preambleInitialReceivedTargetPower_dBm_100; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax=LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize=LTE_RACH_ConfigCommon__ra_SupervisionInfo__ra_ResponseWindowSize_sf10; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer= - LTE_RACH_ConfigCommon__ra_SupervisionInfo__mac_ContentionResolutionTimer_sf48; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx = 4; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1 = calloc(1, sizeof(struct LTE_RACH_ConfigCommon__ext1)); - memset((*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1, 0, sizeof(struct LTE_RACH_ConfigCommon__ext1)); - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = calloc(1, sizeof(LTE_PreambleTransMax_t)); - *(*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = LTE_PreambleTransMax_n5; // to be re-initialized when we find the enum - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->rach_CE_LevelInfoList_r13 = calloc(1, sizeof(LTE_RACH_CE_LevelInfoList_r13_t)); - memset((*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->rach_CE_LevelInfoList_r13, 0, sizeof(LTE_RACH_CE_LevelInfoList_r13_t)); - LTE_RACH_CE_LevelInfo_r13_t *rach_ce_levelinfo_r13 = calloc(1, sizeof(LTE_RACH_CE_LevelInfo_r13_t)); - memset(rach_ce_levelinfo_r13, 0, sizeof(LTE_RACH_CE_LevelInfo_r13_t)); - rach_ce_levelinfo_r13->preambleMappingInfo_r13.firstPreamble_r13 = 0; - rach_ce_levelinfo_r13->preambleMappingInfo_r13.lastPreamble_r13 = 63; - rach_ce_levelinfo_r13->ra_ResponseWindowSize_r13 = LTE_RACH_CE_LevelInfo_r13__ra_ResponseWindowSize_r13_sf80; - rach_ce_levelinfo_r13->mac_ContentionResolutionTimer_r13 = LTE_RACH_CE_LevelInfo_r13__mac_ContentionResolutionTimer_r13_sf200; - rach_ce_levelinfo_r13->rar_HoppingConfig_r13 = LTE_RACH_CE_LevelInfo_r13__rar_HoppingConfig_r13_off; - ASN_SEQUENCE_ADD(&(*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->rach_CE_LevelInfoList_r13->list, rach_ce_levelinfo_r13); - // BCCH-Config - (*sib2)->radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff=LTE_BCCH_Config__modificationPeriodCoeff_n2; - // PCCH-Config - (*sib2)->radioResourceConfigCommon.pcch_Config.defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf128; - (*sib2)->radioResourceConfigCommon.pcch_Config.nB=LTE_PCCH_Config__nB_oneT; - // PRACH-Config - (*sib2)->radioResourceConfigCommon.prach_Config.rootSequenceIndex = Mod_id;//0;//384; - (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex = 0;//3; - (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag = 0; - (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig = 1;//12; - (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset = 2; - // PDSCH-Config - (*sib2)->radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower=0; // corresponds to 24.7 dBm 5 MHz/ 27.7 10 MHz/ 30.7 20 MHz - (*sib2)->radioResourceConfigCommon.pdsch_ConfigCommon.p_b=0; - // PUSCH-Config - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB=1; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode=LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset=0; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM=0; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled=1; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH=0; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled=0; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift=0; - // PUCCH-Config - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift=LTE_PUCCH_ConfigCommon__deltaPUCCH_Shift_ds1; - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI = 1; - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = 0; - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = 32; - (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present=LTE_SoundingRS_UL_ConfigCommon_PR_release; - (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.release=0; - // uplinkPowerControlCommon - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH = -108; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH = -108; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.alpha=LTE_UplinkPowerControlCommon__alpha_al1; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 = 6; - (*sib2)->radioResourceConfigCommon.ul_CyclicPrefixLength=UL_CyclicPrefixLength_len1; - (*sib2)->radioResourceConfigCommon.ext4 = calloc(1, sizeof(struct LTE_RadioResourceConfigCommonSIB__ext4)); - memset((*sib2)->radioResourceConfigCommon.ext4, 0, sizeof(struct LTE_RadioResourceConfigCommonSIB__ext4)); - (*sib2)->radioResourceConfigCommon.ext4->bcch_Config_v1310 = calloc(1, sizeof(LTE_BCCH_Config_v1310_t)); - memset((*sib2)->radioResourceConfigCommon.ext4->bcch_Config_v1310, 0, sizeof(LTE_BCCH_Config_v1310_t)); - (*sib2)->radioResourceConfigCommon.ext4->bcch_Config_v1310->modificationPeriodCoeff_v1310 = LTE_BCCH_Config_v1310__modificationPeriodCoeff_v1310_n64; - (*sib2)->radioResourceConfigCommon.ext4->pcch_Config_v1310 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->freqHoppingParameters_r13 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->pdsch_ConfigCommon_v1310 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->pusch_ConfigCommon_v1310 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310 = calloc(1, sizeof(LTE_PRACH_ConfigSIB_v1310_t)); - memset((*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310, 0, sizeof(PRACH_ConfigSIB_v1310_t)); - LTE_RSRP_Range_t rsrp_range = 60; - ASN_SEQUENCE_ADD(&(*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->rsrp_ThresholdsPrachInfoList_r13.list, &rsrp_range); - (*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->mpdcch_startSF_CSS_RA_r13 = calloc(1, sizeof(struct LTE_PRACH_ConfigSIB_v1310__mpdcch_startSF_CSS_RA_r13)); - memset((*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->mpdcch_startSF_CSS_RA_r13, 0, sizeof(struct LTE_PRACH_ConfigSIB_v1310__mpdcch_startSF_CSS_RA_r13)); - (*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->mpdcch_startSF_CSS_RA_r13->present = LTE_PRACH_ConfigSIB_v1310__mpdcch_startSF_CSS_RA_r13_PR_fdd_r13; - (*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->mpdcch_startSF_CSS_RA_r13->choice.fdd_r13 = LTE_PRACH_ConfigSIB_v1310__mpdcch_startSF_CSS_RA_r13__fdd_r13_v5; - (*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->prach_HoppingOffset_r13 = NULL; - LTE_PRACH_ParametersCE_r13_t *prach_parametersce_r13 = calloc(1, sizeof(LTE_PRACH_ParametersCE_r13_t)); - memset(prach_parametersce_r13, 0, sizeof(LTE_PRACH_ParametersCE_r13_t)); - prach_parametersce_r13->prach_ConfigIndex_r13 = 3; - prach_parametersce_r13->prach_FreqOffset_r13 = 1; - prach_parametersce_r13->prach_StartingSubframe_r13 = NULL; - prach_parametersce_r13->maxNumPreambleAttemptCE_r13 = calloc(1, sizeof(long)); - *prach_parametersce_r13->maxNumPreambleAttemptCE_r13 = LTE_PRACH_ParametersCE_r13__maxNumPreambleAttemptCE_r13_n3; - prach_parametersce_r13->numRepetitionPerPreambleAttempt_r13 = LTE_PRACH_ParametersCE_r13__numRepetitionPerPreambleAttempt_r13_n1; - long maxavailablenarrowband = 2; - ASN_SEQUENCE_ADD(&prach_parametersce_r13->mpdcch_NarrowbandsToMonitor_r13.list, &maxavailablenarrowband); - prach_parametersce_r13->mpdcch_NumRepetition_RA_r13 = LTE_PRACH_ParametersCE_r13__mpdcch_NumRepetition_RA_r13_r1; - prach_parametersce_r13->prach_HoppingConfig_r13 = LTE_PRACH_ParametersCE_r13__prach_HoppingConfig_r13_off; - ASN_SEQUENCE_ADD(&(*sib2)->radioResourceConfigCommon.ext4->prach_ConfigCommon_v1310->prach_ParametersListCE_r13.list, prach_parametersce_r13); - (*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310 = calloc(1, sizeof(LTE_PUCCH_ConfigCommon_v1310_t)); - memset((*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310, 0, sizeof(LTE_PUCCH_ConfigCommon_v1310_t)); - (*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->n1PUCCH_AN_InfoList_r13 = calloc(1, sizeof(LTE_N1PUCCH_AN_InfoList_r13_t)); - long pucch_info_value1 = 0; - long pucch_info_value2 = 2; - ASN_SEQUENCE_ADD(&(*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->n1PUCCH_AN_InfoList_r13->list, &pucch_info_value1); - ASN_SEQUENCE_ADD(&(*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->n1PUCCH_AN_InfoList_r13->list, &pucch_info_value2); - (*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->pucch_NumRepetitionCE_Msg4_Level0_r13 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->pucch_NumRepetitionCE_Msg4_Level1_r13 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->pucch_NumRepetitionCE_Msg4_Level2_r13 = NULL; - (*sib2)->radioResourceConfigCommon.ext4->pucch_ConfigCommon_v1310->pucch_NumRepetitionCE_Msg4_Level3_r13 = NULL; - (*sib2)->ue_TimersAndConstants.t300=UE_TimersAndConstants__t300_ms1000; - (*sib2)->ue_TimersAndConstants.t301=UE_TimersAndConstants__t301_ms1000; - (*sib2)->ue_TimersAndConstants.t310=UE_TimersAndConstants__t310_ms1000; - (*sib2)->ue_TimersAndConstants.n310=UE_TimersAndConstants__n310_n20; - (*sib2)->ue_TimersAndConstants.t311=UE_TimersAndConstants__t311_ms10000; - (*sib2)->ue_TimersAndConstants.n311=UE_TimersAndConstants__n311_n1; -#endif + (*sib2)->freqInfo.additionalSpectrumEmission = 1; (*sib2)->freqInfo.ul_CarrierFreq = NULL; (*sib2)->freqInfo.ul_Bandwidth = NULL; @@ -2724,21 +2441,12 @@ do_RRCConnectionSetup( SRB1_config->rlc_Config = SRB1_rlc_config; SRB1_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB1_rlc_config->choice.explicitValue.present=LTE_RLC_Config_PR_am; -#if defined(ENABLE_ITTI) SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = rrc->srb1_poll_byte; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; -#else - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; -#endif SRB1_lchan_config = CALLOC(1,sizeof(*SRB1_lchan_config)); SRB1_config->logicalChannelConfig = SRB1_lchan_config; SRB1_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; @@ -3099,21 +2807,12 @@ uint8_t do_RRCConnectionSetup_BR( SRB1_config->rlc_Config = SRB1_rlc_config; // check this SRB1_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB1_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; -#if defined(ENABLE_ITTI) SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = rrc->srb1_poll_byte; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; -#else - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20; // FIXME should be 80 - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4; // FIXME should be infinity - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; -#endif SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config)); SRB1_config->logicalChannelConfig = SRB1_lchan_config; SRB1_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; @@ -3403,9 +3102,9 @@ uint8_t do_RRCConnectionSetup_BR( rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.sps_Config = NULL; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2; // rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = NULL; -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void *)&dl_ccch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void *)&dl_ccch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, (void *)&dl_ccch_msg, @@ -3413,31 +3112,8 @@ uint8_t do_RRCConnectionSetup_BR( 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { - MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif -#ifdef USER_MODE - LOG_D(RRC,"RRCConnectionSetup_BR Encoded %d bits (%d bytes), ecause %d\n", - enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); -#endif - // FREEMEM(SRB_list); - // free(SRB1_config); - // free(SRB1_rlc_config); - // free(SRB1_lchan_config); - // free(SRB1_ul_SpecificParameters); + return((enc_rval.encoded+7)/8); } @@ -3661,25 +3337,10 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const RRC_BUF_SIZE); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed %s, %lu!\n", enc_rval.failed_type->name, enc_rval.encoded); -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void *)&dl_dcch_msg); -#endif -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[30000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { - MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void *)&dl_dcch_msg); } -# endif -#endif + LOG_I(RRC,"RRCConnectionReconfiguration Encoded %d bits (%d bytes)\n",(int)enc_rval.encoded,(int)(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } @@ -3933,21 +3594,12 @@ do_RRCConnectionReestablishment( SRB1_config->rlc_Config = SRB1_rlc_config; SRB1_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB1_rlc_config->choice.explicitValue.present=LTE_RLC_Config_PR_am; -#if defined(ENABLE_ITTI) SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = rrc->srb1_poll_byte; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; -#else - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; -#endif SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config)); SRB1_config->logicalChannelConfig = SRB1_lchan_config; SRB1_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 925f09416e..ccd5e1c537 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -91,10 +91,8 @@ LTE_DRX_Config_t *do_DrxConfig(int CC_id, RrcConfigurationReq *configuration, LT @param br_flag Do for BL/CE UE configuration @return size of encoded bit stream in bytes*/ -uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id, BOOLEAN_t brOption -#if defined(ENABLE_ITTI) - ,RrcConfigurationReq *configuration -#endif +uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id, BOOLEAN_t brOption, + RrcConfigurationReq *configuration ); /** @@ -120,10 +118,8 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id, RrcCo @param MBMS_flag Indicates presence of MBMS system information (when 1) @return size of encoded bit stream in bytes*/ -uint8_t do_SIB23(uint8_t Mod_id,int CC_id, BOOLEAN_t brOption -#if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration -#endif +uint8_t do_SIB23(uint8_t Mod_id,int CC_id, BOOLEAN_t brOption, + RrcConfigurationReq *configuration ); /** diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c index 480f5c3516..350a8baf77 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c @@ -68,10 +68,8 @@ //#include "PHY/defs.h" #include "enb_config.h" +#include "intertask_interface.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif @@ -178,21 +176,15 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0; //left as it is??? -#if defined(ENABLE_ITTI) + dummy_mcc[0] = (configuration->mcc / 100) % 10; dummy_mcc[1] = (configuration->mcc / 10) % 10; dummy_mcc[2] = (configuration->mcc / 1) % 10; -#else - dummy_mcc[0] = 0; - dummy_mcc[1] = 0; - dummy_mcc[2] = 1; -#endif ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]); ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]); ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]); PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0; PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0; -#if defined(ENABLE_ITTI) if (configuration->mnc >= 100) { dummy_mnc[0] = (configuration->mnc / 100) % 10; @@ -210,11 +202,6 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, } } -#else - dummy_mnc[0] = 0; - dummy_mnc[1] = 1; - dummy_mnc[2] = 0xf; -#endif ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]); ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]); @@ -230,28 +217,16 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, // 16 bits = 2 byte (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte //lefts as it is? -#if defined(ENABLE_ITTI) (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff; (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff; -#else - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01; -#endif (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2; (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0; // 28 bits --> i have to use 32 bits = 4 byte (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte? -#if defined(ENABLE_ITTI) (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff; (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff; (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff; (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0; -#else - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10; -#endif (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4; (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; //Still set to "notBarred" as in the previous case @@ -264,11 +239,8 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, *((*sib1_NB_IoT)->p_Max_r13) = 23; //FIXME (*sib1_NB_IoT)->freqBandIndicator_r13 = -#if defined(ENABLE_ITTI) configuration->eutra_band; -#else - 5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode) -#endif + //OPTIONAL new parameters, to be used? /* * freqBandInfo_r13 @@ -305,10 +277,8 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); //printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13); -#if defined(ENABLE_ITTI) if (configuration->frame_type == TDD) -#endif { //FIXME in NB-IoT mandatory to be FDD --> so must give an error LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct? @@ -342,9 +312,7 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, enc_rval.failed_type->name, enc_rval.encoded); } -#ifdef USER_MODE LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { return(-1); @@ -563,10 +531,9 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, 900); // AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", // enc_rval.failed_type->name, enc_rval.encoded); - //#if defined(ENABLE_ITTI)..... -#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif + if (enc_rval.encoded==-1) { msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n"); @@ -748,10 +715,8 @@ uint8_t do_RRCConnectionSetup_NB_IoT( enc_rval.failed_type->name, enc_rval.encoded); } -#ifdef USER_MODE - LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n", - enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); -#endif + LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } @@ -793,15 +758,11 @@ uint8_t do_SecurityModeCommand_NB_IoT( enc_rval.failed_type->name, enc_rval.encoded); } - //#if defined(ENABLE_ITTI) - //# if !defined(DISABLE_XER_SPRINT).... -#ifdef USER_MODE LOG_D(RRC,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, enc_rval.encoded, (enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { LOG_E(RRC,"[NB-IoT %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n", @@ -850,15 +811,12 @@ uint8_t do_UECapabilityEnquiry_NB_IoT( enc_rval.failed_type->name, enc_rval.encoded); } - //#if defined(ENABLE_ITTI) - //# if !defined(DISABLE_XER_SPRINT).... -#ifdef USER_MODE LOG_D(RRC,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, enc_rval.encoded, (enc_rval.encoded+7)/8); -#endif + if (enc_rval.encoded==-1) { LOG_E(RRC,"[NB-IoT %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n", @@ -940,8 +898,6 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message_NB,(void *)&dl_dcch_msg_NB_IoT); } - //#if defined(ENABLE_ITTI) - //# if !defined(DISABLE_XER_SPRINT)... LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } @@ -977,10 +933,8 @@ uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( } //Only change in "asn_DEF_DL_CCCH_Message_NB" -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } @@ -1025,10 +979,8 @@ uint8_t do_RRCConnectionReject_NB_IoT( enc_rval.failed_type->name, enc_rval.encoded); } -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionReject-NB Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index bf62fc3df2..a91e6fcd00 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -152,21 +152,15 @@ init_SI( (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); do_MIB_FeMBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], -#ifdef ENABLE_ITTI configuration->N_RB_DL[CC_id], - 0 //additionalNonMBSFN -#else - 50,0 -#endif - ,0); + 0, //additionalNonMBSFN + 0); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = 0; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_MBMS = (uint8_t *) malloc16(32); AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_MBMS!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1_MBMS allocated\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = do_SIB1_MBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id -#if defined(ENABLE_ITTI) - , configuration -#endif + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = do_SIB1_MBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id, + configuration ); LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB1-MBMS\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP) @@ -892,7 +886,6 @@ rrc_eNB_free_mem_UE_context( //uint8_t Status; //rnti_t rnti; //uint64_t random_ue_identity; -#if defined(ENABLE_ITTI) //UE_S_TMSI Initialue_identity_s_TMSI; //EstablishmentCause_t establishment_cause; //ReestablishmentCause_t reestablishment_cause; @@ -905,7 +898,6 @@ rrc_eNB_free_mem_UE_context( //transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; //rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; #endif -#endif } //----------------------------------------------------------------------------- @@ -4758,7 +4750,6 @@ check_handovers( if (ue_context_p->ue_context.Status == RRC_RECONFIGURED && ue_context_p->ue_context.handover_info != NULL && ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) { -#if defined(ENABLE_ITTI) MessageDef *msg_p; int result; protocol_ctxt_t ctxt; @@ -4889,7 +4880,6 @@ check_handovers( ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_EMPTY; ue_context_p->ue_context.handover_info->state = HO_FORWARDING_COMPLETE; -#endif } } } @@ -5805,7 +5795,6 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct securityConfigHO->handoverType.choice.intraLTE.securityAlgorithmConfig = NULL; /* TODO: to be checked */ securityConfigHO->handoverType.choice.intraLTE.keyChangeIndicator = 0; securityConfigHO->handoverType.choice.intraLTE.nextHopChainingCount = 0; -#if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -5838,7 +5827,6 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct dedicatedInfoNASList = NULL; } -#endif measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 || RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports; memset(buffer, 0, RRC_BUF_SIZE); @@ -5887,7 +5875,6 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct *_size = size = ho_size; LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration handover\n"); -#if defined(ENABLE_ITTI) /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { @@ -5897,8 +5884,6 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL; } } - -#endif LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration handover (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 749dff3ace..6bbdef181b 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -27,7 +27,6 @@ * \email: lionel.gauthier@eurecom.fr */ -//#if defined(ENABLE_USE_MME) # include "rrc_defs.h" # include "rrc_extern.h" # include "RRC/LTE/MESSAGES/asn1_msg.h" @@ -35,10 +34,10 @@ # include "rrc_eNB_UE_context.h" # include "msc.h" -//# if defined(ENABLE_ITTI) -# include "asn1_conversions.h" -# include "intertask_interface.h" -//#endif + +#include "asn1_conversions.h" +#include "intertask_interface.h" + # include "common/ran_context.h" @@ -113,7 +112,6 @@ gtpv_data_req( return FALSE; } LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP); -#if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). @@ -167,8 +165,6 @@ gtpv_data_req( return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } } -#endif - return TRUE; } diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 11c6d27f5f..59998cebcc 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -58,7 +58,7 @@ #include "TLVDecoder.h" #include "S1AP_NAS-PDU.h" #include "flexran_agent_common_internal.h" - +#include "executables/softmodem-common.h" extern RAN_CONTEXT_t RC; extern int @@ -540,9 +540,10 @@ rrc_pdcp_config_security( derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, &kRRCint); -#if !defined(USRP_REC_PLAY) + if (!IS_SOFTMODEM_IQPLAYER) { SET_LOG_DUMP(DEBUG_SECURITY) ; -#endif + } + if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { if (print_keys ==1 ) { diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 86cff69517..2a9448218a 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -36,9 +36,7 @@ #include "msc.h" #include "common/ran_context.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "NR_MIB.h" #include "NR_BCCH-BCH-Message.h" diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index a3bdffb5f6..b321aa3e4f 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -99,9 +99,7 @@ #include "gnb_config.h" #endif -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #include "common/ran_context.h" @@ -289,23 +287,18 @@ uint8_t do_MIB_NR(rrc_gNB_carrier_data_t *carrier, } -uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier -#if defined(ENABLE_ITTI) - , gNB_RrcConfigurationReq *configuration -#endif +uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, + gNB_RrcConfigurationReq *configuration ) { asn_enc_rval_t enc_rval; NR_BCCH_DL_SCH_Message_t *sib1_message ; struct NR_SIB1 *sib1 ; int i; struct NR_PLMN_IdentityInfo nr_plmn_info; -#if defined(ENABLE_ITTI) + // TODO : Add support for more than one PLMN //int num_plmn = configuration->num_plmn; int num_plmn = 1; -#else - int num_plmn = 1; -#endif struct NR_PLMN_Identity nr_plmn[num_plmn]; NR_MCC_MNC_Digit_t nr_mcc_digit[num_plmn][3]; NR_MCC_MNC_Digit_t nr_mnc_digit[num_plmn][3]; @@ -329,30 +322,18 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier memset(nr_plmn,0,num_plmn*sizeof(struct NR_PLMN_Identity)); for (i = 0; i < num_plmn; ++i) { -#ifdef ENABLE_ITTI nr_mcc_digit[i][0] = (configuration->mcc[i]/100)%10; nr_mcc_digit[i][1] = (configuration->mcc[i]/10)%10; nr_mcc_digit[i][2] = (configuration->mcc[i])%10; -#else - nr_mcc_digit[i][0] = 0; - nr_mcc_digit[i][1] = 0; - nr_mcc_digit[i][2] = 1; -#endif nr_plmn[i].mcc = CALLOC(1,sizeof(struct NR_MCC)); memset(nr_plmn[i].mcc,0,sizeof(struct NR_MCC)); asn_set_empty(&nr_plmn[i].mcc->list); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][0]); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][1]); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][2]); -#ifdef ENABLE_ITTI nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10; nr_mnc_digit[i][1] = (configuration->mnc[i]/10)%10; nr_mnc_digit[i][2] = (configuration->mnc[i])%10; -#else - nr_mnc_digit[i][0] = 0; - nr_mnc_digit[i][1] = 0; - nr_mnc_digit[i][2] = 1; -#endif memset(&nr_plmn[i].mnc,0,sizeof(NR_MNC_t)); nr_plmn[i].mnc.list.size=0; nr_plmn[i].mnc.list.count=0; @@ -364,17 +345,10 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier nr_plmn_info.cellIdentity.buf = MALLOC(8); memset(nr_plmn_info.cellIdentity.buf,0,8); -#ifdef ENABLE_ITTI nr_plmn_info.cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff; nr_plmn_info.cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff; nr_plmn_info.cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff; nr_plmn_info.cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff; -#else - nr_plmn_info.cellIdentity.buf[0]= 0x00; - nr_plmn_info.cellIdentity.buf[1]= 0x00; - nr_plmn_info.cellIdentity.buf[2]= 0x00; - nr_plmn_info.cellIdentity.buf[3]= 0x10; -#endif nr_plmn_info.cellIdentity.size= 4; nr_plmn_info.cellIdentity.bits_unused= 4; nr_plmn_info.cellReservedForOperatorUse = 0; @@ -410,9 +384,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id, int CC_id, -#if defined(ENABLE_ITTI) - gNB_RrcConfigurationReq *configuration, -#endif + gNB_RrcConfigurationReq *configuration, int initial_flag ) { NR_ServingCellConfigCommon_t **servingcellconfigcommon = &RC.nrrrc[Mod_id]->carrier[CC_id].servingcellconfigcommon; @@ -1143,17 +1115,13 @@ void do_SpCellConfig(uint8_t Mod_id, common_configuration = CALLOC(1,sizeof(gNB_RrcConfigurationReq)); //Fill servingcellconfigcommon config value rrc_config_servingcellconfigcommon(Mod_id, - CC_id -#if defined(ENABLE_ITTI) - ,common_configuration -#endif + CC_id, + common_configuration ); //Fill common config to structure do_SERVINGCELLCONFIGCOMMON(Mod_id, CC_id, -#if defined(ENABLE_ITTI) common_configuration, -#endif 0 ); spconfig->reconfigurationWithSync = CALLOC(1,sizeof(struct NR_ReconfigurationWithSync)); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index c3154b708e..69ce650b23 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -76,17 +76,13 @@ uint8_t do_MIB_NR(rrc_gNB_carrier_data_t *carrier, @param carrier pointer to Carrier information @param configuration Pointer Configuration Request structure @return size of encoded bit stream in bytes*/ -uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier -#if defined(ENABLE_ITTI) - , gNB_RrcConfigurationReq *configuration -#endif +uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, + gNB_RrcConfigurationReq *configuration ); void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id, int CC_id, -#if defined(ENABLE_ITTI) gNB_RrcConfigurationReq *configuration, -#endif int initial_flag); void do_RLC_BEARER(uint8_t Mod_id, diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 80008d9af2..e09b1e6055 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -31,10 +31,8 @@ #include "nr_rrc_config.h" void rrc_config_servingcellconfigcommon(uint8_t Mod_id, - int CC_id - #if defined(ENABLE_ITTI) - ,gNB_RrcConfigurationReq *common_configuration - #endif + int CC_id, + gNB_RrcConfigurationReq *common_configuration ){ common_configuration->MIB_subCarrierSpacingCommon[CC_id] = 0; @@ -259,4 +257,4 @@ void rrc_config_rachdedicated(uint8_t Mod_id, physicalcellgroup_t *physicalcellgroup_config ){ -} \ No newline at end of file +} diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index c30478f0b0..e19d94b341 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -117,10 +117,8 @@ typedef struct rach_dedicated_s{ }rach_dedicated_t; void rrc_config_servingcellconfigcommon(uint8_t Mod_id, - int CC_id - #if defined(ENABLE_ITTI) - ,gNB_RrcConfigurationReq *common_configuration - #endif + int CC_id, + gNB_RrcConfigurationReq *common_configuration ); void rrc_config_rlc_bearer(uint8_t Mod_id, @@ -138,4 +136,4 @@ void rrc_config_physicalcellgroup(uint8_t Mod_id, physicalcellgroup_t *physicalcellgroup_config ); -#endif \ No newline at end of file +#endif diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index e9d4b4bf59..6b4a9864c7 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -72,21 +72,15 @@ #include "NR_EstablishmentCause.h" //------------------- -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" /* TODO: be sure this include is correct. * It solves a problem of compilation of the RRH GW, * issue #186. */ -#if !defined(ENABLE_ITTI) #include "as_message.h" -#endif -#if defined(ENABLE_USE_MME) #include "commonDef.h" -#endif /*I will change the name of the structure for compile purposes--> hope not to undo this process*/ @@ -295,7 +289,6 @@ typedef struct gNB_RRC_UE_s { rnti_t rnti; uint64_t random_ue_identity; -#if defined(ENABLE_ITTI) /* Information from UE RRC ConnectionRequest */ UE_S_TMSI Initialue_identity_s_TMSI; NR_EstablishmentCause_t establishment_cause; @@ -328,7 +321,6 @@ typedef struct gNB_RRC_UE_s { uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; -#endif uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; @@ -420,9 +412,7 @@ typedef struct gNB_RRC_INST_s { hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t //RRC configuration -#if defined(ENABLE_ITTI) gNB_RrcConfigurationReq configuration;//rrc_messages_types.h -#endif // other PLMN parameters /// Mobile country code diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 67b5c34db9..ce90ee46fb 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -58,9 +58,7 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( ); -#if defined(ENABLE_ITTI) /**\brief RRC eNB task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_gnb_task(void *args_p); -#endif \ No newline at end of file diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3d42190887..586fcd3492 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -67,21 +67,15 @@ #include "UTIL/OSA/osa_defs.h" #endif -#if defined(ENABLE_USE_MME) - #include "rrc_eNB_S1AP.h" - #include "rrc_eNB_GTPV1U.h" - #if defined(ENABLE_ITTI) - #else - #include "../../S1AP/s1ap_eNB.h" - #endif -#endif +#include "rrc_eNB_S1AP.h" +#include "rrc_eNB_GTPV1U.h" + #include "pdcp.h" #include "gtpv1u_eNB_task.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" + #if ENABLE_RAL #include "rrc_eNB_ral.h" @@ -200,11 +194,9 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( ///---------------------------------------------------------------------------------------------------------------/// static void init_NR_SI(const protocol_ctxt_t *const ctxt_pP, - const int CC_id -#if defined(ENABLE_ITTI) - , - gNB_RrcConfigurationReq *configuration -#endif + const int CC_id, + gNB_RrcConfigurationReq *configuration + ) { //int i; LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); @@ -219,20 +211,14 @@ static void init_NR_SI(const protocol_ctxt_t *const ctxt_pP, RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_MIB = 0; RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t *) malloc16(4); RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_MIB = do_MIB_NR(&RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id],0, -#ifdef ENABLE_ITTI - configuration->MIB_ssb_SubcarrierOffset[CC_id], - configuration->pdcch_ConfigSIB1[CC_id], - configuration->MIB_subCarrierSpacingCommon[CC_id], - configuration->MIB_dmrs_TypeA_Position[CC_id] -#else - 0,0,15,2 -#endif + configuration->MIB_ssb_SubcarrierOffset[CC_id], + configuration->pdcch_ConfigSIB1[CC_id], + configuration->MIB_subCarrierSpacingCommon[CC_id], + configuration->MIB_dmrs_TypeA_Position[CC_id] ); do_SERVINGCELLCONFIGCOMMON(ctxt_pP->module_id, CC_id, -#if defined(ENABLE_ITTI) configuration, -#endif 1 ); LOG_I(NR_RRC,"Done init_NR_SI\n"); @@ -268,9 +254,8 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu #endif AssertFatal(RC.nrrrc[gnb_mod_idP] != NULL, "RC.nrrrc not initialized!"); AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); -#ifdef ENABLE_ITTI AssertFatal(configuration!=NULL,"configuration input is null\n"); -#endif + RC.nrrrc[ctxt.module_id]->Nb_ue = 0; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -287,10 +272,8 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { init_NR_SI(&ctxt, - CC_id -#if defined(ENABLE_ITTI) - ,configuration -#endif + CC_id, + configuration ); }//END for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) @@ -302,7 +285,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -#if defined(ENABLE_ITTI) + void *rrc_gnb_task(void *args_p) { MessageDef *msg_p; @@ -408,4 +391,3 @@ void *rrc_gnb_task(void *args_p) { } } -#endif //END #if defined(ENABLE_ITTI) diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c deleted file mode 100644 index faff4fcfb9..0000000000 --- a/openair2/UTIL/LOG/log.c +++ /dev/null @@ -1,1832 +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 log.c -* \brief log implementaion -* \author Navid Nikaein -* \date 2009 - 2014 -* \version 0.5 -* @ingroup util - -*/ - -#define _GNU_SOURCE /* required for pthread_getname_np */ -//#define LOG_TEST 1 - -#define COMPONENT_LOG -#define COMPONENT_LOG_IF -#include -#define LOG_MAIN -#include "log.h" -#include "vcd_signal_dumper.h" -#include "assertions.h" - -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - -# include -# include -#include "common/config/config_userapi.h" -// main log variables - - -mapping log_level_names[] = { - {"emerg", LOG_EMERG}, - {"alert", LOG_ALERT}, - {"crit", LOG_CRIT}, - {"error", LOG_ERR}, - {"warn", LOG_WARNING}, - {"notice", LOG_NOTICE}, - {"info", LOG_INFO}, - {"debug", LOG_DEBUG}, - {"file", LOG_FILE}, - {"trace", LOG_TRACE}, - {NULL, -1} -}; -mapping log_verbosity_names[] = { - {"none", 0x0}, - {"low", 0x5}, - {"medium", 0x15}, - {"high", 0x35}, - {"full", 0x75}, - {NULL, -1} -}; - -// vars for the log thread -LOG_params log_list[2000]; -int log_list_tail = 0; -int log_list_nb_elements = 0; - -pthread_mutex_t log_lock; -pthread_cond_t log_notify; - - -#if !defined(LOG_NO_THREAD) -int log_list_head = 0; -int log_shutdown; -#endif - -static int gfd; - -static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_ORANGE, LOG_BLUE, "", ""}; /*!< \brief Optional start-format strings for highlighting */ -static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET,LOG_RESET, "",""}; /*!< \brief Optional end-format strings for highlighting */ - -#if defined(ENABLE_ITTI) -static log_instance_type_t log_instance_type; -#endif - -/* get log parameters from configuration file */ -void log_getconfig(log_t *g_log) { - char *gloglevel = NULL; - char *glogverbo = NULL; - int level,verbosity; - paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; - paramdef_t logparams_level[MAX_LOG_COMPONENTS]; - paramdef_t logparams_verbosity[MAX_LOG_COMPONENTS]; - paramdef_t logparams_logfile[MAX_LOG_COMPONENTS]; - - int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX); - if (ret <0) { - fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed"); - return; - } - memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS); - memset(logparams_verbosity,0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS); - memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS); - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - if(g_log->log_component[i].name == NULL) { - g_log->log_component[i].name = malloc(16); - sprintf((char *)g_log->log_component[i].name,"comp%i?",i); - logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD; - logparams_level[i].paramflags = PARAMFLAG_DONOTREAD; - logparams_verbosity[i].paramflags = PARAMFLAG_DONOTREAD; - } - sprintf(logparams_level[i].optname, LOG_CONFIG_LEVEL_FORMAT, g_log->log_component[i].name); - sprintf(logparams_verbosity[i].optname,LOG_CONFIG_VERBOSITY_FORMAT, g_log->log_component[i].name); - sprintf(logparams_logfile[i].optname, LOG_CONFIG_LOGFILE_FORMAT, g_log->log_component[i].name); -/* workaround: all log options in existing configuration files use lower case component names - where component names include uppercase char in log.h.... */ - for (int j=0 ; jlog_component[PHY].name = "PHY"; - g_log->log_component[PHY].level = LOG_EMERG; - g_log->log_component[PHY].flag = LOG_MED; - g_log->log_component[PHY].interval = 1; - g_log->log_component[PHY].fd = 0; - g_log->log_component[PHY].filelog = 0; - g_log->log_component[PHY].filelog_name = "/tmp/phy.log"; - - g_log->log_component[MAC].name = "MAC"; - g_log->log_component[MAC].level = LOG_EMERG; - g_log->log_component[MAC].flag = LOG_MED; - g_log->log_component[MAC].interval = 1; - g_log->log_component[MAC].fd = 0; - g_log->log_component[MAC].filelog = 0; - g_log->log_component[MAC].filelog_name = "/tmp/mac.log"; - - g_log->log_component[OPT].name = "OPT"; - g_log->log_component[OPT].level = LOG_EMERG; - g_log->log_component[OPT].flag = LOG_MED; - g_log->log_component[OPT].interval = 1; - g_log->log_component[OPT].fd = 0; - g_log->log_component[OPT].filelog = 0; - g_log->log_component[OPT].filelog_name = ""; - - g_log->log_component[RLC].name = "RLC"; - g_log->log_component[RLC].level = LOG_INFO; - g_log->log_component[RLC].flag = LOG_MED; - g_log->log_component[RLC].interval = 1; - g_log->log_component[RLC].fd = 0; - g_log->log_component[RLC].filelog = 0; - g_log->log_component[RLC].filelog_name = "/tmp/rlc.log"; - - g_log->log_component[PDCP].name = "PDCP"; - g_log->log_component[PDCP].level = LOG_INFO; - g_log->log_component[PDCP].flag = LOG_MED; - g_log->log_component[PDCP].interval = 1; - g_log->log_component[PDCP].fd = 0; - g_log->log_component[PDCP].filelog = 0; - g_log->log_component[PDCP].filelog_name = "/tmp/pdcp.log"; - - g_log->log_component[RRC].name = "RRC"; - g_log->log_component[RRC].level = LOG_TRACE; - g_log->log_component[RRC].flag = LOG_MED; - g_log->log_component[RRC].interval = 1; - g_log->log_component[RRC].fd = 0; - g_log->log_component[RRC].filelog = 0; - g_log->log_component[RRC].filelog_name = "/tmp/rrc.log"; - - g_log->log_component[EMU].name = "EMU"; - g_log->log_component[EMU].level = LOG_EMERG; - g_log->log_component[EMU].flag = LOG_MED; - g_log->log_component[EMU].interval = 1; - g_log->log_component[EMU].fd = 0; - g_log->log_component[EMU].filelog = 0; - g_log->log_component[EMU].filelog_name = ""; - - g_log->log_component[OMG].name = "OMG"; - g_log->log_component[OMG].level = LOG_EMERG; - g_log->log_component[OMG].flag = LOG_MED; - g_log->log_component[OMG].interval = 1; - g_log->log_component[OMG].fd = 0; - g_log->log_component[OMG].filelog = 0; - g_log->log_component[OMG].filelog_name = "/tmp/omg.csv"; - - g_log->log_component[OTG].name = "OTG"; - g_log->log_component[OTG].level = LOG_EMERG; - g_log->log_component[OTG].flag = LOG_MED; - g_log->log_component[OTG].interval = 1; - g_log->log_component[OTG].fd = 0; - g_log->log_component[OTG].filelog = 0; - g_log->log_component[OTG].filelog_name = "/tmp/otg.log"; - - g_log->log_component[OTG_LATENCY].name = "OTG_LATENCY"; - g_log->log_component[OTG_LATENCY].level = LOG_EMERG; - g_log->log_component[OTG_LATENCY].flag = LOG_MED; - g_log->log_component[OTG_LATENCY].interval = 1; - g_log->log_component[OTG_LATENCY].fd = 0; - g_log->log_component[OTG_LATENCY].filelog = 0; - g_log->log_component[OTG_LATENCY].filelog_name = "/tmp/otg_latency.dat"; - - g_log->log_component[OTG_LATENCY_BG].name = "OTG_LATENCY_BG"; - g_log->log_component[OTG_LATENCY_BG].level = LOG_EMERG; - g_log->log_component[OTG_LATENCY_BG].flag = LOG_MED; - g_log->log_component[OTG_LATENCY_BG].interval = 1; - g_log->log_component[OTG_LATENCY_BG].fd = 0; - g_log->log_component[OTG_LATENCY_BG].filelog = 0; - g_log->log_component[OTG_LATENCY_BG].filelog_name = "/tmp/otg_latency_bg.dat"; - - g_log->log_component[OTG_GP].name = "OTG_GP"; - g_log->log_component[OTG_GP].level = LOG_EMERG; - g_log->log_component[OTG_GP].flag = LOG_MED; - g_log->log_component[OTG_GP].interval = 1; - g_log->log_component[OTG_GP].fd = 0; - g_log->log_component[OTG_GP].filelog = 0; - g_log->log_component[OTG_GP].filelog_name = "/tmp/otg_goodput.dat"; - - g_log->log_component[OTG_GP_BG].name = "OTG_GP_BG"; - g_log->log_component[OTG_GP_BG].level = LOG_EMERG; - g_log->log_component[OTG_GP_BG].flag = LOG_MED; - g_log->log_component[OTG_GP_BG].interval = 1; - g_log->log_component[OTG_GP_BG].fd = 0; - g_log->log_component[OTG_GP_BG].filelog = 0; - g_log->log_component[OTG_GP_BG].filelog_name = "/tmp/otg_goodput_bg.dat"; - - g_log->log_component[OTG_JITTER].name = "OTG_JITTER"; - g_log->log_component[OTG_JITTER].level = LOG_EMERG; - g_log->log_component[OTG_JITTER].flag = LOG_MED; - g_log->log_component[OTG_JITTER].interval = 1; - g_log->log_component[OTG_JITTER].fd = 0; - g_log->log_component[OTG_JITTER].filelog = 0; - g_log->log_component[OTG_JITTER].filelog_name = "/tmp/otg_jitter.dat"; - - g_log->log_component[OCG].name = "OCG"; - g_log->log_component[OCG].level = LOG_EMERG; - g_log->log_component[OCG].flag = LOG_MED; - g_log->log_component[OCG].interval = 1; - g_log->log_component[OCG].fd = 0; - g_log->log_component[OCG].filelog = 0; - g_log->log_component[OCG].filelog_name = ""; - - g_log->log_component[PERF].name = "PERF"; - g_log->log_component[PERF].level = LOG_EMERG; - g_log->log_component[PERF].flag = LOG_MED; - g_log->log_component[PERF].interval = 1; - g_log->log_component[PERF].fd = 0; - g_log->log_component[PERF].filelog = 0; - g_log->log_component[PERF].filelog_name = ""; - - g_log->log_component[OIP].name = "OIP"; - g_log->log_component[OIP].level = LOG_EMERG; - g_log->log_component[OIP].flag = LOG_MED; - g_log->log_component[OIP].interval = 1; - g_log->log_component[OIP].fd = 0; - g_log->log_component[OIP].filelog = 0; - g_log->log_component[OIP].filelog_name = ""; - - g_log->log_component[CLI].name = "CLI"; - g_log->log_component[CLI].level = LOG_EMERG; - g_log->log_component[CLI].flag = LOG_MED; - g_log->log_component[CLI].interval = 1; - g_log->log_component[CLI].fd = 0; - g_log->log_component[CLI].filelog = 0; - g_log->log_component[CLI].filelog_name = ""; - - g_log->log_component[MSC].name = "MSC"; - g_log->log_component[MSC].level = LOG_EMERG; - g_log->log_component[MSC].flag = LOG_MED; - g_log->log_component[MSC].interval = 1; - g_log->log_component[MSC].fd = 0; - g_log->log_component[MSC].filelog = 0; - g_log->log_component[MSC].filelog_name = "/tmp/msc.log"; - - g_log->log_component[PROTO_AGENT].name = "PROTO_AGENT"; - g_log->log_component[PROTO_AGENT].level = LOG_EMERG; - g_log->log_component[PROTO_AGENT].flag = LOG_MED; - g_log->log_component[PROTO_AGENT].interval = 1; - g_log->log_component[PROTO_AGENT].fd = 0; - g_log->log_component[PROTO_AGENT].filelog = 0; - g_log->log_component[PROTO_AGENT].filelog_name = "/tmp/proto_agent.log"; - - - - g_log->log_component[PROTO_AGENT].name = "PROTO_AGENT"; - g_log->log_component[PROTO_AGENT].level = LOG_EMERG; - g_log->log_component[PROTO_AGENT].flag = LOG_MED; - g_log->log_component[PROTO_AGENT].interval = 1; - g_log->log_component[PROTO_AGENT].fd = 0; - g_log->log_component[PROTO_AGENT].filelog = 0; - g_log->log_component[PROTO_AGENT].filelog_name = "/tmp/proto_agent.log"; - - g_log->log_component[F1U].name = "F1U"; - g_log->log_component[F1U].level = LOG_EMERG; - g_log->log_component[F1U].flag = LOG_MED; - g_log->log_component[F1U].interval = 1; - g_log->log_component[F1U].fd = 0; - g_log->log_component[F1U].filelog = 0; - g_log->log_component[F1U].filelog_name = "/tmp/f1u.log"; - - g_log->log_component[OCM].name = "OCM"; - g_log->log_component[OCM].level = LOG_EMERG; - g_log->log_component[OCM].flag = LOG_MED; - g_log->log_component[OCM].interval = 1; - g_log->log_component[OCM].fd = 0; - g_log->log_component[OCM].filelog = 0; - g_log->log_component[OCM].filelog_name = "/tmp/ocm.log"; - - g_log->log_component[HW].name = "HW"; - g_log->log_component[HW].level = LOG_EMERG; - g_log->log_component[HW].flag = LOG_MED; - g_log->log_component[HW].interval = 1; - g_log->log_component[HW].fd = 0; - g_log->log_component[HW].filelog = 0; - g_log->log_component[HW].filelog_name = ""; - - g_log->log_component[OSA].name = "OSA"; - g_log->log_component[OSA].level = LOG_EMERG; - g_log->log_component[OSA].flag = LOG_MED; - g_log->log_component[OSA].interval = 1; - g_log->log_component[OSA].fd = 0; - g_log->log_component[OSA].filelog = 0; - g_log->log_component[OSA].filelog_name = ""; - - g_log->log_component[RAL_ENB].name = "eRAL"; - g_log->log_component[RAL_ENB].level = LOG_EMERG; - g_log->log_component[RAL_ENB].flag = LOG_MED; - g_log->log_component[RAL_ENB].interval = 1; - g_log->log_component[RAL_ENB].fd = 0; - g_log->log_component[RAL_ENB].filelog = 0; - g_log->log_component[RAL_ENB].filelog_name = ""; - - g_log->log_component[RAL_UE].name = "mRAL"; - g_log->log_component[RAL_UE].level = LOG_EMERG; - g_log->log_component[RAL_UE].flag = LOG_MED; - g_log->log_component[RAL_UE].interval = 1; - g_log->log_component[RAL_UE].fd = 0; - g_log->log_component[RAL_UE].filelog = 0; - g_log->log_component[RAL_UE].filelog_name = ""; - - g_log->log_component[ENB_APP].name = "ENB_APP"; - g_log->log_component[ENB_APP].level = LOG_EMERG; - g_log->log_component[ENB_APP].flag = LOG_MED; - g_log->log_component[ENB_APP].interval = 1; - g_log->log_component[ENB_APP].fd = 0; - g_log->log_component[ENB_APP].filelog = 0; - g_log->log_component[ENB_APP].filelog_name = ""; - - g_log->log_component[FLEXRAN_AGENT].name = "FLEXRAN_AGENT"; - g_log->log_component[FLEXRAN_AGENT].level = LOG_DEBUG; - g_log->log_component[FLEXRAN_AGENT].flag = LOG_MED; - g_log->log_component[FLEXRAN_AGENT].interval = 1; - g_log->log_component[FLEXRAN_AGENT].fd = 0; - g_log->log_component[FLEXRAN_AGENT].filelog = 0; - g_log->log_component[FLEXRAN_AGENT].filelog_name = ""; - - g_log->log_component[TMR].name = "TMR"; - g_log->log_component[TMR].level = LOG_EMERG; - g_log->log_component[TMR].flag = LOG_MED; - g_log->log_component[TMR].interval = 1; - g_log->log_component[TMR].fd = 0; - g_log->log_component[TMR].filelog = 0; - g_log->log_component[TMR].filelog_name = ""; - - g_log->log_component[USIM].name = "USIM"; - g_log->log_component[USIM].level = LOG_DEBUG; - g_log->log_component[USIM].flag = LOG_NONE; - g_log->log_component[USIM].interval = 1; - g_log->log_component[USIM].fd = 0; - g_log->log_component[USIM].filelog = 0; - g_log->log_component[USIM].filelog_name = "/tmp/usim.txt"; - - /* following log component are used for the localization*/ - g_log->log_component[LOCALIZE].name = "LOCALIZE"; - g_log->log_component[LOCALIZE].level = LOG_EMERG; - g_log->log_component[LOCALIZE].flag = LOG_MED; - g_log->log_component[LOCALIZE].interval = 1; - g_log->log_component[LOCALIZE].fd = 0; - g_log->log_component[LOCALIZE].filelog = 0; - g_log->log_component[LOCALIZE].filelog_name = "/tmp/localize.log"; -#endif // ! defined(CN_BUILD) - - g_log->log_component[NAS].name = "NAS"; - g_log->log_component[NAS].level = LOG_TRACE; - g_log->log_component[NAS].flag = LOG_MED; - g_log->log_component[NAS].interval = 1; - g_log->log_component[NAS].fd = 0; - g_log->log_component[NAS].filelog = 0; - g_log->log_component[NAS].filelog_name = "/tmp/nas.log"; - - g_log->log_component[UDP_].name = "UDP"; - g_log->log_component[UDP_].level = LOG_EMERG; - g_log->log_component[UDP_].flag = LOG_FULL; - g_log->log_component[UDP_].interval = 1; - g_log->log_component[UDP_].fd = 0; - g_log->log_component[UDP_].filelog = 0; - g_log->log_component[UDP_].filelog_name = ""; - - g_log->log_component[GTPU].name = "GTPV1U"; - g_log->log_component[GTPU].level = LOG_EMERG; - g_log->log_component[GTPU].flag = LOG_FULL; - g_log->log_component[GTPU].interval = 1; - g_log->log_component[GTPU].fd = 0; - g_log->log_component[GTPU].filelog = 0; - g_log->log_component[GTPU].filelog_name = ""; - - g_log->log_component[S1AP].name = "S1AP"; - g_log->log_component[S1AP].level = LOG_EMERG; - g_log->log_component[S1AP].flag = LOG_FULL; - g_log->log_component[S1AP].interval = 1; - g_log->log_component[S1AP].fd = 0; - g_log->log_component[S1AP].filelog = 0; - g_log->log_component[S1AP].filelog_name = ""; - - g_log->log_component[SCTP].name = "SCTP"; - g_log->log_component[SCTP].level = LOG_EMERG; - g_log->log_component[SCTP].flag = LOG_MED; - g_log->log_component[SCTP].interval = 1; - g_log->log_component[SCTP].fd = 0; - g_log->log_component[SCTP].filelog = 0; - g_log->log_component[SCTP].filelog_name = ""; - - g_log->log_component[RRH].name = "RRH"; - g_log->log_component[RRH].level = LOG_EMERG; - g_log->log_component[RRH].flag = LOG_MED; - g_log->log_component[RRH].interval = 1; - g_log->log_component[RRH].fd = 0; - g_log->log_component[RRH].filelog = 0; - g_log->log_component[RRH].filelog_name = ""; - - g_log->level2string[LOG_EMERG] = "G"; //EMERG - g_log->level2string[LOG_ALERT] = "A"; // ALERT - g_log->level2string[LOG_CRIT] = "C"; // CRITIC - g_log->level2string[LOG_ERR] = "E"; // ERROR - g_log->level2string[LOG_WARNING] = "W"; // WARNING - g_log->level2string[LOG_NOTICE] = "N"; // NOTICE - g_log->level2string[LOG_INFO] = "I"; //INFO - g_log->level2string[LOG_DEBUG] = "D"; // DEBUG - g_log->level2string[LOG_FILE] = "F"; // file - g_log->level2string[LOG_TRACE] = "T"; // TRACE - - g_log->onlinelog = 1; //online log file - g_log->syslog = 0; - g_log->filelog = 0; - g_log->level = LOG_TRACE; - g_log->flag = LOG_LOW; - - g_log->config.remote_ip = 0; - g_log->config.remote_level = LOG_EMERG; - g_log->config.facility = LOG_LOCAL7; - g_log->config.audit_ip = 0; - g_log->config.audit_facility = LOG_LOCAL6; - g_log->config.format = 0x00; // online debug inactive - - g_log->filelog_name = "/tmp/openair.log"; - - if (g_log->syslog) { -#if ! defined(CN_BUILD) - openlog(g_log->log_component[EMU].name, LOG_PID, g_log->config.facility); -#endif // ! defined(CN_BUILD) - } - log_getconfig(g_log); - if (g_log->filelog) { - gfd = open(g_log->filelog_name, O_WRONLY | O_CREAT, 0666); - } - - // could put a loop here to check for all comps - for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - if (g_log->log_component[i].filelog == 1 ) { - g_log->log_component[i].fd = open(g_log->log_component[i].filelog_name, - O_WRONLY | O_CREAT | O_APPEND, 0666); - } - } - - printf("log init done\n"); - - return 0; -} - -void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args) -{ - //logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args) - int len = 0; - log_component_t *c; - char *log_start; - char *log_end; - /* The main difference with the version above is the use of this local log_buffer. - * The other difference is the return value of snprintf which was not used - * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is - * big enough so that the buffer is never full. - */ - char log_buffer[MAX_LOG_TOTAL]; - - /* for no gcc warnings */ - (void)log_start; - (void)log_end; - - c = &g_log->log_component[comp]; - - // do not apply filtering for LOG_F - // only log messages which are enabled and are below the global log level and component's level threshold - if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { - /* if ((level != LOG_FILE) && - ((level > c->level) || - (level > g_log->level) || - ( c->level > g_log->level))) { - */ - return; - } - - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_IN); - - // adjust syslog level for TRACE messages - if (g_log->syslog) { - if (g_log->level > LOG_DEBUG) { - g_log->level = LOG_DEBUG; - } - } - - // make sure that for log trace the extra info is only printed once, reset when the level changes - if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { - log_start = log_buffer; - len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - log_end = log_buffer + len; - } else { - if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", - log_level_highlight_start[level]); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - log_start = log_buffer + len; - - if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", - g_log->log_component[comp].name); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", - g_log->level2string[level]); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { -# define THREAD_NAME_LEN 128 - char threadname[THREAD_NAME_LEN]; - if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) - { - perror("pthread_getname_np : "); - } else { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } -# undef THREAD_NAME_LEN - } - - if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", - func); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", - file, line); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - //len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%08lx]", thread_id); - //if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - - len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - log_end = log_buffer + len; - - if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", - log_level_highlight_end[level]); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - } - - va_end(args); - - // OAI printf compatibility - if ((g_log->onlinelog == 1) && (level != LOG_FILE)) -#ifdef RTAI - if (len > MAX_LOG_TOTAL) { - rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n"); - } - - if (len > 0) { - rtf_put (FIFO_PRINTF_NO, log_buffer, len); - } - -#else - fwrite(log_buffer, len, 1, stdout); -#endif - -#ifndef RTAI - - if (g_log->syslog) { - syslog(g_log->level, "%s", log_buffer); - } - - if (g_log->filelog) { - if (write(gfd, log_buffer, len) < len) { - // TODO assert ? - } - } - - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - if (write(g_log->log_component[comp].fd, log_buffer, len) < len) { - // TODO assert ? - } - } - -#else - - // online print messges - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - printf(log_buffer); - } - -#endif - -#if defined(ENABLE_ITTI) - - if (level <= LOG_DEBUG) { - task_id_t origin_task_id = TASK_UNKNOWN; - MessagesIds messages_id; - MessageDef *message_p; - size_t message_string_size; - char *message_msg_p; - - message_string_size = log_end - log_start; - -#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) - - /* Try to identify sub task ID from log information (comp, log_instance_type) */ - switch (comp) { - case PHY: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_PHY_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_PHY_UE; - break; - - default: - break; - } - - break; - - case MAC: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_MAC_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_MAC_UE; - - default: - break; - } - - break; - - case RLC: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_RLC_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_RLC_UE; - - default: - break; - } - - break; - - case PDCP: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_PDCP_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_PDCP_UE; - - default: - break; - } - - break; - - default: - break; - } - -#endif - - switch (level) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - messages_id = ERROR_LOG; - break; - - case LOG_WARNING: - messages_id = WARNING_LOG; - break; - - case LOG_NOTICE: - messages_id = NOTICE_LOG; - break; - - case LOG_INFO: - messages_id = INFO_LOG; - break; - - default: - messages_id = DEBUG_LOG; - break; - } - - message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); - - switch (level) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - message_msg_p = (char *) &message_p->ittiMsg.error_log; - break; - - case LOG_WARNING: - message_msg_p = (char *) &message_p->ittiMsg.warning_log; - break; - - case LOG_NOTICE: - message_msg_p = (char *) &message_p->ittiMsg.notice_log; - break; - - case LOG_INFO: - message_msg_p = (char *) &message_p->ittiMsg.info_log; - break; - - default: - message_msg_p = (char *) &message_p->ittiMsg.debug_log; - break; - } - - memcpy(message_msg_p, log_start, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); - } - -#endif -#if 0 - LOG_params log_params; - int len; - - len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args); - - //2 first parameters must be passed as 'const' to the thread function - log_params.file = strdup(file); - log_params.func = strdup(func); - log_params.line = line; - log_params.comp = PHY;//comp; - log_params.level = 6; // INFO - level; - log_params.format = format; - log_params.len = len; - - if (pthread_mutex_lock(&log_lock) != 0) { - return; - } - - log_list_tail++; - log_list[log_list_tail - 1] = log_params; - - if (log_list_tail >= 1000) { - log_list_tail = 0; - } - - if (log_list_nb_elements < 1000) { - log_list_nb_elements++; - } - - if(pthread_cond_signal(&log_notify) != 0) { - pthread_mutex_unlock(&log_lock); - return; - } - - if(pthread_mutex_unlock(&log_lock) != 0) { - return; - } - -#endif -} - -//log record: add to a list -void logRecord(const char *file, const char *func, int line, int comp, - int level, const char *format, ...) -{ - va_list args; - LOG_params log_params; - int len; - - va_start(args, format); - len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args); - va_end(args); - - //2 first parameters must be passed as 'const' to the thread function - log_params.file = strdup(file); - log_params.func = strdup(func); - log_params.line = line; - log_params.comp = comp; - log_params.level = level; - log_params.format = format; - log_params.len = len; - - if (pthread_mutex_lock(&log_lock) != 0) { - return; - } - - log_list_tail++; - log_list[log_list_tail - 1] = log_params; - - if (log_list_tail >= 1000) { - log_list_tail = 0; - } - - if (log_list_nb_elements < 1000) { - log_list_nb_elements++; - } - - if(pthread_cond_signal(&log_notify) != 0) { - pthread_mutex_unlock(&log_lock); - return; - } - - if(pthread_mutex_unlock(&log_lock) != 0) { - return; - } - - //log = malloc(sizeof(LOG_elt)); - //log->next = NULL; - //log->log_params = log_params; - /* Add log task to queue */ - //log_list_add_tail_eurecom(log, &log_list); - -} - -void logRecord_thread_safe(const char *file, const char *func, - int line, int comp, int level, - int len, const char *params_string) -{ - log_component_t *c; - int total_len = 0; - char log_buffer[MAX_LOG_TOTAL]; - - c = &g_log->log_component[comp]; - - // do not apply filtering for LOG_F - // only log messages which are enabled and are below the global log level and component's level threshold - if ((level != LOG_FILE) && ((c->level > g_log->level) || - (level > c->level) || (level > g_log->level))) { - return; - } - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, - VCD_FUNCTION_IN); - - // adjust syslog level for TRACE messages - if (g_log->syslog) { - if (g_log->level > LOG_DEBUG) { - g_log->level = LOG_DEBUG; - } - } - - // make sure that for log trace the extra info is only printed once, reset when the level changes - if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level ==LOG_TRACE )) { - total_len = snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - 1, "%s", - params_string); - } else { - if ((g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR)) { - total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "%s", - log_level_highlight_start[level]); - } - - if ((g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { - total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s]", - g_log->log_component[comp].name); - } - - if ((g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL)) { - total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s]", - g_log->level2string[level]); - } - - if ((g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT)) { - total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s] ", - func); - } - - if ((g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { - total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s:%d]", - file, line); - } - - len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - len, "%s", - params_string); - - if ((g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR)) { - total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "%s", - log_level_highlight_end[level]); - } - } - - // OAI printf compatibility - if ((g_log->onlinelog == 1) && (level != LOG_FILE)) { - fprintf(stdout, "%s", log_buffer); - } - - if (g_log->syslog) { - syslog(g_log->level, "%s", log_buffer); - } - - if (g_log->filelog) { - if (write(gfd, log_buffer, total_len) < total_len) { - // TODO assert ? - } - } - - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - if (write(g_log->log_component[comp].fd, log_buffer, total_len) < total_len) { - // TODO assert ? - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, - VCD_FUNCTION_OUT); -} - -#if !defined(LOG_NO_THREAD) -void *log_thread_function(void *list) -{ - - LOG_params log_params; - - for(;;) { - - //log_elt = NULL; - - /* Lock must be taken to wait on conditional variable */ - pthread_mutex_lock(&log_lock); - - /* Wait on condition variable, check for spurious wakeups. - When returning from pthread_cond_wait(), we own the lock. */ - - // sleep - while((log_list_nb_elements == 0) && (log_shutdown == 0)) { - pthread_cond_wait(&log_notify, &log_lock); - } - - // exit - if ((log_shutdown==1) && (log_list_nb_elements == 0)) { - break; - } - - /* Grab our task */ - //log_elt = log_list_remove_head(&log_list); - log_params = log_list[log_list_head]; - log_list_head++; - log_list_nb_elements--; - - if (log_list_head >= 1000) { - log_list_head = 0; - } - - - /* Unlock */ - pthread_mutex_unlock(&log_lock); - - /* Get to work */ - logRecord_thread_safe(log_params.file, - log_params.func, - log_params.line, - log_params.comp, - log_params.level, - log_params.len, - log_params.l_buff_info); - - //free(log_elt); - } -} -#endif - -#if 0 -/* This function does not work. When multiple threads call it at the same time - * for the same component, both threads end up using the same buffer. - * The output is the completely messed up/wrong. - * Kept in case the fix below is not correct or acceptable. - */ -//log record, format, and print: executed in the main thread (mt) -void logRecord_mt(const char *file, const char *func, int line, int comp, - int level, const char *format, ...) -{ - int len = 0; - va_list args; - log_component_t *c; - char *log_start; - char *log_end; - - /* for no gcc warnings */ - (void)log_start; - (void)log_end; - - c = &g_log->log_component[comp]; - - // do not apply filtering for LOG_F - // only log messages which are enabled and are below the global log level and component's level threshold - if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { - /* if ((level != LOG_FILE) && - ((level > c->level) || - (level > g_log->level) || - ( c->level > g_log->level))) { - */ - return; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, - VCD_FUNCTION_IN); - - va_start(args, format); - - // adjust syslog level for TRACE messages - if (g_log->syslog) { - if (g_log->level > LOG_DEBUG) { - g_log->level = LOG_DEBUG; - } - } - - // make sure that for log trace the extra info is only printed once, reset when the level changes - if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { - log_start = c->log_buffer; - len = vsnprintf(c->log_buffer, MAX_LOG_TOTAL-1, format, args); - log_end = c->log_buffer + len; - } else { - if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { - len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "%s", - log_level_highlight_start[level]); - } - - log_start = c->log_buffer + len; - - if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { - len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", - g_log->log_component[comp].name); - } - - if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { - len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", - g_log->level2string[level]); - } - - if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { - len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", - func); - } - - if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { - len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", - file, line); - } - - len += vsnprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, format, args); - log_end = c->log_buffer + len; - - if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { - len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "%s", - log_level_highlight_end[level]); - } - } - - va_end(args); - - // OAI printf compatibility - if ((g_log->onlinelog == 1) && (level != LOG_FILE)) - fwrite(c->log_buffer, len, 1, stdout); - - if (g_log->syslog) { - syslog(g_log->level, "%s", c->log_buffer); - } - - if (g_log->filelog) { - if (write(gfd, c->log_buffer, len) < len) { - // TODO assert ? - } - } - - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - if (write(g_log->log_component[comp].fd, c->log_buffer, len) < len) { - // TODO assert ? - } - } - -#if defined(ENABLE_ITTI) - - if (level <= LOG_DEBUG) { - task_id_t origin_task_id = TASK_UNKNOWN; - MessagesIds messages_id; - MessageDef *message_p; - size_t message_string_size; - char *message_msg_p; - - message_string_size = log_end - log_start; - -#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) - - /* Try to identify sub task ID from log information (comp, log_instance_type) */ - switch (comp) { - case PHY: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_PHY_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_PHY_UE; - break; - - default: - break; - } - - break; - - case MAC: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_MAC_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_MAC_UE; - - default: - break; - } - - break; - - case RLC: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_RLC_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_RLC_UE; - - default: - break; - } - - break; - - case PDCP: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_PDCP_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_PDCP_UE; - - default: - break; - } - - break; - - default: - break; - } - -#endif - - switch (level) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - messages_id = ERROR_LOG; - break; - - case LOG_WARNING: - messages_id = WARNING_LOG; - break; - - case LOG_NOTICE: - messages_id = NOTICE_LOG; - break; - - case LOG_INFO: - messages_id = INFO_LOG; - break; - - default: - messages_id = DEBUG_LOG; - break; - } - - message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); - - switch (level) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - message_msg_p = (char *) &message_p->ittiMsg.error_log; - break; - - case LOG_WARNING: - message_msg_p = (char *) &message_p->ittiMsg.warning_log; - break; - - case LOG_NOTICE: - message_msg_p = (char *) &message_p->ittiMsg.notice_log; - break; - - case LOG_INFO: - message_msg_p = (char *) &message_p->ittiMsg.info_log; - break; - - default: - message_msg_p = (char *) &message_p->ittiMsg.debug_log; - break; - } - - memcpy(message_msg_p, log_start, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); - } - -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, - VCD_FUNCTION_OUT); -} -#endif /* #if 0 */ - -//log record, format, and print: executed in the main thread (mt) -void logRecord_mt(const char *file, const char *func, int line, int comp, - int level, const char *format, ...) -{ - int len = 0; - va_list args; - log_component_t *c; - char *log_start; - char *log_end; - /* The main difference with the version above is the use of this local log_buffer. - * The other difference is the return value of snprintf which was not used - * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is - * big enough so that the buffer is never full. - */ - char log_buffer[MAX_LOG_TOTAL]; - - /* for no gcc warnings */ - (void)log_start; - (void)log_end; - - c = &g_log->log_component[comp]; - - // do not apply filtering for LOG_F - // only log messages which are enabled and are below the global log level and component's level threshold - if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { - /* if ((level != LOG_FILE) && - ((level > c->level) || - (level > g_log->level) || - ( c->level > g_log->level))) { - */ - return; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, - VCD_FUNCTION_IN); - - va_start(args, format); - - // adjust syslog level for TRACE messages - if (g_log->syslog) { - if (g_log->level > LOG_DEBUG) { - g_log->level = LOG_DEBUG; - } - } - - // make sure that for log trace the extra info is only printed once, reset when the level changes - if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { - log_start = log_buffer; - len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - log_end = log_buffer + len; - } else { - if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", - log_level_highlight_start[level]); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - log_start = log_buffer + len; - - if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", - g_log->log_component[comp].name); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", - g_log->level2string[level]); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { -# define THREAD_NAME_LEN 128 - char threadname[THREAD_NAME_LEN]; - if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) - { - perror("pthread_getname_np : "); - } else { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } -# undef THREAD_NAME_LEN - } - - if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", - func); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", - file, line); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - - len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - log_end = log_buffer + len; - - if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { - len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", - log_level_highlight_end[level]); - if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; - } - } - - va_end(args); - - // OAI printf compatibility - if ((g_log->onlinelog == 1) && (level != LOG_FILE)) - fwrite(log_buffer, len, 1, stdout); - - if (g_log->syslog) { - syslog(g_log->level, "%s", log_buffer); - } - - if (g_log->filelog) { - if (write(gfd, log_buffer, len) < len) { - // TODO assert ? - } - } - - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - if (write(g_log->log_component[comp].fd, log_buffer, len) < len) { - // TODO assert ? - } - } - -#if defined(ENABLE_ITTI) - - if (level <= LOG_DEBUG) { - task_id_t origin_task_id = TASK_UNKNOWN; - MessagesIds messages_id; - MessageDef *message_p; - size_t message_string_size; - char *message_msg_p; - - message_string_size = log_end - log_start; - -#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) - - /* Try to identify sub task ID from log information (comp, log_instance_type) */ - switch (comp) { - case PHY: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_PHY_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_PHY_UE; - break; - - default: - break; - } - - break; - - case MAC: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_MAC_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_MAC_UE; - - default: - break; - } - - break; - - case RLC: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_RLC_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_RLC_UE; - - default: - break; - } - - break; - - case PDCP: - switch (log_instance_type) { - case LOG_INSTANCE_ENB: - origin_task_id = TASK_PDCP_ENB; - break; - - case LOG_INSTANCE_UE: - origin_task_id = TASK_PDCP_UE; - - default: - break; - } - - break; - - default: - break; - } - -#endif - - switch (level) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - messages_id = ERROR_LOG; - break; - - case LOG_WARNING: - messages_id = WARNING_LOG; - break; - - case LOG_NOTICE: - messages_id = NOTICE_LOG; - break; - - case LOG_INFO: - messages_id = INFO_LOG; - break; - - default: - messages_id = DEBUG_LOG; - break; - } - - message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); - - switch (level) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - message_msg_p = (char *) &message_p->ittiMsg.error_log; - break; - - case LOG_WARNING: - message_msg_p = (char *) &message_p->ittiMsg.warning_log; - break; - - case LOG_NOTICE: - message_msg_p = (char *) &message_p->ittiMsg.notice_log; - break; - - case LOG_INFO: - message_msg_p = (char *) &message_p->ittiMsg.info_log; - break; - - default: - message_msg_p = (char *) &message_p->ittiMsg.debug_log; - break; - } - - memcpy(message_msg_p, log_start, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); - } - -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, - VCD_FUNCTION_OUT); -} - -int set_log(int component, int level, int interval) -{ - /* Checking parameters */ - DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), - component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); - DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, - LOG_EMERG); - DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); - - g_log->log_component[component].level = level; - - switch (level) { - case LOG_TRACE: - g_log->log_component[component].flag = LOG_MED ; - break; - - case LOG_DEBUG: - g_log->log_component[component].flag = LOG_MED ; - break; - - case LOG_INFO: - g_log->log_component[component].flag = LOG_LOW ; - break; - - default: - g_log->log_component[component].flag = LOG_NONE ; - break; - } - - g_log->log_component[component].interval = interval; - - return 0; -} - -int set_comp_log(int component, int level, int verbosity, int interval) -{ - /* Checking parameters */ - DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), - component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); - DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, - LOG_EMERG); - DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); - -#if 0 - if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) || - (verbosity == LOG_MED) || (verbosity == LOG_FULL) || - (verbosity == LOG_HIGH)) { - g_log->log_component[component].flag = verbosity; - } -#else - g_log->log_component[component].flag = verbosity; -#endif - - g_log->log_component[component].level = level; - g_log->log_component[component].interval = interval; - - return 0; -} - -void set_glog(int level, int verbosity) -{ - if( g_log->level >= 0) g_log->level = level; - if( g_log->flag >= 0) g_log->flag = verbosity; -} -void set_glog_syslog(int enable) -{ - g_log->syslog = enable; -} -void set_glog_onlinelog(int enable) -{ - g_log->onlinelog = enable; -} -void set_glog_filelog(int enable) -{ - g_log->filelog = enable; -} - -void set_component_filelog(int comp) -{ - if (g_log->log_component[comp].filelog == 0) { - g_log->log_component[comp].filelog = 1; - - if (g_log->log_component[comp].fd == 0) { - g_log->log_component[comp].fd = open(g_log->log_component[comp].filelog_name, - O_WRONLY | O_CREAT | O_TRUNC, 0666); - } - } -} - -/* - * for the two functions below, the passed array must have a final entry - * with string value NULL - */ -/* map a string to an int. Takes a mapping array and a string as arg */ -int map_str_to_int(mapping *map, const char *str) -{ - while (1) { - if (map->name == NULL) { - return(-1); - } - - if (!strcmp(map->name, str)) { - return(map->value); - } - - map++; - } -} - -/* map an int to a string. Takes a mapping array and a value */ -char *map_int_to_str(mapping *map, int val) -{ - while (1) { - if (map->name == NULL) { - return NULL; - } - - if (map->value == val) { - return map->name; - } - - map++; - } -} - -int is_newline( char *str, int size) -{ - int i; - - for ( i = 0; i < size; i++ ) { - if ( str[i] == '\n' ) { - return 1; - } - } - - /* if we get all the way to here, there must not have been a newline! */ - return 0; -} - -void logClean (void) -{ - int i; - - if (g_log->syslog) { - closelog(); - } - - if (g_log->filelog) { - close(gfd); - } - - for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - if (g_log->log_component[i].filelog) { - close(g_log->log_component[i].fd); - } - } -} - -#if defined(ENABLE_ITTI) -void log_set_instance_type (log_instance_type_t instance) -{ - log_instance_type = instance; -} -#endif - -#ifdef LOG_TEST - -int main(int argc, char *argv[]) -{ - - logInit(); - - //set_log_syslog(1); - test_log(); - - return 1; -} - -int test_log(void) -{ - LOG_ENTER(MAC); // because the default level is DEBUG - LOG_I(EMU, "1 Starting OAI logs version %s Build date: %s on %s\n", - BUILD_VERSION, BUILD_DATE, BUILD_HOST); - LOG_D(MAC, "1 debug MAC \n"); - LOG_N(MAC, "1 notice MAC \n"); - LOG_W(MAC, "1 warning MAC \n"); - - set_comp_log(EMU, LOG_INFO, FLAG_ONLINE); - set_comp_log(MAC, LOG_WARNING, 0); - - LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n", - BUILD_VERSION, BUILD_DATE, BUILD_HOST); - LOG_E(MAC, "2 emerge MAC\n"); - LOG_D(MAC, "2 debug MAC \n"); - LOG_N(MAC, "2 notice MAC \n"); - LOG_W(MAC, "2 warning MAC \n"); - LOG_I(MAC, "2 info MAC \n"); - - - set_comp_log(MAC, LOG_NOTICE, 1); - - LOG_ENTER(MAC); - LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n", - BUILD_VERSION, BUILD_DATE, BUILD_HOST); - LOG_D(MAC, "3 debug MAC \n"); - LOG_N(MAC, "3 notice MAC \n"); - LOG_W(MAC, "3 warning MAC \n"); - LOG_I(MAC, "3 info MAC \n"); - - set_comp_log(MAC, LOG_DEBUG,1); - set_comp_log(EMU, LOG_DEBUG,1); - - LOG_ENTER(MAC); - LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n", - BUILD_VERSION, BUILD_DATE, BUILD_HOST); - LOG_D(MAC, "4 debug MAC \n"); - LOG_N(MAC, "4 notice MAC \n"); - LOG_W(MAC, "4 warning MAC \n"); - LOG_I(MAC, "4 info MAC \n"); - - - set_comp_log(MAC, LOG_DEBUG,0); - set_comp_log(EMU, LOG_DEBUG,0); - - LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n", - BUILD_VERSION, BUILD_DATE, BUILD_HOST); - LOG_D(MAC, "5 debug MAC \n"); - LOG_N(MAC, "5 notice MAC \n"); - LOG_W(MAC, "5 warning MAC \n"); - LOG_I(MAC, "5 info MAC \n"); - - - set_comp_log(MAC, LOG_TRACE,0X07F); - set_comp_log(EMU, LOG_TRACE,0X07F); - - LOG_ENTER(MAC); - LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n", - BUILD_VERSION, BUILD_DATE, BUILD_HOST); - LOG_D(MAC, "6 debug MAC \n"); - LOG_N(MAC, "6 notice MAC \n"); - LOG_W(MAC, "6 warning MAC \n"); - LOG_I(MAC, "6 info MAC \n"); - LOG_EXIT(MAC); - - return 0; -} -#endif diff --git a/openair3/NAS/COMMON/UTIL/nas_timer.c b/openair3/NAS/COMMON/UTIL/nas_timer.c index 7ddcb61d1d..9ccca12520 100644 --- a/openair3/NAS/COMMON/UTIL/nas_timer.c +++ b/openair3/NAS/COMMON/UTIL/nas_timer.c @@ -43,13 +43,7 @@ Description Timer utilities #include // memset #include // malloc, free #include // setitimer - -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#else -# include -# include // clock_gettime -#endif +#include "intertask_interface.h" #include "nas_timer.h" #include "commonDef.h" #include "msc.h" @@ -69,11 +63,7 @@ Description Timer utilities * value when the timer entry was allocated. */ typedef struct { -#if defined(ENABLE_ITTI) - long timer_id; /* Timer id returned by the timer API from ITTI */ -#else - pthread_t pid; /* Thread identifier of the callback */ -#endif +long timer_id; /* Timer id returned by the timer API from ITTI */ struct timeval itv; /* Initial interval timer value */ struct timeval tv; /* Interval timer value */ @@ -105,10 +95,6 @@ typedef struct { #define TIMER_DATABASE_SIZE 256 timer_queue_t tq[TIMER_DATABASE_SIZE]; timer_queue_t *head;/* Pointer to the first timer entry to be fired */ - -#if !defined(ENABLE_ITTI) - pthread_mutex_t mutex; -#endif } nas_timer_database_t; /* @@ -118,25 +104,15 @@ static nas_timer_database_t _nas_timer_db = { 0, {}, NULL -#if !defined(ENABLE_ITTI) - , PTHREAD_MUTEX_INITIALIZER -#endif }; -#if defined(ENABLE_ITTI) #define nas_timer_lock_db() #define nas_timer_unlock_db() -#else -#define nas_timer_lock_db() pthread_mutex_lock(&_nas_timer_db.mutex) -#define nas_timer_unlock_db() pthread_mutex_unlock(&_nas_timer_db.mutex) -#endif /* * The handler executed whenever the system timer expires */ -#if !defined(ENABLE_ITTI) -static void _nas_timer_handler(int signal); -#endif + /* * ----------------------------------------------------------------------------- @@ -191,33 +167,6 @@ int nas_timer_init(void) /* Initialize the timer database */ _nas_timer_db_init(); -#if !defined(ENABLE_ITTI) - /* Setup the timer database handler */ - struct sigaction act; - - (void) memset (&act, 0, sizeof (act)); - (void) sigfillset (&act.sa_mask); - (void) sigdelset (&act.sa_mask, SIGHUP); - (void) sigdelset (&act.sa_mask, SIGINT); - (void) sigdelset (&act.sa_mask, SIGTERM); - (void) sigdelset (&act.sa_mask, SIGILL); - (void) sigdelset (&act.sa_mask, SIGTRAP); - (void) sigdelset (&act.sa_mask, SIGIOT); -# ifndef LINUX - (void) sigdelset (&act.sa_mask, SIGEMT); -# endif - (void) sigdelset (&act.sa_mask, SIGFPE); - (void) sigdelset (&act.sa_mask, SIGBUS); - (void) sigdelset (&act.sa_mask, SIGSEGV); - (void) sigdelset (&act.sa_mask, SIGSYS); - - act.sa_handler = _nas_timer_handler; - - if ( sigaction (SIGALRM, &act, 0) < 0 ) { - return (RETURNerror); - } - -#endif return (RETURNok); } @@ -243,10 +192,8 @@ int nas_timer_start(long sec, nas_timer_callback_t cb, void *args) { int id; nas_timer_entry_t *te; -#if defined(ENABLE_ITTI) int ret; long timer_id; -#endif /* Do not start null timer */ if (sec == 0) { @@ -270,7 +217,6 @@ int nas_timer_start(long sec, nas_timer_callback_t cb, void *args) /* Insert the new entry into the timer queue */ _nas_timer_db_insert_entry(id, te); -#if defined(ENABLE_ITTI) # if defined(NAS_MME) ret = timer_setup(sec, 0, TASK_NAS_MME, INSTANCE_DEFAULT, TIMER_PERIODIC, args, &timer_id); # else @@ -280,10 +226,7 @@ int nas_timer_start(long sec, nas_timer_callback_t cb, void *args) if (ret == -1) { return NAS_TIMER_INACTIVE_ID; } - te->timer_id = timer_id; -#endif - return (id); } @@ -309,11 +252,7 @@ int nas_timer_stop(int id) nas_timer_entry_t *entry; /* Remove the entry from the timer queue */ entry = _nas_timer_db_remove_entry(id); -#if defined(ENABLE_ITTI) timer_remove(entry->timer_id); -#else - (void)entry; -#endif /* Delete the timer entry */ _nas_timer_db_delete_entry(id); return (NAS_TIMER_INACTIVE_ID); @@ -380,7 +319,7 @@ int nas_timer_restart(int id) ** Others: _nas_timer_db ** ** ** ***************************************************************************/ -#if defined(ENABLE_ITTI) + void nas_timer_handle_signal_expiry(long timer_id, void *arg_p) { /* Get the timer entry for which the system timer expired */ @@ -388,25 +327,7 @@ void nas_timer_handle_signal_expiry(long timer_id, void *arg_p) te->cb(te->args); } -#else -static void _nas_timer_handler(int signal) -{ - /* At least one timer has been started */ - assert( (_nas_timer_db.head != NULL) && (_nas_timer_db.head->entry != NULL) ); - /* Get the timer entry for which the system timer expired */ - nas_timer_entry_t *te = _nas_timer_db.head->entry; - - threadCreate (&te->pid, te->cb, te->args, "nas-timer", -1, OAI_PRIORITY_RT_LOW); - - void *result = NULL; - (void) pthread_join(te->pid, &result); - - if (result) { - free(result); - } -} -#endif /* * ----------------------------------------------------------------------------- @@ -605,17 +526,7 @@ static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t *te) restart = _nas_timer_db_insert(&_nas_timer_db.tq[id]); nas_timer_unlock_db(); -#if !defined(ENABLE_ITTI) - - if (restart) { - /* The new entry is the first entry of the list; - * restart the system timer */ - setitimer(ITIMER_REAL, &it, 0); - } - -#else (void)(restart); -#endif } static int _nas_timer_db_insert(timer_queue_t *entry) @@ -704,21 +615,8 @@ static nas_timer_entry_t *_nas_timer_db_remove_entry(int id) tv.tv_usec = ts.tv_nsec/1000; /* tv = tv - time() */ rc = _nas_timer_sub(&_nas_timer_db.head->entry->tv, &tv, &it.it_value); - -#if defined(ENABLE_ITTI) timer_remove(_nas_timer_db.head->entry->timer_id); (void) (rc); -#else - - if (rc < 0) { - /* The system timer should have already expired */ - _nas_timer_handler(SIGALRM); - } else { - /* Restart the system timer */ - setitimer(ITIMER_REAL, &it, 0); - } - -#endif } /* Return a pointer to the removed entry */ @@ -749,17 +647,6 @@ static int _nas_timer_db_remove(timer_queue_t *entry) /* Other timers are scheduled to expire */ return TRUE; } - -#if !defined(ENABLE_ITTI) - { - /* No more timer is scheduled to expire; stop the system timer */ - struct itimerval it; - it.it_interval.tv_sec = it.it_interval.tv_usec = 0; - it.it_value.tv_sec = it.it_value.tv_usec = 0; - setitimer(ITIMER_REAL, &it, 0); - return FALSE; - } -#endif } /* The entry was NOT the first entry of the list */ diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 48730f2ca9..3b5bad7529 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -61,9 +61,7 @@ Description Defines the PDN connectivity ESM procedure executed by the #include "emm_sap.h" -#if defined(ENABLE_ITTI) # include "assertions.h" -#endif /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 6df6666638..d712a7b7f0 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -20,7 +20,6 @@ */ #include "utils.h" -#if defined(ENABLE_ITTI) # include "assertions.h" # include "intertask_interface.h" # include "nas_ue_task.h" @@ -301,4 +300,3 @@ char *make_port_str_from_ueid(const char *base_port_str, int ueid) { return itoa(port); } -#endif diff --git a/openair3/NAS/UE/nas_ue_task.h b/openair3/NAS/UE/nas_ue_task.h index c9890719cb..5615f366b7 100644 --- a/openair3/NAS/UE/nas_ue_task.h +++ b/openair3/NAS/UE/nas_ue_task.h @@ -33,8 +33,6 @@ typedef struct { nas_user_t *find_user_from_fd(nas_user_container_t *users, int fd); -# if defined(ENABLE_ITTI) void *nas_ue_task(void *args_p); -# endif #endif /* NAS_TASK_H_ */ diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 16b86cfd64..757ad6f75d 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -41,49 +41,22 @@ #include "common/utils/LOG/log.h" #include "targets/RT/USER/lte-softmodem.h" +char *get_devname(int devtype) { +char *devnames[MAX_RF_DEV_TYPE]=DEVTYPE_NAMES; + if (devtype < MAX_RF_DEV_TYPE && devtype !=MIN_RF_DEV_TYPE ) + return devnames[devtype]; + return "none"; +} + int set_device(openair0_device *device) { - switch (device->type) { - case EXMIMO_DEV: - LOG_I(HW,"[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case USRP_B200_DEV: - LOG_I(HW,"[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case USRP_X300_DEV: - LOG_I(HW,"[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case BLADERF_DEV: - LOG_I(HW,"[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case LMSSDR_DEV: - LOG_I(HW,"[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case IRIS_DEV: - LOG_I(HW,"[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case ADRV9371_ZC706_DEV: - LOG_I(HW,"[%s] has loaded ADRV9371_ZC706 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case UEDv2_DEV: - LOG_I(HW,"[%s] has loaded UEDv2 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - case NONE_DEV: - LOG_I(HW,"[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - - default: + char *devname = get_devname(device->type); + if (strcmp(devname,"none") != 0) { + LOG_I(HW,"[%s] has loaded %s device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),devname); + } else { LOG_E(HW,"[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); return -1; - } + } return 0; } @@ -108,7 +81,7 @@ int set_transport(openair0_device *device) } typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); -//loader_shlibfunc_t shlib_fdesc[2]; + /* look for the interface library and load it */ int load_lib(openair0_device *device, @@ -119,7 +92,14 @@ int load_lib(openair0_device *device, loader_shlibfunc_t shlib_fdesc[1]; int ret=0; char *libname; - if ( IS_SOFTMODEM_BASICSIM ) { + + openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state)); + + if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) { + libname=OAI_IQPLAYER_LIBNAME; + shlib_fdesc[0].fname="device_init"; + set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms + } else if ( IS_SOFTMODEM_BASICSIM ) { libname=OAI_BASICSIM_LIBNAME; shlib_fdesc[0].fname="device_init"; } else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) { diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 03ab4da5f9..7e51bdc81a 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -35,15 +35,19 @@ #include #include #include +#include "record_player.h" -/* name of shared library implementing the radio front end */ +/* default name of shared library implementing the radio front end */ #define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ #define OAI_TP_LIBNAME "oai_transpro" -/* name of shared library implementing the basic/rf simulator */ +/* name of shared library implementing the rf simulator */ #define OAI_RFSIM_LIBNAME "rfsimulator" -/* name of shared library implementing the basic/rf simulator */ +/* name of shared library implementing the basic simulator */ #define OAI_BASICSIM_LIBNAME "tcp_bridge_oai" +/* name of shared library implementing the iq player */ +#define OAI_IQPLAYER_LIBNAME "oai_iqplayer" + /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 #define RAU_REMOTE_RADIO_HEAD 1 @@ -101,7 +105,7 @@ typedef enum { UEDv2_DEV, MAX_RF_DEV_TYPE } dev_type_t; - +#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"} /*!\brief transport protocol types */ typedef enum { @@ -145,6 +149,7 @@ typedef enum { gpsdo=2 } clock_source_t; + /*! \brief RF frontend parameters set by application */ typedef struct { //! Module ID for this configuration @@ -219,15 +224,9 @@ typedef struct { char *my_addr; //! local port number for Ethernet interface (eNB/BBU, UE) unsigned int my_port; -#if defined(USRP_REC_PLAY) - unsigned short sf_mode; // 1=record, 2=replay - char sf_filename[1024]; // subframes file path - unsigned int sf_max; // max number of recorded subframes - unsigned int sf_loops; // number of loops in replay mode - unsigned int sf_read_delay; // read delay in replay mode - unsigned int sf_write_delay; // write delay in replay mode - unsigned int eth_mtu; // ethernet MTU -#endif + //! record player configuration, definition in record_player.h + uint32_t recplay_mode; + recplay_conf_t *recplay_conf; //! number of samples per tti unsigned int samples_per_tti; //! the sample rate for receive. @@ -298,7 +297,8 @@ struct openair0_device_t { /* !brief ETH params set by application */ eth_params_t *eth_params; - + //! record player data, definition in record_player.h + recplay_state_t *recplay_state; /* !brief Indicates if device already initialized */ int is_init; @@ -443,11 +443,13 @@ typedef struct { #define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) + #ifdef __cplusplus extern "C" { #endif - +/*! \brief get device name from device type */ +char *get_devname(int devtype); /*! \brief Initialize openair RF target. It returns 0 if OK */ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); /*! \brief Initialize transport protocol . It returns 0 if OK */ @@ -465,6 +467,11 @@ openair0_timestamp get_usrp_time(openair0_device *device); * \returns 0 in success */ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg); +/*! \brief read the iq record/player configuration */ +extern int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state); +/*! \brief store recorded iqs from memory to file. */ +extern void iqrecorder_end(openair0_device *device); + #define gettid() syscall(__NR_gettid) /*@}*/ diff --git a/targets/ARCH/COMMON/record_player.c b/targets/ARCH/COMMON/record_player.c new file mode 100644 index 0000000000..2dcd61e479 --- /dev/null +++ b/targets/ARCH/COMMON/record_player.c @@ -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 + */ + +/** record_player.c + * + * \author: Nokia bellLabs B. Mongazon F. Taburet + * + */ + +#include +#include +#include +#include +#include +#include "common/utils/LOG/log.h" +#include "assertions.h" +#include "common_lib.h" +#include "record_player.h" + +/*! \brief read the oai recorder or player configuration, called from common device code + * \param recplay_conf: store parameters + * recplay_state: store recorder or player data while the device runs + */ +int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) { + unsigned int u_sf_record = 0; // record mode + unsigned int u_sf_replay = 0; // replay mode + *recplay_conf = calloc(sizeof(recplay_conf_t),1); + paramdef_t device_recplay_params[]=DEVICE_RECPLAY_PARAMS_DESC ; + config_get(device_recplay_params,sizeof(device_recplay_params)/sizeof(paramdef_t),DEVICE_RECPLAY_SECTION); + + if (u_sf_record || u_sf_replay ) { + struct sysinfo systeminfo; + *recplay_state = calloc(sizeof(recplay_state_t),1); + + if ( *recplay_state == NULL) { + LOG_E(HW,"calloc error in %s\n", __FILE__); + return -1; + } + + // 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; + } + } else { /* record player enabled */ + free(*recplay_conf); + *recplay_conf=NULL; + } + + if (u_sf_replay == 1) return RECPLAY_REPLAYMODE; + else if (u_sf_record == 1) return RECPLAY_RECORDMODE; + + return 0; +} + +/*! \brief Terminate operation of the oai iq recorder. to be called by any device + * used in record mode + * \param device, the hardware used + */ +void iqrecorder_end(openair0_device *device) { + if (device->recplay_state != NULL) { // subframes store + iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,OAIIQFILE_ID}; + recplay_state_t *rs = device->recplay_state; + recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf; + rs->pFile = fopen (rc->u_sf_filename,"wb+"); + + if (rs->pFile == NULL) { + LOG_E(HW,"Cannot open %s\n", rc->u_sf_filename); + } else { + unsigned int i = 0; + unsigned int modu = 0; + + if ((modu = rs->nb_samples % 10) != 0) { + rs->nb_samples -= modu; // store entire number of frames + } + + LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename ); + fwrite(&fh, sizeof(fh), 1, rs->pFile); + LOG_UI(HW,"Writing %u subframes to %s \n",rs->nb_samples, rc->u_sf_filename ); + + for (i = 0; i < rs->nb_samples; i++) { + fwrite(rs->ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), rs->pFile); + } + + fclose (rs->pFile); + LOG_UI(HW,"File %s closed\n",rc->u_sf_filename ); + } + + if (rs->ms_sample != NULL) { + free((void *)rs->ms_sample); + rs->ms_sample = NULL; + } + } +} \ No newline at end of file diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h b/targets/ARCH/COMMON/record_player.h similarity index 81% rename from targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h rename to targets/ARCH/COMMON/record_player.h index d29cf41db2..903dda006b 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h +++ b/targets/ARCH/COMMON/record_player.h @@ -1,5 +1,5 @@ -#ifndef __USRP_LIB_H -#define __USRP_LIB_H +#ifndef __RECORD_PLAYER_H +#define __RECORD_PLAYER_H /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with @@ -21,7 +21,7 @@ * contact@openairinterface.org */ -/** usrp_lib.h +/** targets/ARCH/COMMON/record-player.h * * \author: bruno.mongazon-cazavet@nokia-bell-labs.com */ @@ -46,7 +46,7 @@ extern "C" /* command line parameters for USRP record/playback */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define USRP_DEVICE_PARAMS_DESC { \ +#define DEVICE_PARAMS_DESC { \ {CONFIG_OPT_RECPLAY, CONFIG_HLP_RECPLAY, PARAMFLAG_BOOL, uptr:&enable_recplay, defuintval:0, TYPE_UINT, 0} \ } @@ -59,6 +59,15 @@ extern "C" #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) + +#define OAIIQFILE_ID "OIQF" +typedef struct { + uint64_t devtype; + uint64_t tx_sample_advance; + double bw; + char oaiid[4]; +} iqfile_header_t; + typedef struct { int64_t header; int64_t ts; @@ -75,8 +84,8 @@ typedef struct { /* 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" +#define CONFIG_HLP_SF_REC "Record subframes from device driver into a file for later replay" +#define CONFIG_HLP_SF_REP "Replay subframes from a file using the oai replay driver" #define CONFIG_HLP_SF_MAX "Maximum count of subframes to be recorded in subframe file" #define CONFIG_HLP_SF_LOOPS "Number of loops to replay of the entire subframes file" #define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode" @@ -91,41 +100,43 @@ typedef struct { #define CONFIG_OPT_SF_RDELAY "subframes-read-delay" #define CONFIG_OPT_SF_WDELAY "subframes-write-delay" -#define USRP_RECPLAY_SECTION "device.recplay" +#define DEVICE_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 */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define USRP_RECPLAY_PARAMS_DESC { \ - {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}, \ +#define DEVICE_RECPLAY_PARAMS_DESC { \ + {CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:(char **)((*recplay_conf)->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_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->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_conf_t; + +typedef struct { + int use_mmap; // default is to use mmap + size_t mapsize; + FILE *pFile; + int mmapfd; + int iqfd; + iqrec_t *ms_sample; // memory for all subframes + unsigned int nb_samples; } recplay_state_t; -extern int read_usrpconfig(uint32_t *recplay_mode, recplay_state_t **recplay_state); + #ifdef __cplusplus } #endif -#endif // __USRP_LIB_H +#endif // __RECORD_PLAYER_H diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index eb8c6ec010..5135be0cd4 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -23,7 +23,8 @@ * * \author: HongliangXU : hong-liang-xu@agilent.com */ - +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 #include #include #include @@ -51,8 +52,6 @@ #include -#include "usrp_lib.h" - #ifdef __SSE4_1__ #include #endif @@ -108,8 +107,6 @@ 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) @@ -271,9 +268,6 @@ static int sync_to_gps(openair0_device *device) { static int trx_usrp_start(openair0_device *device) { usrp_state_t *s = (usrp_state_t *)device->priv; - if ( s->recplay_mode == RECPLAY_REPLAYMODE) - return 0; - // setup GPIO for TDD, GPIO(4) = ATR_RX //set data direction register (DDR) to output s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); @@ -316,86 +310,14 @@ static void trx_usrp_end(openair0_device *device) { return; usrp_state_t *s = (usrp_state_t *)device->priv; - + if (s == NULL) return; + iqrecorder_end(device); - 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 (s->recplay_mode == RECPLAY_RECORDMODE) { // subframes store - s->recplay_state->pFile = fopen (s->recplay_state->u_sf_filename,"wb+"); - - 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 = s->recplay_state->nb_samples % 10) != 0) { - s->recplay_state->nb_samples -= modu; // store entire number of frames - } - - std::cerr << "Writing " << s->recplay_state->nb_samples << " subframes to " << s->recplay_state->u_sf_filename << " ..." << std::endl; - - 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 (s->recplay_state->pFile); - std::cerr << "File " << s->recplay_state->u_sf_filename << " closed." << std::endl; - } - - if (s->recplay_state->ms_sample != NULL) { - free((void *)s->recplay_state->ms_sample); - s->recplay_state->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 (s->recplay_state->mmapfd != 0) { - close(s->recplay_state->mmapfd); - s->recplay_state->mmapfd = 0; - } - } else { - if (s->recplay_state->ms_sample != NULL) { - free(s->recplay_state->ms_sample); - s->recplay_state->ms_sample = NULL; - } - - if (s->recplay_state->iqfd != 0) { - close(s->recplay_state->iqfd); - s->recplay_state->iqfd = 0; - } - } - } -} -/*! \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 @@ -488,106 +410,6 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, 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 @@ -689,13 +511,13 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp 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 + if (device->recplay_state != NULL) { // 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++; + if (device->recplay_state->nb_samples < device->openair0_cfg->recplay_conf->u_sf_max) { + (device->recplay_state->ms_sample+device->recplay_state->nb_samples)->header = BELL_LABS_IQ_HEADER; + (device->recplay_state->ms_sample+device->recplay_state->nb_samples)->ts = *ptimestamp; + memcpy((device->recplay_state->ms_sample+device->recplay_state->nb_samples)->samples, buff[0], nsamps*4); + device->recplay_state->nb_samples++; } else exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n"); } @@ -909,7 +731,6 @@ extern "C" { } 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; @@ -918,90 +739,74 @@ extern "C" { device->trx_set_freq_func = trx_usrp_set_freq; device->trx_set_gains_func = trx_usrp_set_gains; - if ( s->recplay_mode == RECPLAY_REPLAYMODE) { - // Replay subframes from from file - int bw_gain_adjust=0; - device->type = USRP_B200_DEV; - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - 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->trx_write_func = trx_usrp_write_recplay; - device->trx_read_func = trx_usrp_read_recplay; - 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; + + // 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; + + if (device->openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) { + std::cerr << "USRP device initialized in subframes record mode" << std::endl; + } + + 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 { - // 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; - - if (s->recplay_mode == RECPLAY_RECORDMODE) { - std::cerr << "USRP device initialized in subframes record mode" << std::endl; - } - - 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); - } - - uhd::device_addrs_t device_adds = uhd::device::find(args); - - if (device_adds.size() == 0) { - LOG_E(HW,"No USRP Device Found.\n "); - free(s); - 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; - } - - LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str()); - double usrp_master_clock; - - if (device_adds[0].get("type") == "b200") { - printf("Found USRP b200\n"); - device->type = USRP_B200_DEV; - usrp_master_clock = 30.72e6; - 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 - usrp_master_clock = 122.88e6; - args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - //args += ", send_buff_size=33554432"; - } - - if (device_adds[0].get("type") == "x300") { - printf("Found USRP x300\n"); - 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"); - } - - s->usrp = uhd::usrp::multi_usrp::make(args); - - if (args.find("clock_source")==std::string::npos) { + args = 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); + + if (device_adds.size() == 0) { + LOG_E(HW,"No USRP Device Found.\n "); + free(s); + 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; + } + + LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str()); + double usrp_master_clock; + + if (device_adds[0].get("type") == "b200") { + printf("Found USRP b200\n"); + device->type = USRP_B200_DEV; + usrp_master_clock = 30.72e6; + 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 + usrp_master_clock = 122.88e6; + args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + //args += ", send_buff_size=33554432"; + } + + if (device_adds[0].get("type") == "x300") { + printf("Found USRP x300\n"); + 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"); + } + + s->usrp = uhd::usrp::multi_usrp::make(args); + + if (args.find("clock_source")==std::string::npos) { 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"); @@ -1023,358 +828,292 @@ extern "C" { else { LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n"); } - } - else { + } + 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) { - LOG_I(HW,"USRP synced with GPS!\n"); - } 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); - } - } - - if (device->type==USRP_X300_DEV) { - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info - LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); - - switch ((int)openair0_cfg[0].sample_rate) { - case 122880000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; //to be checked - openair0_cfg[0].tx_bw = 80e6; - openair0_cfg[0].rx_bw = 80e6; - break; - - case 92160000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; //to be checked - 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; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 40e6; - openair0_cfg[0].rx_bw = 40e6; - break; - - case 46080000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 40e6; - openair0_cfg[0].rx_bw = 40e6; - break; - - case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - - default: - LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } - - if (device->type == USRP_B200_DEV) { - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info - } else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info - } - - switch ((int)openair0_cfg[0].sample_rate) { - case 46080000: - s->usrp->set_master_clock_rate(46.08e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 40e6; - openair0_cfg[0].rx_bw = 40e6; - break; - - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - - default: - LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } - - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - - for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), - "RX Gain too high, lower by %f dB\n", - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } - } - - LOG_D(HW, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels()); - LOG_D(HW, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels); - - for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) { - ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); - - if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); - s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i); - LOG_I(HW,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); - } - } - - //s->usrp->set_clock_source("external"); - //s->usrp->set_time_source("external"); - // 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; - int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); - samples/=10000; - LOG_I(HW,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); - - if ( samples < max ) { - stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); - } - - LOG_I(HW,"rx_max_num_samps %zu\n", - s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); - - for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - - for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - - for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - - for (int i=0; iusrp->get_rx_rate(i)/1e6); - LOG_I(HW," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); - LOG_I(HW," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); - LOG_I(HW," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); - LOG_I(HW," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); - } - - for (int i=0; iusrp->get_tx_rate(i)/1e6); - LOG_I(HW," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); - 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,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - s->sample_rate = openair0_cfg[0].sample_rate; - - // TODO: - // init tx_forward_nsamps based usrp_time_offset ex - if(is_equal(s->sample_rate, (double)30.72e6)) - s->tx_forward_nsamps = 176; - - if(is_equal(s->sample_rate, (double)15.36e6)) - s->tx_forward_nsamps = 90; - - if(is_equal(s->sample_rate, (double)7.68e6)) - s->tx_forward_nsamps = 50; - } - - 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 (s->recplay_state->ms_sample == NULL) { - std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; - exit(-1); - } - - 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 - s->recplay_state->mmapfd = open(s->recplay_state->u_sf_filename, O_RDONLY | O_LARGEFILE); - - 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 (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(s->recplay_state->mmapfd); - exit(-1); - } - } else { - std::cerr << "Cannot mmap file, exiting." << std::endl; - close(s->recplay_state->mmapfd); - exit(-1); - } - } else { - std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << " , exiting." << std::endl; - exit(-1); - } - } else { - s->recplay_state->iqfd = open(s->recplay_state->u_sf_filename, O_RDONLY | O_LARGEFILE); - - 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 - s->recplay_state->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); - - if (s->recplay_state->ms_sample == NULL) { - std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; - close(s->recplay_state->iqfd); - exit(-1); - } - - memset(s->recplay_state->ms_sample, 0, sizeof(iqrec_t)); - - // point at beginning of file - 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 " << s->recplay_state->u_sf_filename << " , exiting." << std::endl; - exit(-1); - } - } - } - - return 0; } - - + + if (s->usrp->get_clock_source(0) == "gpsdo") { + s->use_gps = 1; + + if (sync_to_gps(device)==EXIT_SUCCESS) { + LOG_I(HW,"USRP synced with GPS!\n"); + } 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); + } + } + + if (device->type==USRP_X300_DEV) { + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info + LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); + + switch ((int)openair0_cfg[0].sample_rate) { + case 122880000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; //to be checked + openair0_cfg[0].tx_bw = 80e6; + openair0_cfg[0].rx_bw = 80e6; + break; + + case 92160000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; //to be checked + 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; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; + + case 46080000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; + + case 30720000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 15360000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + + case 7680000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + + case 1920000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; + break; + + default: + LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + + if (device->type == USRP_B200_DEV) { + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; + std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info + } + + switch ((int)openair0_cfg[0].sample_rate) { + case 46080000: + s->usrp->set_master_clock_rate(46.08e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; + + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + default: + LOG_E(HW,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + + for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) { + if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); + set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); + // limit to maximum gain + AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), + "RX Gain too high, lower by %f dB\n", + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); + LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i, + openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); + } + } + + LOG_D(HW, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels()); + LOG_D(HW, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels); + + for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) { + ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); + + if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); + s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i); + LOG_I(HW,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); + } + } + + //s->usrp->set_clock_source("external"); + //s->usrp->set_time_source("external"); + // 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; + int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); + samples/=10000; + LOG_I(HW,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); + + if ( samples < max ) { + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + } + + LOG_I(HW,"rx_max_num_samps %zu\n", + s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + + for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); + + /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ + for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + + for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); + + for (int i=0; iusrp->get_rx_rate(i)/1e6); + LOG_I(HW," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); + LOG_I(HW," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); + LOG_I(HW," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); + LOG_I(HW," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + } + + for (int i=0; iusrp->get_tx_rate(i)/1e6); + LOG_I(HW," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); + 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,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + s->sample_rate = openair0_cfg[0].sample_rate; + + // TODO: + // init tx_forward_nsamps based usrp_time_offset ex + if(is_equal(s->sample_rate, (double)30.72e6)) + s->tx_forward_nsamps = 176; + + if(is_equal(s->sample_rate, (double)15.36e6)) + s->tx_forward_nsamps = 90; + + if(is_equal(s->sample_rate, (double)7.68e6)) + s->tx_forward_nsamps = 50; + + + if (device->recplay_state != NULL) { // record mode + device->recplay_state->ms_sample = (iqrec_t *) malloc(openair0_cfg[0].recplay_conf->u_sf_max * sizeof(iqrec_t)); + + if (device->recplay_state->ms_sample == NULL) { + std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; + exit(-1); + } + + memset(device->recplay_state->ms_sample, 0, openair0_cfg[0].recplay_conf->u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + } + return 0; } /*@}*/ +}/* extern c */ \ No newline at end of file diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c deleted file mode 100644 index ebf1d61eed..0000000000 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c +++ /dev/null @@ -1,73 +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 - */ - -/** 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 diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c new file mode 100644 index 0000000000..beb05de3fd --- /dev/null +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -0,0 +1,307 @@ +/* + * 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 + */ + +/** iqplayer_lib.cpp + * + * \author:FrancoisTaburet: francois.taburet@nokia-bell-labs.com + */ +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common_lib.h" +#include "assertions.h" +#include "common/utils/LOG/log.h" + + + + + + +static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) { + AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),"iqfile doesn't seem to be compatible with oai (invalid id in header)\n"); + device->type = iq_fh->devtype; + device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance; + device->openair0_cfg[0].tx_bw = device->openair0_cfg[0].rx_bw = iq_fh->bw; + LOG_UI(HW,"Replay iqs from %s device, bandwidth %e\n",get_devname(iq_fh->devtype),iq_fh->bw); +} + + +/*! \brief Called to start the iqplayer device. Return 0 if OK, < 0 if error + @param device pointer to the device structure specific to the RF hardware target +*/ +static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair0_cfg) { + recplay_state_t *s = device->recplay_state; + recplay_conf_t *c = openair0_cfg->recplay_conf; + + if (s->use_mmap) { + // use mmap + s->mmapfd = open(c->u_sf_filename, O_RDONLY ); + + if (s->mmapfd != 0) { + struct stat sb; + fstat(s->mmapfd, &sb); + s->mapsize=sb.st_size; + LOG_I(HW,"Loading subframes using mmap() from %s size=%lu bytes ...\n",c->u_sf_filename, (uint64_t)sb.st_size ); + void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) ; + s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->mmapfd, 0) + sizeof(iqfile_header_t)); + + if (mptr != MAP_FAILED) { + parse_iqfile_header(device, (iqfile_header_t *)mptr); + s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t)); + s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t)) / sizeof(iqrec_t)); + int aligned = (((unsigned long)s->ms_sample & 31) == 0)? 1:0; + LOG_I(HW,"Loaded %u subframes.\n",s->nb_samples ); + + if (aligned == 0) { + LOG_E(HW, "mmap address is not 32 bytes aligned, exiting.\n" ); + close(s->mmapfd); + exit(-1); + } + } else { + LOG_E(HW,"Cannot mmap file, exiting.\n"); + close(s->mmapfd); + exit(-1); + } + } else { + LOG_E( HW,"Cannot open %s exiting.\n", c->u_sf_filename ); + exit(-1); + } + } else { + s->iqfd = open(c->u_sf_filename, O_RDONLY); + + if (s->iqfd != 0) { + struct stat sb; + iqfile_header_t fh; + size_t hs = read(s->iqfd,&fh,sizeof(fh)); + + if (hs == sizeof(fh)) { + parse_iqfile_header(device, &fh); + fstat(s->iqfd, &sb); + s->mapsize=sb.st_size; + s->nb_samples = ((sb.st_size-sizeof(iqfile_header_t))/ sizeof(iqrec_t)); + LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nb_samples, c->u_sf_filename,(uint64_t)sb.st_size); + // allocate buffer for 1 sample at a time + s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); + + if (s->ms_sample == NULL) { + LOG_E(HW,"Memory allocation failed for individual subframe replay mode.\n" ); + close(s->iqfd); + exit(-1); + } + + memset(s->ms_sample, 0, sizeof(iqrec_t)); + + // point at beginning of iqs in file + if (lseek(s->iqfd,sizeof(iqfile_header_t), SEEK_SET) == 0) { + LOG_I(HW,"Initial seek at beginning of the file\n" ); + } else { + LOG_I(HW,"Problem initial seek at beginning of the file\n"); + } + } else { + LOG_E(HW,"Cannot read header in %s exiting.\n",c->u_sf_filename ); + close(s->iqfd); + exit(-1); + } + } else { + LOG_E(HW,"Cannot open %s exiting.\n",c->u_sf_filename ); + exit(-1); + } + } + + return 0; +} + +/*! \brief Terminate operation of the oai iq player + * \param device, the hardware used + */ +static void trx_iqplayer_end(openair0_device *device) { + if (device == NULL) + return; + + if (device->recplay_state == NULL) + return; + + if (device->recplay_state->use_mmap) { + if (device->recplay_state->ms_sample != MAP_FAILED) { + munmap(device->recplay_state->ms_sample, device->recplay_state->mapsize); + device->recplay_state->ms_sample = NULL; + } + + if (device->recplay_state->mmapfd != 0) { + close(device->recplay_state->mmapfd); + device->recplay_state->mmapfd = 0; + } + } else { + if (device->recplay_state->ms_sample != NULL) { + free(device->recplay_state->ms_sample); + device->recplay_state->ms_sample = NULL; + } + + if (device->recplay_state->iqfd != 0) { + close(device->recplay_state->iqfd); + device->recplay_state->iqfd = 0; + } + } +} +/*! \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_iqplayer_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = device->openair0_cfg->recplay_conf->u_sf_write_delay * 1000; + nanosleep(&req, NULL); + return nsamps; +} + +/*! \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_iqplayer_read(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; + recplay_state_t *s = device->recplay_state; + + if (cur_samples == s->nb_samples) { + cur_samples = 0; + wrap_count++; + + if (wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) { + LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n",device->openair0_cfg->recplay_conf->u_sf_loops); + exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n"); + } + + wrap_ts = wrap_count * (s->nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); + + if (!device->recplay_state->use_mmap) { + if (lseek(device->recplay_state->iqfd, 0, SEEK_SET) == 0) { + LOG_I(HW,"Seeking at the beginning of IQ file"); + } else { + LOG_I(HW, "Problem seeking at the beginning of IQ file"); + } + } + } + + if (s->use_mmap) { + if (cur_samples < s->nb_samples) { + *ptimestamp = (s->ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; + + if (cur_samples == 0) { + LOG_I(HW,"starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu\n", wrap_count,wrap_ts,*ptimestamp); + } + + memcpy(buff[0], &s->ms_sample[cur_samples].samples[0], nsamps*4); + cur_samples++; + } + } else { + // read sample from file + if (read(s->iqfd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { + LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*cur_samples ); + close(s->iqfd); + free(s->ms_sample); + s->ms_sample = NULL; + s->iqfd = 0; + exit(-1); + } + + if (cur_samples < s->nb_samples) { + static int64_t ts0 = 0; + + if ((cur_samples == 0) && (wrap_count == 0)) { + ts0 = s->ms_sample->ts; + } + + *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; + + if (cur_samples == 0) { + LOG_I(HW, "starting subframes file with wrap_count=%lu wrap_ts=%lu ts=%lu ",wrap_count,wrap_ts, *ptimestamp); + } + + memcpy(buff[0], &s->ms_sample->samples[0], nsamps*4); + cur_samples++; + // Prepare for next read + off_t where = lseek(s->iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); + + if (where < 0) { + LOG_E(HW,"Cannot lseek in iqfile: %s\n",strerror(errno)); + exit(-1); + } + } + } + + struct timespec req; + + req.tv_sec = 0; + + req.tv_nsec = (device->openair0_cfg[0].recplay_conf->u_sf_read_delay) * 1000; + + nanosleep(&req, NULL); + + return nsamps; + + return samples_received; +} + + +int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + device->openair0_cfg = openair0_cfg; + device->trx_start_func = NULL; + device->trx_get_stats_func = NULL; + device->trx_reset_stats_func = NULL; + device->trx_end_func = trx_iqplayer_end; + device->trx_stop_func = NULL; + device->trx_set_freq_func = NULL; + device->trx_set_gains_func = NULL; + // Replay subframes from from file + // openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + // bw_gain_adjust=1; + device->trx_write_func = trx_iqplayer_write; + device->trx_read_func = trx_iqplayer_read; + iqplayer_loadfile(device, openair0_cfg); + LOG_UI(HW,"iqplayer device initialized, replay %s for %i iterations",openair0_cfg->recplay_conf->u_sf_filename,openair0_cfg->recplay_conf->u_sf_loops); + return 0; +} + +/*@}*/ diff --git a/targets/COMMON/create_nr_tasks.h b/targets/COMMON/create_nr_tasks.h index 7f5961f5ae..ca259a2b34 100644 --- a/targets/COMMON/create_nr_tasks.h +++ b/targets/COMMON/create_nr_tasks.h @@ -22,12 +22,10 @@ #ifndef CREATE_NR_TASKS_H_ #define CREATE_NR_TASKS_H_ -#if defined(ENABLE_ITTI) /* External declaration of L2L1 task that depend on the target */ extern void *l2l1_task(void *arg); int create_gNB_tasks(uint32_t gnb_nb); -#endif #endif /* CREATE_TASKS_H_ */ diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h index 339f4aaa8f..843897cefb 100644 --- a/targets/COMMON/create_tasks.h +++ b/targets/COMMON/create_tasks.h @@ -22,13 +22,11 @@ #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/COMMON/create_tasks_mbms.h b/targets/COMMON/create_tasks_mbms.h index 339f4aaa8f..843897cefb 100644 --- a/targets/COMMON/create_tasks_mbms.h +++ b/targets/COMMON/create_tasks_mbms.h @@ -22,13 +22,11 @@ #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-softmodem.c b/targets/RT/USER/lte-softmodem.c index eccece02ca..c08ab2a77b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -265,7 +265,7 @@ void exit_function(const char *file, const char *function, const int line, const static void get_options(void) { CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - get_common_options(); + get_common_options(SOFTMODEM_ENB_BIT ); CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index b468ff12d4..d0014b5e8a 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -79,10 +79,7 @@ #include "UTIL/OTG/otg_vars.h" #endif -#if defined(ENABLE_ITTI) - #include "create_tasks.h" -#endif - +#include "create_tasks.h" #include "system.h" @@ -300,7 +297,7 @@ static void get_options(void) { CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); /* unknown parameters on command line will be checked in main after all init have been performed */ - get_common_options(); + get_common_options(SOFTMODEM_4GUE_BIT ); get_uethreads_params(); paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; @@ -780,19 +777,11 @@ int main( int argc, char **argv ) { // wait for end of program printf("TYPE TO TERMINATE\n"); //getchar(); -#if defined(ENABLE_ITTI) printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); printf("Returned from ITTI signal handler\n"); oai_exit=1; printf("oai_exit=%d\n",oai_exit); -#else - - while (oai_exit==0) - rt_sleep_ns(100000000ULL); - - printf("Terminating application - oai_exit=%d\n",oai_exit); -#endif // stop threads if(IS_SOFTMODEM_DOFORMS) From e091f94ae786253ff232b9bba751f28c8d1af935 Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 12 Feb 2020 19:29:53 +0100 Subject: [PATCH 250/343] fix T_IDs.h build problem --- cmake_targets/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 01b1d6c273..80ea64700e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2866,7 +2866,7 @@ if (${T_TRACER}) nr_ulschsim ldpctest polartest smallblocktest cu_test du_test #all "add_library" definitions ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP - params_libconfig oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif + params_libconfig oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_iqplayer oai_eth_transpro oai_mobipass tcp_bridge tcp_bridge_oai coding FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL From ff4829284b84592005364ad79ae4a72dcf80b4b4 Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 12 Feb 2020 20:29:51 +0100 Subject: [PATCH 251/343] --amend --- common/utils/T/local_tracer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index 8cbd06490d..539e72b223 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -15,7 +15,7 @@ #include "T_messages.txt.h" #include "T_defs.h" #include "T_IDs.h" -#include "softmodem-common.h" + static T_cache_t *T_local_cache; static int T_busylist_head; @@ -357,7 +357,7 @@ static void forward(void *_forwarder, char *buf, int size) { if (f->tail != NULL) f->tail->next = new; f->tail = new; - if( IS_SOFTMODEM_BASICSIM){ +#if BASIC_SIMULATOR /* When runnng the basic simulator, the tracer may be too slow. * Let's not take too much memory in the tracee and * wait if there is too much data to send. 200MB is @@ -372,7 +372,7 @@ static void forward(void *_forwarder, char *buf, int size) { if (pthread_mutex_lock(&f->lock)) abort(); } - } +#endif f->memusage += size+4; /* warn every 100MB */ From 1e38ef5fde292229e97f780e6e43e0bfb9d1cdc7 Mon Sep 17 00:00:00 2001 From: Thomas Dreibholz Date: Thu, 13 Feb 2020 11:33:46 +0100 Subject: [PATCH 252/343] Using "--allow-unauthenticated" with apt-get disables package verification, allowing to install untrusted/modified packages into the development system. Fixed calls to apt-get to make sure that packages are verified. --- cmake_targets/tools/build_helper | 10 +++++----- .../ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index cdb7885945..6ed17649cc 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -296,8 +296,8 @@ check_install_usrp_uhd_driver(){ x=$((x + 1)) done $SUDO apt-get update - $SUDO apt-get -y --allow-unauthenticated install python python-tk libboost-all-dev libusb-1.0-0-dev - $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host + $SUDO apt-get -y install python python-tk libboost-all-dev libusb-1.0-0-dev + $SUDO apt-get -y install libuhd-dev libuhd003 uhd-host elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake $SUDO -H pip install requests @@ -367,9 +367,9 @@ check_install_bladerf_driver(){ $SUDO add-apt-repository -y ppa:bladerf/bladerf $SUDO apt-get update fi - $SUDO apt-get install -y --allow-unauthenticated bladerf libbladerf-dev - $SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3 - $SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40 + $SUDO apt-get install -y bladerf libbladerf-dev + $SUDO apt-get install -y bladerf-firmware-fx3 + $SUDO apt-get install -y bladerf-fpga-hostedx40 elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then install_bladerf_driver_from_source else diff --git a/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh b/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh index 6651a3beb8..e0d5289f00 100755 --- a/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh +++ b/targets/ARCH/ADRV9371_ZC706/SYRTEM_IQ_uninstall_previous_SW.sh @@ -4,7 +4,7 @@ MODULE="riffa" KERNEL_VERSION=$(uname -r) RHR=/etc/redhat-release -sudo apt-get install -y --allow-unauthenticated linux-headers-`uname -r` +sudo apt-get install -y linux-headers-`uname -r` if lsmod | grep "$MODULE" &> /dev/null ; then echo "Previous SYRIQ is loaded!" From 9f1350805c351cde3e98d20e58db89619c8c7224 Mon Sep 17 00:00:00 2001 From: matzakos Date: Thu, 13 Feb 2020 13:25:23 +0100 Subject: [PATCH 253/343] nr-ip-ul-nos1: Resolve some dependency issues to make the phy simulators compile --- openair1/SIMULATION/NR_PHY/dlsim.c | 51 ++++------------------------ openair1/SIMULATION/NR_PHY/pbchsim.c | 1 + openair1/SIMULATION/NR_PHY/ulsim.c | 49 +++----------------------- 3 files changed, 11 insertions(+), 90 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 2974c4634a..60b79c17c2 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -68,58 +68,19 @@ uint16_t NB_UE_INST = 1; //Dummy Functions lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms, unsigned char subframe) {return(SF_DL);} -int rlc_module_init (int enb) {return(0);} +//int rlc_module_init (int enb) {return(0);} void pdcp_layer_init (void) {} +boolean_t pdcp_data_ind( const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, mem_block_t *const sdu_buffer_pP) +{return (0);} + int rrc_init_nr_global_param (void) {return(0);} void config_common(int Mod_idP,int CC_idP,int Nid_cell,int nr_bandP,uint64_t SSB_positions,uint16_t ssb_periodicity,uint64_t dl_CarrierFreqP,uint32_t dl_BandwidthP); int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return(0);} uint64_t get_softmodem_optmask(void) {return 0;} -mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP, - const rnti_t rntiP, - const eNB_index_t eNB_index, - const frame_t frameP, - const sub_frame_t subframeP, - 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, - const uint32_t sourceL2Id, - const uint32_t destinationL2Id) {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, - const frame_t frameP, - 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, - char *buffer_pP, - const uint32_t sourceL2Id, - const uint32_t destinationL2Id) {return 0;} -int generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding){return 0;} void nr_ip_over_LTE_DRB_preconfiguration(void){} -void mac_rlc_data_ind ( - const module_id_t module_idP, - const rnti_t rntiP, - const eNB_index_t eNB_index, - const frame_t frameP, - const eNB_flag_t enb_flagP, - const MBMS_flag_t MBMS_flagP, - const logical_chan_id_t channel_idP, - char *buffer_pP, - const tb_size_t tb_sizeP, - num_tb_t num_tbP, - crc_t *crcs_pP) -{} + // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 33bfc02f33..58bf213e3a 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -60,6 +60,7 @@ uint16_t NB_UE_INST = 1; // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; +uint64_t get_softmodem_optmask(void) {return 0;} int main(int argc, char **argv) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index dcc1b82426..adfb09ea6e 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -70,53 +70,12 @@ uint16_t NB_UE_INST = 1; // dummy functions int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } -void mac_rlc_data_ind ( const module_id_t module_idP, - const rnti_t rntiP, - const eNB_index_t eNB_index, - const frame_t frameP, - const eNB_flag_t enb_flagP, - const MBMS_flag_t MBMS_flagP, - const logical_chan_id_t channel_idP, - char *buffer_pP, - const tb_size_t tb_sizeP, - num_tb_t num_tbP, - crc_t *crcs_pP){} -mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, - const rnti_t rntiP, - const eNB_index_t eNB_index, - const frame_t frameP, - const sub_frame_t subframeP, - 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, - const uint32_t sourceL2Id, - const uint32_t destinationL2Id) -{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, - const frame_t frameP, - 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, - char *buffer_pP, - const uint32_t sourceL2Id, - const uint32_t destinationL2Id ) -{return 0;} -int generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding){return 0;} uint64_t get_softmodem_optmask(void) {return 0;} -int rlc_module_init (int enb) {return(0);} +//int rlc_module_init (int enb) {return(0);} void pdcp_layer_init (void) {} +boolean_t pdcp_data_ind( const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, mem_block_t *const sdu_buffer_pP) +{return (0);} void nr_ip_over_LTE_DRB_preconfiguration(void){} // needed for some functions From b3334dbc2ead23a398b75a368fd2d2ef148fb570 Mon Sep 17 00:00:00 2001 From: frtabu Date: Thu, 13 Feb 2020 15:53:54 +0100 Subject: [PATCH 254/343] A fix proposal for phy simulators compilation Pb. --- cmake_targets/CMakeLists.txt | 6 +- executables/softmodem-common.c | 121 +++++++++++++++-------------- openair1/SIMULATION/NR_PHY/dlsim.c | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 1 - 4 files changed, 66 insertions(+), 63 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 038309d74c..116ed36832 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2771,6 +2771,7 @@ add_executable(nr_dlsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -2779,6 +2780,7 @@ target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) +target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) add_executable(nr_prachsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c @@ -2807,6 +2809,7 @@ add_executable(nr_ulsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/executables/softmodem-common.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -2815,7 +2818,7 @@ target_link_libraries(nr_ulsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) - +target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) @@ -2833,6 +2836,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) + endforeach(myExe) add_executable(test_epc_generate_scenario diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 00b974e3ae..e05f5b6513 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -60,6 +60,66 @@ softmodem_params_t *get_softmodem_params(void) { return &softmodem_params; } +void softmodem_printresources(int sig, telnet_printfunc_t pf) { + struct rusage usage; + struct timespec stop; + + clock_gettime(CLOCK_BOOTTIME, &stop); + + uint64_t elapse = (stop.tv_sec - start.tv_sec) ; // in seconds + + + int st = getrusage(RUSAGE_SELF,&usage); + if (!st) { + pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600))); + pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec); + pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec); + pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss); + pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt); + pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt); + pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock); + pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock); + pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw); + pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw); + } +} + +void signal_handler(int sig) { + void *array[10]; + size_t size; + + if (sig==SIGSEGV) { + // get void*'s for all entries on the stack + size = backtrace(array, 10); + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(-1); + } else { + if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL) + softmodem_printresources(sig,(telnet_printfunc_t)printf); + if (sig != SOFTMODEM_RTSIGNAL) { + printf("Linux signal %s...\n",strsignal(sig)); + exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n"); + } + } +} + + + +void set_softmodem_sighandler(void) { + struct sigaction act,oldact; + clock_gettime(CLOCK_BOOTTIME, &start); + memset(&act,0,sizeof(act)); + act.sa_handler=signal_handler; + sigaction(SOFTMODEM_RTSIGNAL,&act,&oldact); + printf("Send signal %d to display resource usage...\n",SIGRTMIN+1); + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); +} +#ifndef PHYSICAL_SIMULATOR void get_common_options(void) { uint32_t online_log_messages; uint32_t glog_level ; @@ -123,63 +183,4 @@ void get_common_options(void) { if(worker_config != NULL) set_worker_conf(worker_config); } - -void softmodem_printresources(int sig, telnet_printfunc_t pf) { - struct rusage usage; - struct timespec stop; - - clock_gettime(CLOCK_BOOTTIME, &stop); - - uint64_t elapse = (stop.tv_sec - start.tv_sec) ; // in seconds - - - int st = getrusage(RUSAGE_SELF,&usage); - if (!st) { - pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600))); - pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec); - pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec); - pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss); - pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt); - pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt); - pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock); - pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock); - pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw); - pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw); - } -} - -void signal_handler(int sig) { - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL) - softmodem_printresources(sig,(telnet_printfunc_t)printf); - if (sig != SOFTMODEM_RTSIGNAL) { - printf("Linux signal %s...\n",strsignal(sig)); - exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n"); - } - } -} - - - -void set_softmodem_sighandler(void) { - struct sigaction act,oldact; - clock_gettime(CLOCK_BOOTTIME, &start); - memset(&act,0,sizeof(act)); - act.sa_handler=signal_handler; - sigaction(SOFTMODEM_RTSIGNAL,&act,&oldact); - printf("Send signal %d to display resource usage...\n",SIGRTMIN+1); - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); -} +#endif \ No newline at end of file diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 473c86bed0..f53812cbff 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -109,7 +109,6 @@ void config_common(int Mod_idP, NR_ServingCellConfigCommon_t *scc ); -uint64_t get_softmodem_optmask(void) {return 0;} mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 2c397090ba..7e8e06a274 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -113,7 +113,6 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char *ue_cont_res_id, unsigned char short_padding, unsigned short post_padding){return 0;} -uint64_t get_softmodem_optmask(void) {return 0;} int rlc_module_init (int enb) {return(0);} void pdcp_layer_init (void) {} void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} From cc9d5136498379db0c2a6189800a47ce306154ee Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 14 Feb 2020 11:51:19 +0100 Subject: [PATCH 255/343] fixed txslot issue in realtime --- executables/nr-gnb.c | 1 + openair1/SIMULATION/NR_PHY/dlsim.c | 1 + 2 files changed, 2 insertions(+) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 8752e9b8c7..84aa00210d 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -147,6 +147,7 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { + sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; start_meas(&softmodem_stats_rxtx_sf); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index ba84abb3c2..54b8d6afee 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -77,6 +77,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; int sf_ahead=4, phy_test = 0; +int sl_ahead=0; uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; From 0d6fabb9b6c7d9e62da3be44838856f46c1572d1 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 14 Feb 2020 15:46:40 +0100 Subject: [PATCH 256/343] CI: fixed the iperf analysis in 5G-RF-SIM now that we have UL also added the UL test for 5G-RF-SIM Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 4 ++-- ci-scripts/runTestOnVM.sh | 38 ++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index c4236a4e0e..72779e3824 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -730,8 +730,8 @@ function report_test { 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 + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null` + analyzeIperfFiles done done done diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index e6440ffef9..d46ed07bbb 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -342,6 +342,7 @@ function check_iperf { local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` if [ $FILE_COMPLETE -eq 0 ] then + # This part will become obsolete once we have UL 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" @@ -350,11 +351,11 @@ function check_iperf { 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" + local BW_PREFIX="K" else - local BW_SUFFIX="M" + local BW_PREFIX="M" fi - if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_SUFFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_SUFFIX}bits.* ]] + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_PREFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_PREFIX}bits.* ]] then echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" else @@ -370,10 +371,19 @@ function check_iperf { 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 [ `egrep -c "Mbits/sec" ${LOC_BASE_LOG}_client.txt` -ne 0 ] + then + local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + local BW_PREFIX="M" + fi + if [ `egrep -c "Kbits/sec" ${LOC_BASE_LOG}_client.txt` -ne 0 ] + then + local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Kbits/sec" | sed -e "s#^.*KBytes *##" -e "s#sec.*#sec#"` + local BW_PREFIX="K" + fi if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] then - if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_THREE}.*Mbits.* ]] + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_PREFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_PREFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*${BW_PREFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_THREE}.*${BW_PREFIX}bits.* ]] then echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" else @@ -381,7 +391,7 @@ function check_iperf { IPERF_STATUS=-1 fi else - if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_PREFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_PREFIX}bits.* ]] then if [ $LOC_IS_DL -eq 1 ] then @@ -390,7 +400,7 @@ function check_iperf { echo "got requested UL bandwidth: $EFFECTIVE_BANDWIDTH" fi else - echo "not basic-sim got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + echo "got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" IPERF_STATUS=-1 fi fi @@ -2067,7 +2077,7 @@ function run_test_on_vm { fi echo "############################################################" - echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client" echo "############################################################" THROUGHPUT="30K" CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl @@ -2078,6 +2088,18 @@ function run_test_on_vm { 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} : iperf UL -- gNB is server and NR-UE is client" + echo "############################################################" + THROUGHPUT="30K" + CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul + 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 $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT + echo "############################################################" echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" echo "############################################################" From e0fd2de76d6c7c2fccc77dfa6c2ca31e59f9934b Mon Sep 17 00:00:00 2001 From: frtabu Date: Thu, 13 Feb 2020 17:16:03 +0100 Subject: [PATCH 257/343] replacing phy_test local variable from nr_dlsim.c and nr_ulsim.c with get_softmodem_params()->phy_test --- openair1/SIMULATION/NR_PHY/dlsim.c | 4 +++- openair1/SIMULATION/NR_PHY/ulsim.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index f53812cbff..7459cfe072 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -76,7 +76,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int sf_ahead=4, phy_test = 0; +int sf_ahead=4 ; uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; @@ -447,6 +447,8 @@ int main(int argc, char **argv) set_glog(loglvl); T_stdout = 1; + get_softmodem_params()->phy_test = 1; + if (snr1set==0) snr1 = snr0+10; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 7e8e06a274..d0ac099651 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -62,7 +62,7 @@ PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -int sf_ahead=4, phy_test = 0; +int sf_ahead=4 ; double cpuf; uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; @@ -372,6 +372,8 @@ int main(int argc, char **argv) set_glog(loglvl); T_stdout = 1; + get_softmodem_params()->phy_test = 1; + if (snr1set == 0) snr1 = snr0 + 10; From f3f3dff1bee61de1eaefbc935d1887f043c05250 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 17 Feb 2020 11:33:03 +0100 Subject: [PATCH 258/343] fixed physim compile errors --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 + openair1/SIMULATION/NR_PHY/ulsim.c | 1 + 2 files changed, 2 insertions(+) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index be2c966f95..73a540747a 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -77,6 +77,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; int sf_ahead=4 ; +int sl_ahead=0; uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index cab19f50b4..5816befd93 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -63,6 +63,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int sf_ahead=4 ; +int sl_ahead=0; double cpuf; uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; From 8dac1f134dd67e2bf8f2b3d2818a44532f20e269 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 17 Feb 2020 14:31:11 +0100 Subject: [PATCH 259/343] fix for pbchsim --- openair1/PHY/INIT/nr_init_ue.c | 1 - openair1/SIMULATION/NR_PHY/pbchsim.c | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index d16858aed4..c3d401c8a1 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -651,7 +651,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int i,j,k,l,slot,symb,q; int eNB_id; int th_id; - int k_ssb=0; uint32_t ****pusch_dmrs; uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig int n_scid; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 8d3e372b57..91e70dc332 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -349,7 +349,6 @@ int main(int argc, char **argv) frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; frame_parms->N_RB_DL = N_RB_DL; - frame_parms->N_RB_UL = N_RB_DL; frame_parms->Nid_cell = Nid_cell; frame_parms->nushift = Nid_cell%4; frame_parms->ssb_type = nr_ssb_type_C; @@ -475,7 +474,7 @@ int main(int argc, char **argv) memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t)); nr_common_signal_procedures (gNB,frame,slot); - + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { if (cyclic_prefix_type == 1) { PHY_ofdm_mod(gNB->common_vars.txdataF[aa], @@ -576,7 +575,7 @@ int main(int argc, char **argv) if (gNB->frame_parms.nb_antennas_tx>1) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1); } - + UE->frame_parms.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; ret = nr_initial_sync(&proc, UE, normal_txrx,1); @@ -618,7 +617,7 @@ int main(int argc, char **argv) uint8_t gNB_xtra_byte=0; for (int i=0; i<8; i++) gNB_xtra_byte |= ((gNB->pbch.pbch_a>>(31-i))&1)<<(7-i); - + payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte); for (i=0;i<3;i++){ payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i))); From 1ff025a4a136581d0c906c5765aa9bc95725bc71 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 17 Feb 2020 15:20:50 +0100 Subject: [PATCH 260/343] fix for pbchsim that works also for -I --- openair1/SIMULATION/NR_PHY/pbchsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 91e70dc332..ed6274740f 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -355,6 +355,7 @@ int main(int argc, char **argv) nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); + nr_set_ssb_first_subcarrier(&gNB->gNB_config,frame_parms); uint8_t n_hf = 0; int cyclic_prefix_type = NFAPI_CP_NORMAL; @@ -575,7 +576,6 @@ int main(int argc, char **argv) if (gNB->frame_parms.nb_antennas_tx>1) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1); } - UE->frame_parms.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; ret = nr_initial_sync(&proc, UE, normal_txrx,1); From c691f9b601f63b6d1b2a578cd94dc3365929d053 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 17 Feb 2020 11:35:41 +0100 Subject: [PATCH 261/343] a few fixes for FR2. fixing beam to boresight for testing --- executables/nr-ru.c | 6 ++++-- openair2/ENB_APP/enb_paramdef.h | 2 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 4 ++-- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 2297ccdca7..fdf07d4f79 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -764,11 +764,13 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { // the beam index is written in bits 8-10 of the flags // bit 11 enables the gpio programming int beam=0; + if (slot==0) beam = 11; //3 for boresight & 8 to enable + /* if (slot==0 || slot==40) beam=0&8; if (slot==10 || slot==50) beam=1&8; if (slot==20 || slot==60) beam=2&8; if (slot==30 || slot==70) beam=3&8; - + */ flags |= beam<<8; } @@ -2371,7 +2373,7 @@ void RCconfig_RU(void) 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]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].uptr); + RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr); if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index c20072c8bf..f91c7056c5 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -153,7 +153,7 @@ typedef enum { {CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_BF_WEIGHTS_LIST, NULL, 0, iptr:NULL, defintarrayval:DEFBFW, TYPE_INTARRAY, 0}, \ - {CONFIG_STRING_RU_IF_FREQUENCY, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT64, 0}, \ + {CONFIG_STRING_RU_IF_FREQUENCY, NULL, 0, u64ptr:NULL, defuintval:0, TYPE_UINT64, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 55cb22f4ec..8ec8484a4d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -248,7 +248,7 @@ uint32_t to_nrarfcn(int nr_bandP, uint32_t nrarfcn, delta_arfcn; LOG_I(MAC,"Searching for nr band %d DL Carrier frequency %llu bw %u\n",nr_bandP,(long long unsigned int)dl_CarrierFreq,bw); - AssertFatal(nr_bandP < 261, "nr_band %d > 260\n", nr_bandP); + AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP); for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); // selection of correct Deltaf raster according to SCS @@ -296,7 +296,7 @@ uint64_t from_nrarfcn(int nr_bandP, if (dl_nrarfcn > 2016666 && dl_nrarfcn < 3279166) deltaFglobal = 60; - AssertFatal(nr_bandP < 261, "nr_band %d > 260\n", nr_bandP); + AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP); for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL %llu\n",dl_nrarfcn, (long long unsigned int)nr_bandtable[i].N_OFFs_DL); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 4564907fa8..686c942db5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -238,7 +238,7 @@ RUs = ( max_rxgain = 114; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2"; - clock_src = "external"; + #clock_src = "external"; } ); From 1b1bbd28499de977819c9443a413350a22807851 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 18 Feb 2020 09:25:21 +0100 Subject: [PATCH 262/343] config files update for rfsimulator CI --- .../gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- ci-scripts/rrc-files/rbconfig.raw | Bin 8 -> 8 bytes ci-scripts/rrc-files/reconfig.raw | Bin 479 -> 479 bytes .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index 4564907fa8..904a455600 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -148,7 +148,7 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; - ssb_PositionsInBurst_Bitmap = 255; + ssb_PositionsInBurst_Bitmap = 1; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 @@ -238,7 +238,7 @@ RUs = ( max_rxgain = 114; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2"; - clock_src = "external"; + #clock_src = "external"; } ); diff --git a/ci-scripts/rrc-files/rbconfig.raw b/ci-scripts/rrc-files/rbconfig.raw index 9c561b7a9fdfd29760e658ee09ed731ab4b2851b..b03f18d1219201d789d1c70e1dced3e84a932990 100644 GIT binary patch literal 8 PcmWgP)DUkvz{3Cl2C4z8 literal 8 PcmWgP)VSVsfJXrU3W@@Y diff --git a/ci-scripts/rrc-files/reconfig.raw b/ci-scripts/rrc-files/reconfig.raw index 5c5e01afe2aec3f97c30c6c395e691b906f53d10..864510c9a938a162efc5947ee5453566b5a2a12f 100644 GIT binary patch delta 424 zcmWlUK}b_!0LTB|_r2|X&pqv<2xsl^Mk8V!dfA8<2zz^&uu-x`gvp?%psYhUNF+Ms zx1O4#qy-ipUqz4}Lg>&b_>5r=I!Mq#5L~yedWcTiy#3&J`0?9gdu)`~cFWjT{d{Wk z3?JCK))h1@F)?lY@L7I~)BBDDw4a;HlcD;6cVv(~u+B@I8XnHP@Bb|DYiRuN2Hxz? zPsL6bG{Jr~7tL6xL#H zE=uC4aG%J_-rrgzwqqS+?o`2X;*Te!;M%&Aiv)q@xQT)e@ZPU*A;Gp0$^_i;^jaqs zPc~8dc+0msduV^clj|e=7(rYPy9~PoQZnBFipu=h>eacz%(kLEp6^z`siO) Oxfwx+l6^9(D)F|0Ed6?z1i89j{1ack!7i;jj@QxARaV2Jcm^bB07eMj3XTqLP1Y@@Hry= zIc*Y)5XCA4Awf%BJal*)v8)skf;Y(_DLkeZFP3h1Z{K(OzJ0dOM)}g-7>;Vae7c(9 zH){jw<Ycum-VXx1!{NW%C?2g$ zH(u@^!@6ld^i4ba82B%rjrxmnU@gBV96(C@IenZEO)u{9t7m@zh!~MAa>2n?*aoP< zEx!!}t6I7wrb?mUQ8$I{Bz#|`3T4~vBik*A0<{{LjS2OB!h8zVPH28ks^dv>kbm2C zFDs);CCbX?PNrcs{?LmO3gi$u$$Hf6MZJ~H!W6Yyxu?xFG!X}$og4oy*B9I?!%x4} zgUDa*3rbK-a#@}U9&z?W#US*g#36urG;m@pyJPbW1c|cB$*iPleGknIadPOF*8dqP vXqGT6Az?<~W#DklXbGkU?*<&9nN^pfMt5Ok==j~)@~OoJ;fAei?9|rhJFJ6H diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 686c942db5..904a455600 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -148,7 +148,7 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; - ssb_PositionsInBurst_Bitmap = 255; + ssb_PositionsInBurst_Bitmap = 1; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 From ad99f473f44baa1dee718ef3e5490c3a5976f1b3 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 18 Feb 2020 09:40:31 +0100 Subject: [PATCH 263/343] CI: fix 5G NR rfsimulator synch check --- ci-scripts/runTestOnVM.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index be6ebda8a9..07ab50246b 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1271,7 +1271,7 @@ function start_rf_sim_nr_ue { rm $1 local i="0" - echo "egrep -c \"rfsimulator: Success\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + echo "egrep -c \"Initial sync: pbch decoded sucessfully\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 while [ $i -lt 10 ] do sleep 5 From 37bbfc09456ca0ce4c30f01aae429227c8d92dc6 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Tue, 18 Feb 2020 11:00:02 +0100 Subject: [PATCH 264/343] fixes for polartest and ulschsim --- openair1/PHY/CODING/TESTBENCH/polartest.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 ++-- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 2 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 11 ++++++----- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 6c3a61766d..806d8de28c 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -175,7 +175,7 @@ if (logFlag){ double channelOutput[coderLength]; //add noise int16_t channelOutput_int16[coderLength]; - t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, 1, aggregation_level,NULL); + t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, 1, NULL); #ifdef DEBUG_DCI_POLAR_PARAMS uint32_t dci_pdu[4]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index f8d8f38dd1..b4ce29eedf 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -34,7 +34,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL); -NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); +NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag); /*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2 diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 872342cd5b..13ad6a0efe 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -112,7 +112,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL) } -NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag) +NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag) { NR_gNB_ULSCH_t *ulsch; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 177640bacc..425cfd030a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -113,7 +113,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) } } -NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag) +NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_ldpc_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag) { NR_UE_DLSCH_t *dlsch; 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 b5a5ecc4db..17c442f635 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -59,12 +59,12 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch,uint8_t N_RB_DL); @params N_RB_DL total number of resource blocks (determine the operating BW) @param abstraction_flag Flag to indicate abstracted interface */ -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); +NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint16_t N_RB_DL, uint8_t abstraction_flag); void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch,unsigned char N_RB_UL); -NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag); +NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag); void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index cc8beb3c3d..460ab495bb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -105,7 +105,7 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL) } -NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, +NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag) { diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 56e6e9936c..0b9340debd 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -232,9 +232,9 @@ int main(int argc, char **argv) break; case 'R': - N_RB_DL = atoi(optarg); + N_RB_UL = atoi(optarg); #ifdef DEBUG_NR_ULSCHSIM - printf("N_RB_DL (-R) = %d\n", N_RB_DL); + printf("N_RB_UL (-R) = %d\n", N_RB_UL); #endif break; @@ -292,7 +292,7 @@ int main(int argc, char **argv) //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); printf("-M Multiple SSB positions in burst\n"); printf("-N Nid_cell\n"); - printf("-R N_RB_DL\n"); + printf("-R N_RB_UL\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); printf("-m\n"); printf("-l\n"); @@ -339,10 +339,11 @@ int main(int argc, char **argv) frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_UL = N_RB_UL; frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; - crcTableInit(); - nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions); + memcpy(&gNB->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + + nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); phy_init_nr_gNB(gNB, 0, 0); From 04b64f84a1549010d1f5282d70bd3304a9f70690 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 18 Feb 2020 12:21:44 +0100 Subject: [PATCH 265/343] set ue dl carrier from cmdline --- executables/nr-softmodem.h | 2 +- executables/nr-uesoftmodem.c | 4 ++++ executables/nr-uesoftmodem.h | 4 ++-- executables/softmodem-common.h | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 27e3ba1e3e..7976d563e5 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -7,7 +7,7 @@ #include "PHY/defs_gNB.h" #include "proto_agent.h" -#define DEFAULT_DLF 2680000000 +#define DEFAULT_DLF 0 /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 4201a84ddc..604f79ace8 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -727,6 +727,10 @@ int main( int argc, char **argv ) { fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; nr_init_frame_parms_ue(frame_parms[CC_id],nrUE_config,NORMAL); + + // Overwrite DL frequency (for FR2 testing) + if (downlink_frequency[0][0]!=0) + frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 3194839dcf..51a328fba3 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -54,7 +54,7 @@ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \ } -#define DEFAULT_DLF 2680000000 +#define DEFAULT_DLF 0 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -65,7 +65,7 @@ {"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}, \ - {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT64, 0}, \ + {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF,TYPE_UINT64, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 13fa7b7eac..84bd9a987f 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -100,6 +100,8 @@ extern "C" #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; +#define DEFAULT_DLF 0 + #define CMDLINE_PARAMS_DESC { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \ @@ -107,7 +109,7 @@ extern "C" {"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \ - {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT64, 0}, \ + {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT64, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ From 99cd73cd0d3a3965c71511d6dc1267b820d933a6 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 18 Feb 2020 14:26:40 +0100 Subject: [PATCH 266/343] previously comitted reconfig.raw was wrong (not sure why). fixing test_case_list.xml --- ci-scripts/rrc-files/reconfig.raw | Bin 479 -> 479 bytes cmake_targets/autotests/test_case_list.xml | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ci-scripts/rrc-files/reconfig.raw b/ci-scripts/rrc-files/reconfig.raw index 864510c9a938a162efc5947ee5453566b5a2a12f..97b41d9b6b0f0662487ca39848f85e9c1f7f8594 100644 GIT binary patch delta 321 zcmWlUKS%;m0Ed6?-gzGW>jVo4siQ6si8!JmoSstR(9qZrq370;a}7Q&q(9RkAwi3_ z6cQx0I6j+_AR=hZBMBPIrNuJazHj@!F6~n1qNJQihaN3>wysVOKLKbiY(lc#hxwkR$%>t=&f8O zHe$NnZrd?EG)FmP|0~zQKt2%H=|ZXauz0KCC1d@rq54(c@sBTWqTX&e+maksO)h2; zBmtO8eCtWC?-^5>5Q>JikVLu6r2BA{|A)gbO+CK1p$l}A$Ln0KIOmj?lUihSyYS(fkcMNMyJ>j4r) zg;|7eE0+WY{*2V3eSWoDvUy6GjrM$|?2GXD|v-l?sHRSU*nAelxzA(uCba JjA#4`{s5$&R*V1u diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 5227ed010e..02c35ed83e 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1097,8 +1097,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15 - - -n100 -R106 -b106 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R106 -b106 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw -n100 -R217 -b217 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw -n100 -R273 -b273 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw -n100 -R106 -o12 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw From 27266ddc9a74872ac2d5a195146458bc7b7b3916 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 18 Feb 2020 16:55:44 +0100 Subject: [PATCH 267/343] adding config file for band n261 --- .../CONF/gnb.band261.tm1.32PRB.usrpn300.conf | 271 ++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf new file mode 100644 index 0000000000..72a27cc1e7 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -0,0 +1,271 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 600; + + plmn_list = ({mcc = 311; mnc = 480; mnc_length = 3;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP) + absoluteFrequencySSB = 2071241; + dl_frequencyBand = 261; + # this is 27.900 GHz + dl_absoluteFrequencyPointA = 2070833; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 3; + dl_carrierBandwidth = 32; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 8525; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 3; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=2,L=3 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 261; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 3; + ul_carrierBandwidth = 32; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 8525; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 3; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#0 = 839, 1 = 139 + prach_RootSequenceIndex_PR = 1; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 3; + ssb_PositionsInBurst_Bitmap = 0x100000001L; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 3; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 3; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 5; + nrofDownlinkSlots = 10; + nrofDownlinkSymbols = 0; + nrofUplinkSlots = 10; + nrofUplinkSymbols = 0; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- 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.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +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_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + if_freq = 5124520000L; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #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"; + }; + From 6ea69740bae2c74c26d1ff6b44bdb584731b903e Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 19 Feb 2020 10:00:36 +0100 Subject: [PATCH 268/343] added 50KHz FR2 sample rate in UE --- executables/nr-uesoftmodem.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 604f79ace8..98f0f4fe6f 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -513,6 +513,14 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); exit(-1); } + }else if(frame_parms[0]->N_RB_DL == 32) { + if (numerology==3) { + openair0_cfg[card].sample_rate=61.44e6; + openair0_cfg[card].samples_per_frame = 614400; + } else { + LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); + exit(-1); + } }else if(frame_parms[0]->N_RB_DL == 217) { if (numerology==1) { if (frame_parms[0]->threequarter_fs) { From d59d2fe2bd84d90c4f0530dd43db73ef175ba0f1 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 19 Feb 2020 11:59:46 +0100 Subject: [PATCH 269/343] CI: adding rrc_config_path to nr-uesofrmodem run on caracal --- ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf | 4 ++-- ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index 904a455600..d92804ae44 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -237,8 +237,8 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2"; - #clock_src = "external"; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; } ); diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml index 03220ec286..5b55d4655a 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - -C 3510000000 --numerology 1 -r 106 --phy-test --usrp-args "addr=192.168.30.2,clock_source=external,time_source=external" --threadoffset 16 + -C 3510000000 --numerology 1 -r 106 --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path ci-scripts/rrc-files NR From a3f9a720926b1f59752993cdf1c5d17232eca070 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 19 Feb 2020 14:07:22 +0100 Subject: [PATCH 270/343] pbchsim works for FR2 --- openair1/SIMULATION/NR_PHY/dlsim.c | 6 ++- openair1/SIMULATION/NR_PHY/pbchsim.c | 64 ++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 73a540747a..d471c53b6f 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -733,9 +733,11 @@ int main(int argc, char **argv) Sched_INFO.TX_req = &gNB_mac->TX_req[0]; nr_schedule_response(&Sched_INFO); - phy_procedures_gNB_TX(gNB,frame,slot,0); + if (run_initial_sync) + nr_common_signal_procedures(gNB,frame,slot); + else + phy_procedures_gNB_TX(gNB,frame,slot,0); - //nr_common_signal_procedures (gNB,frame,subframe); int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP; if (n_trials==1) { diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ed6274740f..19a4a49c8a 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -61,6 +61,50 @@ uint16_t NB_UE_INST = 1; // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; +void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, + int N_RB_DL, + int N_RB_UL, + int mu, + int Nid_cell, + uint64_t position_in_burst) +{ + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config; + //overwrite for new NR parameters + + uint64_t rev_burst=0; + for (int i=0; i<64; i++) + rev_burst |= (((position_in_burst>>(63-i))&0x01)<cell_config.phy_cell_id.value = Nid_cell; + gNB_config->ssb_config.scs_common.value = mu; + gNB_config->ssb_table.ssb_subcarrier_offset.value = 0; + gNB_config->ssb_table.ssb_offset_point_a.value = (N_RB_DL-20)>>1; + gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = (rev_burst)&(0xFFFFFFFF); + gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = (rev_burst>>32)&(0xFFFFFFFF); + gNB_config->cell_config.frame_duplex_type.value = TDD; + gNB_config->ssb_table.ssb_period.value = 1; //10ms + gNB_config->carrier_config.dl_grid_size[mu].value = N_RB_DL; + gNB_config->carrier_config.ul_grid_size[mu].value = N_RB_UL; + gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx; + gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx; + + gNB_config->tdd_table.tdd_period.value = 0; + //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); + if (mu>2) fp->nr_band = 257; + else fp->nr_band = 78; + fp->threequarter_fs= 0; + + gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band); + + nr_init_frame_parms(gNB_config, fp); + gNB->configured = 1; + LOG_I(PHY,"gNB configured\n"); +} int main(int argc, char **argv) { char c; @@ -127,7 +171,7 @@ int main(int argc, char **argv) randominit(0); - while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:o:s:S:t:x:y:z:M:N:F:GR:dP:IL:")) != -1) { + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:o:s:S:t:x:y:z:M:N:F:GR:dP:IL:m:")) != -1) { switch (c) { /*case 'f': write_output_file=1; @@ -302,6 +346,10 @@ int main(int argc, char **argv) loglvl = atoi(optarg); break; + case 'm': + mu = atoi(optarg); + 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", @@ -310,6 +358,7 @@ int main(int argc, char **argv) //printf("-p Use extended prefix mode\n"); //printf("-d Use TDD\n"); printf("-n Number of frames to simulate\n"); + printf("-m Numerology index\n"); printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n"); printf("-t Delay spread for multipath channel\n"); @@ -353,7 +402,7 @@ int main(int argc, char **argv) frame_parms->nushift = Nid_cell%4; frame_parms->ssb_type = nr_ssb_type_C; - nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); + nr_phy_config_request_sim_pbchsim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); nr_set_ssb_first_subcarrier(&gNB->gNB_config,frame_parms); @@ -384,8 +433,17 @@ int main(int argc, char **argv) } else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); break; - } + + case 3: + scs = 120000; + if (N_RB_DL == 66) { + fs = 122.88e6; + bw = 100e6; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + break; + } // cfo with respect to sub-carrier spacing eps = cfo/scs; From f8299700859284b47804a2dfaa2d1846bf720f3c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 20 Feb 2020 15:18:50 +0100 Subject: [PATCH 271/343] improve NR UE capabilities request Seems like the UEs in the CI don't like when asked to report NR UE capabilities. So let's first ask for eutra capabilities and then dig into them to check for en-dc support and only then ask for NR capabilities. We chose to ask for NR capabilities after receiving RRCConnectionReconfigurationComplete. That may not be the best thing to do. Today, we do nothing with those capabilities. We could completely skip asking them to the UE, but since the code is there and since it may be useful in the future, let's do it. Hopefully, it should not hurt too much. --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 59 ++++++++++++- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 7 ++ openair2/RRC/LTE/rrc_defs.h | 1 + openair2/RRC/LTE/rrc_eNB.c | 122 ++++++++++++++++++++++++--- openair2/RRC/LTE/rrc_proto.h | 6 ++ 5 files changed, 181 insertions(+), 14 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 5d733a0efe..8572fcbc15 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3510,8 +3510,6 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, { LTE_DL_DCCH_Message_t dl_dcch_msg; LTE_RAT_Type_t rat=LTE_RAT_Type_eutra; - LTE_RAT_Type_t rat_nr=LTE_RAT_Type_nr; - LTE_RAT_Type_t rat_eutra_nr=LTE_RAT_Type_eutra_nr; asn_enc_rval_t enc_rval; memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; @@ -3523,6 +3521,57 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0; ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + 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_D(RRC,"[eNB %d] UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[eNB %d] ASN1 : UECapabilityRequest encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +//------------------------------------------------------------------------------ +uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, + const uint8_t Transaction_id) +//------------------------------------------------------------------------------ +{ + LTE_DL_DCCH_Message_t dl_dcch_msg; + LTE_RAT_Type_t rat_nr=LTE_RAT_Type_nr; + LTE_RAT_Type_t rat_eutra_nr=LTE_RAT_Type_eutra_nr; + asn_enc_rval_t enc_rval; + memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry; + dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.present = LTE_UECapabilityEnquiry__criticalExtensions_PR_c1; + dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.present = + LTE_UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8; + dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0; ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat_nr); ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, @@ -3548,6 +3597,8 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, r13_10.nonCriticalExtension = &r14_30; r14_30.nonCriticalExtension = &r15_10; + /* TODO: no hardcoded values here */ + OCTET_STRING_t req_freq; //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 @@ -3579,14 +3630,14 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, return -1; } - LOG_D(RRC,"[eNB %d] UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", + LOG_D(RRC,"[eNB %d] NR UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, enc_rval.encoded, (enc_rval.encoded+7)/8); if (enc_rval.encoded==-1) { - LOG_E(RRC,"[eNB %d] ASN1 : UECapabilityRequest encoding failed for UE %x\n", + LOG_E(RRC,"[eNB %d] ASN1 : NR UECapabilityRequest encoding failed for UE %x\n", ctxt_pP->module_id, ctxt_pP->rnti); return(-1); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 925f09416e..34b2909394 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -362,6 +362,13 @@ do_UECapabilityEnquiry( const uint8_t Transaction_id ); +uint8_t +do_NR_UECapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, + const uint8_t Transaction_id +); + uint8_t do_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 53ba6d9314..f050733a13 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -647,6 +647,7 @@ typedef struct eNB_RRC_UE_s { uint8_t e_rab_release_command_flag; int8_t reestablishment_xid; int does_nr; + int nr_capabilities_requested; } eNB_RRC_UE_t; typedef uid_t ue_uid_t; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 051012ce28..aafd1cbf6f 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1287,6 +1287,52 @@ rrc_eNB_generate_UECapabilityEnquiry( PDCP_TRANSMISSION_MODE_CONTROL); } +//----------------------------------------------------------------------------- +void +rrc_eNB_generate_NR_UECapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP +) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[100]; + uint8_t size; + T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + size = do_NR_UECapabilityEnquiry( + ctxt_pP, + buffer, + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (NR UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + rrc_eNB_mui, + DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" rrcNRUECapabilityEnquiry UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + size); + rrc_data_req( + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +} + //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionReject( @@ -6396,6 +6442,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( free(DRB_Release_configList2); ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; } + + /* let's request NR capabilities if the UE supports NR + * maybe not the right place/time to request + */ + if (ue_context_pP->ue_context.does_nr && + !ue_context_pP->ue_context.nr_capabilities_requested) { + ue_context_pP->ue_context.nr_capabilities_requested = 1; + rrc_eNB_generate_NR_UECapabilityEnquiry(ctxt_pP, ue_context_pP); + } + } //----------------------------------------------------------------------------- @@ -7214,6 +7270,48 @@ rrc_eNB_decode_ccch( return rval; } +//----------------------------------------------------------------------------- +static int +is_en_dc_supported( + LTE_UE_EUTRA_Capability_t *c +) +//----------------------------------------------------------------------------- +{ + /* to be refined - check that the eNB is connected to a gNB, check that + * the bands supported by the UE include the band of the gNB + */ +#define NCE nonCriticalExtension + return c != NULL + && c->NCE != NULL + && c->NCE->NCE != NULL + && c->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15 != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 != NULL + && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 == LTE_IRAT_ParametersNR_r15__en_DC_r15_supported; +#undef NCE +} + //----------------------------------------------------------------------------- int rrc_eNB_decode_dcch( @@ -7743,13 +7841,6 @@ rrc_eNB_decode_dcch( LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); - if (ue_context_p->ue_context.UE_Capability) { - LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); - ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, - ue_context_p->ue_context.UE_Capability); - ue_context_p->ue_context.UE_Capability = 0; - } - int eutra_index = -1; for (i = 0; i < ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count; i++) { @@ -7760,9 +7851,17 @@ rrc_eNB_decode_dcch( } eutra_index = i; } - /* todo: improve nr dual connectivity capability checking */ - if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type == LTE_RAT_Type_eutra_nr) - ue_context_p->ue_context.does_nr = 1; + } + + /* do nothing if no EUTRA capabilities (TODO: may be NR capabilities, to be processed somehow) */ + if (eutra_index == -1) + break; + + if (ue_context_p->ue_context.UE_Capability) { + LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability); + ue_context_p->ue_context.UE_Capability = 0; } dec_rval = uper_decode(NULL, @@ -7786,6 +7885,9 @@ rrc_eNB_decode_dcch( ue_context_p->ue_context.UE_Capability = 0; } + if (dec_rval.code == RC_OK) + ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability); + if (EPC_MODE_ENABLED) { rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index d5009de270..8f6baabcbf 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -584,6 +584,12 @@ rrc_eNB_generate_UECapabilityEnquiry( rrc_eNB_ue_context_t *const ue_context_pP ); +void +rrc_eNB_generate_NR_UECapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP +); + void rrc_eNB_generate_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, From 85176d7203562ad5ece4e3a4cab52292b533e6a4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 21 Feb 2020 11:09:28 +0100 Subject: [PATCH 272/343] remove compilation warnings --- executables/nr-softmodem.h | 2 +- executables/softmodem-common.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 7976d563e5..27e3ba1e3e 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -7,7 +7,7 @@ #include "PHY/defs_gNB.h" #include "proto_agent.h" -#define DEFAULT_DLF 0 +#define DEFAULT_DLF 2680000000 /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 84bd9a987f..a8a05a5971 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -100,7 +100,7 @@ extern "C" #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; -#define DEFAULT_DLF 0 +#define DEFAULT_DLF 2680000000 #define CMDLINE_PARAMS_DESC { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ From b232be94edc8a98d16128c3275654e156f350b78 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 22 Feb 2020 15:01:55 +0100 Subject: [PATCH 273/343] dlsim/ulsim updated to generate configuration without need for external pre-generated file. --- cmake_targets/autotests/test_case_list.xml | 34 ++-- common/utils/nr/nr_common.c | 11 +- .../PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c | 10 +- openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c | 2 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 9 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 78 ++++---- openair1/SIMULATION/NR_PHY/dlsim.c | 35 +++- openair1/SIMULATION/NR_PHY/nr_unitary_defs.h | 168 ++++++++++++++++++ openair1/SIMULATION/NR_PHY/ulsim.c | 55 ++---- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 1 - .../NR_MAC_gNB/gNB_scheduler_primitives.c | 36 +--- openair2/RRC/NR/nr_rrc_proto.h | 1 - 13 files changed, 273 insertions(+), 169 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 02c35ed83e..78e4577d31 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1097,18 +1097,18 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15 - -n100 -R106 -b106 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R217 -b217 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R273 -b273 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R106 -o12 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R217 -o48 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R106 -a25 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R106 -a51 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R217 -b100 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R217 -a80 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -R217 -a110 -s5 -b100 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -e28 -s20 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -e16 -s10 -s5 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -R106 -b106 -s5 + -n100 -R217 -b217 -s5 + -n100 -R273 -b273 -s5 + -n100 -R106 -o12 -s5 + -n100 -R217 -o48 -s5 + -n100 -R106 -a25 -s5 + -n100 -R106 -a51 -s5 + -n100 -R217 -b100 -s5 + -n100 -R217 -a80 -s5 + -n100 -R217 -a110 -s5 -b100 + -n100 -e287 -s20 + -n100 -e16 -s10 nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 PDSCH test OK @@ -1252,11 +1252,11 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15 - -n100 -m9 -r106 -s0 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -m16 -s10 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -m28 -s20 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -m9 -R217 -r217 -s0 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw - -n100 -m9 -R273 -r273 -s0 -f $OPENAIR_DIR/ci-scripts/rrc-files/reconfig.raw + -n100 -m9 -r106 -s0 + -n100 -m16 -s10 + -n100 -m28 -s20 + -n100 -m9 -R217 -r217 -s0 + -n100 -m9 -R273 -r273 -s0 nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 PUSCH test OK segmentation fault|assertion|exiting|fatal diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index cdbf59cd76..8a236c49f9 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -37,7 +37,8 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; int tmp2 = locationAndBandwidth%N_RB; - if (tmp <= ((N_RB>>1)-tmp2+1)) return(tmp+1); + + if (tmp <= ((N_RB>>1)+1) && (tmp+tmp2)>1)-tmp2+1)) return(tmp2); + + + if (tmp <= ((N_RB>>1)+1) && (tmp+tmp2)0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d)\n",NPRB,RBstart); + AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",NPRB,RBstart,BWPsize); + if (NPRB <= 1+(BWPsize>>1)) return(BWPsize*(NPRB-1)+RBstart); else return(BWPsize*(BWPsize+1-NPRB) + (BWPsize-1-RBstart)); } diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c index ef207b6cdc..5ab55514ce 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c @@ -487,10 +487,10 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha macro_segment = 8*macro_num; - // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; - macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments); - ///printf("macro_segment: %d\n", macro_segment); - ///printf("macro_segment_end: %d\n", macro_segment_end ); + macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; + //macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments); + //printf("macro_segment: %d\n", macro_segment); + //printf("macro_segment_end: %d\n", macro_segment_end ); #ifdef __AVX2__ __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); @@ -564,7 +564,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha for (i=0; i>5; i++) { c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]); //for (j=1; j0,"Nl is 0\n"); AssertFatal(Qm>0,"Qm is 0\n"); - + LOG_D(PHY,"nr_get_E : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r); if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1) E = Nl*Qm*(G/(Nl*Qm*Cprime)); else diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 425cfd030a..7a23ce7167 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -456,9 +456,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, start_meas(dlsch_rate_unmatching_stats); #endif -#ifdef DEBUG_DLSCH_DECODING - LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", - harq_pid,r, G, + LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", + harq_pid,r, G,E,harq_process->F, Kr*3, harq_process->TBS, harq_process->Qm, @@ -466,7 +465,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->Nl, harq_process->rvidx, harq_process->round); -#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN); @@ -673,7 +672,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return((1 + dlsch->max_ldpc_iterations)); } else { //#if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); //#endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index b60843fab8..c704efdb1f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -375,24 +375,24 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } len = (pilots==1)? (nb_rb*6):(nb_rb*12); - + #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - 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)); + 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 %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)); + 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 - + #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #endif n_tx = frame_parms->nb_antenna_ports_gNB; n_rx = frame_parms->nb_antennas_rx; - + nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch, @@ -416,11 +416,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (beamforming_mode==0){ if (dlsch0_harq->mimo_modedl_ch_estimates_ext, - frame_parms, - avg, - symbol, - len, - nb_rb); + frame_parms, + avg, + symbol, + len, + nb_rb); avgs = 0; for (aatx=0;aatxnb_antenna_ports_gNB;aatx++) for (aarx=0;aarxnb_antennas_rx;aarx++) @@ -449,14 +449,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } } -#ifdef UE_DEBUG_TRACE - LOG_I(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", - frame%1024,nr_tti_rx, pdsch_vars[eNB_id]->log2_maxh, - pdsch_vars[eNB_id]->log2_maxh0, - pdsch_vars[eNB_id]->log2_maxh1, - avg[0],avgs); + //#ifdef UE_DEBUG_TRACE + LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", + frame%1024,nr_tti_rx, pdsch_vars[eNB_id]->log2_maxh, + pdsch_vars[eNB_id]->log2_maxh0, + pdsch_vars[eNB_id]->log2_maxh1, + avg[0],avgs); //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); -#endif + //#endif //wait until pdcch is decoded //proc->channel_level = 1; @@ -1849,11 +1849,11 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, //compute average channel_level on each (TX,RX) antenna pair void nr_dlsch_channel_level(int **dl_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - int32_t *avg, - uint8_t symbol, - uint32_t len, - unsigned short nb_rb) + NR_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t symbol, + uint32_t len, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) @@ -1864,8 +1864,9 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, //nb_rb*nre = y * 2^x int16_t x = factor2(len); + //x = (x>4) ? 4 : x; int16_t y = (len)>>x; - //printf("nb_rb*nre = %d = %d * 2^(%d)\n",nb_rb*nre,y,x); + //printf("len = %d = %d * 2^(%d)\n",len,y,x); for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -1876,29 +1877,10 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; for (rb=0;rbNcp-1)))&&(frame_parms->nb_antenna_ports_gNB!=1)) { - dl_ch128+=2; - } - else {*/ - avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); - //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15))); - dl_ch128+=3; - // } - /* - if (rb==0) { - print_shorts("dl_ch128",&dl_ch128[0]); - print_shorts("dl_ch128",&dl_ch128[1]); - print_shorts("dl_ch128",&dl_ch128[2]); - } - */ + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); + dl_ch128+=3; } avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] + diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index d471c53b6f..07e8082cf8 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -142,6 +142,7 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char short_padding, unsigned short post_padding){return 0;} void nr_ip_over_LTE_DRB_preconfiguration(void){} + void mac_rlc_data_ind ( const module_id_t module_idP, const rnti_t rntiP, @@ -160,6 +161,8 @@ void mac_rlc_data_ind ( openair0_config_t openair0_cfg[MAX_CARDS]; + + int main(int argc, char **argv) { char c; @@ -474,6 +477,7 @@ int main(int argc, char **argv) gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); + /* // read in SCGroupConfig AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); char buffer[1024]; @@ -511,15 +515,28 @@ int main(int argc, char **argv) SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, secondaryCellGroup, 1 ); exit(-1); } - - NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); + NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + */ - rrc.carrier.servingcellconfigcommon = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - printf("%p,%p\n", - secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon, - rrc.carrier.servingcellconfigcommon); + + rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon)); + + NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon; + NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup)); + prepare_scc(rrc.carrier.servingcellconfigcommon); + uint64_t ssb_bitmap; + fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); + + fill_default_secondaryCellGroup(scc, + secondaryCellGroup, + 0, + 1, + n_tx, + 0); + fix_scc(scc,ssb_bitmap); + + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; @@ -661,9 +678,9 @@ int main(int argc, char **argv) gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; if (mcsIndex_set==0) dlsch_config.mcsIndex[0]=9; - if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL; + if (rbStart_set==0) dlsch_config.rbStart=0; - + if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL-dlsch_config.rbStart; //Configure UE rrc.carrier.MIB = (uint8_t*) malloc(4); diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index 78596cc792..48fd49943b 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -55,4 +55,172 @@ signed char quantize(double D, double x, unsigned char B) { return ((char) qxd); } +void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL,int N_RB_UL,int mu_dl,int mu_ul) { + + *scc->physCellId=0; \ + // *scc->n_TimingAdvanceOffset=NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0; + *scc->ssb_periodicityServingCell=NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20; + scc->dmrs_TypeA_Position=NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2; + *scc->ssbSubcarrierSpacing=NR_SubcarrierSpacing_kHz30; + *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=641032; + *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=78; + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=640000; + scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; + scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=NR_SubcarrierSpacing_kHz30; + + scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_DL; + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth=13036; + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing=mu_dl;//NR_SubcarrierSpacing_kHz30; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=12; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero=0; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->k0=0; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength=40; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->k0=0; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength=53; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->k0=0; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[3]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[3]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[3]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[4]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[4]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[4]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[5]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[5]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[5]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[6]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[6]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[6]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[7]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[7]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[8]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[8]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[8]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[9]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[9]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[9]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[10]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[10]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[10]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[11]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[11]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[11]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[12]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[12]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[12]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[13]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[13]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[13]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[14]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[14]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[14]->startSymbolAndLength=54; + *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[15]->k0=-1; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[15]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[15]->startSymbolAndLength=54; + *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]=78; + *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA=-1; + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=NR_SubcarrierSpacing_kHz30; + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_UL; + *scc->uplinkConfigCommon->frequencyInfoUL->p_Max=20; + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth=13036; + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing=mu_ul;//NR_SubcarrierSpacing_kHz30; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex=98; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM=NR_RACH_ConfigGeneric__msg1_FDM_one; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart=0; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig=13; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower=-118; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleTransMax=NR_RACH_ConfigGeneric__preambleTransMax_n10; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.powerRampingStep=NR_RACH_ConfigGeneric__powerRampingStep_dB2; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow=NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present=NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one=NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB__one_n64; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer=NR_RACH_ConfigCommon__ra_ContentionResolutionTimer_sf64; + *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB=19; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present=NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139=0; + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig=NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2=2; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2=2; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength=69; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2=2; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[9]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[9]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[9]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->k2=33; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; + scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->startSymbolAndLength=55; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble=1; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant=-90; + scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping=NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither; + *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId=40; + *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal=-90; + scc->ssb_PositionsInBurst->present=NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; + *ssb_bitmap=0xff; + scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing=NR_SubcarrierSpacing_kHz30; + scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5; + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots=7; + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols=6; + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots=2; + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols=4; + scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity=321; + + scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots=-1; + scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols=-1; + scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots=-1; + scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols=-1; + scc->ss_PBCH_BlockPower=20; + *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=-1; +} + +void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap); +void prepare_scc(NR_ServingCellConfigCommon_t *scc); +s1ap_eNB_config_t s1ap_config; +uint32_t s1ap_generate_eNB_id(void) {return 0;} +void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;} +void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;} + + #endif diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 5816befd93..f43709cac5 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -413,53 +413,24 @@ int main(int argc, char **argv) gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); - // read in SCGroupConfig - AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); - char buffer[1024]; - int msg_len=fread(buffer,1,1024,scg_fd); - NR_RRCReconfiguration_t *NR_RRCReconfiguration; + rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon)); - printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len); - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_RRCReconfiguration, - (void **)&NR_RRCReconfiguration, - (uint8_t *)buffer, - msg_len); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"NR_RRCReConfiguration decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, NR_RRCReconfiguration, 1 ); - exit(-1); - } - fclose(scg_fd); + NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon; + NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup)); + prepare_scc(rrc.carrier.servingcellconfigcommon); + uint64_t ssb_bitmap; + fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); - AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n"); + fill_default_secondaryCellGroup(scc, + secondaryCellGroup, + 0, + 1, + n_tx, + 0); + fix_scc(scc,ssb_bitmap); - NR_RRCReconfiguration_IEs_t *reconfig_ies = NR_RRCReconfiguration->criticalExtensions.choice.rrcReconfiguration; - NR_CellGroupConfig_t *secondaryCellGroup; - dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&secondaryCellGroup, - (uint8_t *)reconfig_ies->secondaryCellGroup->buf, - reconfig_ies->secondaryCellGroup->size); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"NR_CellGroupConfig decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, secondaryCellGroup, 1 ); - exit(-1); - } - - NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); - rrc.carrier.servingcellconfigcommon = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - printf("%p,%p\n", - secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon, - rrc.carrier.servingcellconfigcommon); - AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 8ec8484a4d..ae23164194 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -298,7 +298,7 @@ uint64_t from_nrarfcn(int nr_bandP, AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP); for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL %llu\n",dl_nrarfcn, (long long unsigned int)nr_bandtable[i].N_OFFs_DL); + AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL[%d] %llu\n",dl_nrarfcn, nr_bandtable[i].band,(long long unsigned int)nr_bandtable[i].N_OFFs_DL); // selection of correct Deltaf raster according to SCS if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index dffca69222..e4ead72dae 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1685,7 +1685,6 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(fapi_nr_ul_config_pusch_pd /* * TS 38.214 subclause 5.1.2.2.2 Downlink resource allocation type 1 */ - dlsch_config_pdu->number_rbs = NRRIV2BW(riv,n_RB_DLBWP); dlsch_config_pdu->start_rb = NRRIV2PRBOFFSET(riv,n_RB_DLBWP); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9a9bfa0164..e15eb3686e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -573,34 +573,24 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos=fsize; *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_size-pos,*dci_pdu); -#endif // Time domain assignment pos+=4; *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment&0xf) << (dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,dci_size-pos,*dci_pdu); -#endif // VRB to PRB mapping pos++; *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu); -#endif // MCS pos+=5; *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); -#endif // TB scaling pos+=2; *dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling&0x3)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); -#endif break; case NR_RNTI_C: @@ -608,18 +598,14 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, // indicating a DL DCI format 1bit pos++; *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&1)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); -#endif // Freq domain assignment (275rb >> fsize = 16) fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos+=fsize; *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,dci_size-pos,*dci_pdu); -#endif uint16_t is_ra = 1; for (int i=0; itime_domain_assignment&0xf) << (dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,4,dci_size-pos,*dci_pdu); -#endif // VRB to PRB mapping 1bit pos++; *dci_pdu |= (dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,1,dci_size-pos,*dci_pdu); -#endif // MCS 5bit //bit over 32, so dci_pdu ++ pos+=5; *dci_pdu |= (dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"MCS %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,5,dci_size-pos,*dci_pdu); -#endif // New data indicator 1bit pos++; *dci_pdu |= (dci_pdu_rel15->ndi&1)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); -#endif // Redundancy version 2bit pos+=2; *dci_pdu |= (dci_pdu_rel15->rv&0x3)<<(dci_size-pos); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); -#endif // HARQ process number 4bit pos+=4; *dci_pdu |= ((dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); -#endif // Downlink assignment index 2bit pos+=2; *dci_pdu |= ((dci_pdu_rel15->dai&3)<<(dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"DAI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->dai,2,dci_size-pos,*dci_pdu); -#endif // TPC command for scheduled PUCCH 2bit pos+=2; *dci_pdu |= ((dci_pdu_rel15->tpc&3)<<(dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); -#endif // PUCCH resource indicator 3bit pos+=3; *dci_pdu |= ((dci_pdu_rel15->pucch_resource_indicator&0x7)<<(dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pucch_resource_indicator,3,dci_size-pos,*dci_pdu); -#endif // PDSCH-to-HARQ_feedback timing indicator 3bit pos+=3; *dci_pdu |= ((dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_size-pos)); -#ifdef DEBUG_FILL_DCI LOG_D(MAC,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator,3,dci_size-pos,*dci_pdu); -#endif } //end else break; @@ -1363,4 +1329,4 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ } } } -*/ \ No newline at end of file +*/ diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index bd13c6cc22..1e4b1be054 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -70,7 +70,6 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerL void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p); void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_RRCReconfiguration_IEs_t *reconfig, NR_CellGroupConfig_t *secondaryCellGroup, int scg_id, int servCellIndex, From e454e59f614dc7e03cccdfcb04c125305e432fe6 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 24 Feb 2020 15:21:37 +0100 Subject: [PATCH 274/343] CI: fixing the report on 5G NR RF simulation Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 72779e3824..b74fe93a1f 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -112,7 +112,7 @@ function analyzeIperfFiles { echo "
" >> ./test_simulator_results.html fi else - EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "bits/sec" | sed -e "s#^.*Bytes *##" -e "s#sec.*#sec#"` if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] then EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Kbits/sec.*##"` @@ -136,9 +136,9 @@ function analyzeIperfFiles { else echo " " >> ./test_simulator_results.html fi - EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - JITTER=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*Mbits/sec *##" -e "s#ms.*#ms#"` - PACKETLOSS=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*(##" -e "s#).*##"` + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "bits/sec" | sed -e "s#^.*Bytes *##" -e "s#sec.*#sec#"` + JITTER=`tail -n3 $IPERF_CASE | egrep "bits/sec" | sed -e "s#^.*bits/sec *##" -e "s#ms.*#ms#"` + PACKETLOSS=`tail -n3 $IPERF_CASE | egrep "bits/sec" | sed -e "s#^.*(##" -e "s#).*##"` fi echo "
Log File Name OKOK" >> ./test_simulator_results.html echo "
" >> ./test_simulator_results.html

From 2c35740122ad94a3b5102544fd01029bf51d8142 Mon Sep 17 00:00:00 2001
From: frtabu 
Date: Tue, 25 Feb 2020 11:31:40 +0100
Subject: [PATCH 275/343] telnet server and iq record player documentation
 update

---
 common/utils/telnetsrv/DOC/telnetarch.md      |  18 +-
 common/utils/telnetsrv/DOC/telnetusage.md     |   2 +-
 .../ARCH/iqplayer/DOC/iqrecordplayer_usage.md | 161 ++++++++++++++++++
 3 files changed, 176 insertions(+), 5 deletions(-)
 create mode 100644 targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md

diff --git a/common/utils/telnetsrv/DOC/telnetarch.md b/common/utils/telnetsrv/DOC/telnetarch.md
index ebb2342c22..683b14a1b8 100644
--- a/common/utils/telnetsrv/DOC/telnetarch.md
+++ b/common/utils/telnetsrv/DOC/telnetarch.md
@@ -1,6 +1,15 @@
 # telnet server principles
 
-The oai telnet server is implemented in a shared library to be loaded by the [oai shared library loader](loader). The implementation includes a `telnetsrv_autoinit` function which is automatically called at load time, starts the telnet server and registers a first set of commands, which are delivered with the server (telnet, softmodem, loader).
+The oai telnet server is implemented in shared libraries to be loaded by the [oai shared library loader](loader). `libtelnetsrv.so ` contains the code common to all oai softmodem executables, where `libtelnetsrv_.so` contains the code specific to the executable identified by `app`. 
+
+| `` |    executable     |
+| :-----: | :---------------: |
+|   enb   |  `lte-softmodem`  |
+|   gnb   |  `nr-softmodem`   |
+|  4Gue   | `lte-uesoftmodem` |
+|  5Gue   | `nr-uesoftmodem`  |
+
+The implementation includes a `telnetsrv_autoinit` function which is automatically called at load time, starts the telnet server and registers a first set of commands, which are delivered with the server (telnet, softmodem, loader). it also uses the `get_softmodem_function` call to retrieve the running executable id and possibly loads the corresponding `libtelnetsrv_.so`library.
 
 Currently the telnet server only supports one user connection. The same dedicated thread is used to wait for a user connection and process the input received from this connection.
 
@@ -12,10 +21,11 @@ The telnet server provides an API which can be used by any oai component to add
 
 telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv)
 
-1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the telnet CLI command.
+1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the `telnet` CLI command. This implementation is compatible with all softmodem executables and is in charge of loading any additional `libtelnetsrv_ .so` containing code specific to the running executables.
 1.  [telnetsrv.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server.
-1.  `telnetsrv\_\.c`: implementation of \ CLI command which are delivered with the telnet server.
-1.  `telnetsrv\_\.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file
+1.  `telnetsrv_.c`: implementation of \ CLI command which are delivered with the telnet server and are common to all softmodem executables. 
+1. `telnetsrv_.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file
+1.  `telnetsrv__.c`: implementation of \ CLI command specific to the executable identified by \.These sources are used to create `libtelnetsrv_.so` at build time.
 1.  [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt).
 
 [oai telnet server home](telnetsrv.md)
diff --git a/common/utils/telnetsrv/DOC/telnetusage.md b/common/utils/telnetsrv/DOC/telnetusage.md
index ec49deec73..c4777ce0d8 100644
--- a/common/utils/telnetsrv/DOC/telnetusage.md
+++ b/common/utils/telnetsrv/DOC/telnetusage.md
@@ -8,7 +8,7 @@ By default the embedded telnet server, which is implemented in a shared library,
  ./build_oai  --build-lib telnetsrv
 ```
 
-This will create the `libtelnetsrv.so` file in the `targets/bin` and `cmake_targets/ran_build/build` sub directories of the oai repository.
+This will create the `libtelnetsrv.so` and `libtelnetsrv_ file in the `targets/bin` and `cmake_targets/ran_build/build` sub directories of the oai repository.  can be "enb", "gnb", "4GUE" or "5GUE", each library containing functions specific to a given executable.
 
 When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader).
 
diff --git a/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md b/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md
new file mode 100644
index 0000000000..856e2ea27c
--- /dev/null
+++ b/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md
@@ -0,0 +1,161 @@
+#I/Q record-playback
+## using the iq recorder or iq player
+
+This feature provides I/Q record-playback as presented in the 4th OAI workshop. Tests have only been performed with a eNB, but the implementation should allow any softmodem executable to use the iq's record/player.
+The I/Q record/playback feature is briefly described hereafter, it allows you to:
+* record subframes received by the USRP board in a file while the system is operating (for example you can record a full UE connection/traffic/ disconnection sequence). Today the oai USRP device is the only one supporting the recording feature. 
+* replay subframes from a file to operate the system (possibly in multiple loops if the recorded sequence is convenient from the logical point of view). 
+
+The record/replay  are activated and configured using oai configuration parameters
+
+###Record mode
+options for record mode are:
+* `subframes-record` Activate record mode
+* `subframes-file` Path of the file used for subframes recording (default is `/tmp/iqfile`)
+* `subframes-max` Maximum count of subframes to be recorded in subframe file (default is 120000)
+
+Note that the value of --subframes-max parameter needs to be tuned according to your RAM capabilities. The default value is 120000, which allows for 120 seconds of record/replay but will require ~3.6GB of RAM and disk space. If RAM does not allow for the parameter value, an error message will be displayed and the run will be aborted. In record mode, subframes are copied in specific memory records not to disrupt regular behavior. When you estimate the recorded sequence is achieved, you should terminate the eNB/RRU by typing `CTRL-C`. At that time, up to the value of --subframes-max parameter will be written on disk. The eNB/RRU will indicate the exact count of subframes written to disk, which may be less (but not higher) that the value of --subframes-max parameter (120000 by default). The number of subframes written to disk is rounded to an integral number of frames. When replaying a file you should always specify the exact number of subframes, and thus use the exact number of subframes written during recording. You might experiment unexpected behavior if the number of subframes to be replayed does not match the number of subframes recorded. This might be improved in the future.
+Although it is possible to perform recording with a fronthaul setup, it is suggested to perform recording in full eNB mode and then replay in either full or split eNB.
+The option can be used while operating full eNB or RCC/RRU linked by NGFI IF5/IF4p5 fronthaul techniques. One of the advantage of the record/replay technique is that you can replay on a fronthauling setup a file that has been recorded in full eNB mode. This can easily asserts that the fronthauling underlying set up or technique is correct.
+
+>recording session example:
+```bash
+ ./lte-softmodem -O libconfig:/usr/local/oai/conf/enb.band7.tm1.20PRB.usrpb210.conf:dbgl5    --log_config.global_log_options level,thread   --device.recplay.subframes-record 1
+............................................
+............................................
+[CONFIG] device.recplay.subframes-file set to default value "/tmp/iqfile"
+[CONFIG] subframes-record: 0
+[CONFIG] device.recplay.subframes-record set to default value
+[CONFIG] subframes-replay: 0
+[CONFIG] device.recplay.subframes-replay set to default value
+[CONFIG] subframes-max: 120000
+[CONFIG] device.recplay.subframes-max set to default value
+[CONFIG] subframes-loops: 5
+[CONFIG] device.recplay.subframes-loops set to default value
+[CONFIG] subframes-read-delay: 700
+[CONFIG] device.recplay.subframes-read-delay set to default value
+[CONFIG] subframes-write-delay: 15
+[CONFIG] device.recplay.subframes-write-delay set to default value
+[LIBCONFIG] device.recplay: 7/7 parameters successfully set, (7 to default value)
+[CONFIG] subframes-record: 1
+[CONFIG] device.recplay 1 options set from command line
+[CONFIG] loader.oai_device.shlibversion set to default value ""
+[LIBCONFIG] loader.oai_device: 2/2 parameters successfully set, (1 to default value)
+[CONFIG] loader.oai_device 0 options set from command line
+[LOADER] library liboai_device.so successfully loaded
+USRP device initialized in subframes record mode
+[HW]I lte-softmodem UHD version 3.14.1.1-release (3.14.1)
+...................................................
+...................................................
+[PHY]I lte-softmodem prach_I0 = 0.0 dB
+[PHY]I ru thread max_I0 18, min_I0 12
+^C
+Run time: 0h 26s
+	Time executing user inst.: 1s 865251us
+	Time executing system inst.: 2s 805162us
+	Max. Phy. memory usage: 4068328kB
+	Page fault number (no io): 1008741
+	Page fault number (requiring io): 15
+	Number of file system read: 97672
+	Number of filesystem write: 0
+	Number of context switch (process origin, io...): 562871
+	Number of context switch (os origin, priority...): 112
+Linux signal Interrupt...
+/usr/local/oai/develop/openairinterface5g/executables/softmodem-common.c:188 signal_handler() Exiting OAI softmodem: softmodem starting exit procedure
+Exiting ru_thread 
+U[HW]I ru thread Writing file header to /tmp/iqfile 
+[HW]I lte-softmodem Writing file header to /tmp/iqfile 
+[HW]I ru thread Writing 19730 subframes to /tmp/iqfile 
+[HW]I lte-softmodem Writing 19730 subframes to /tmp/iqfile 
+[HW]I lte-softmodem File /tmp/iqfile closed
+[HW]I ru thread File /tmp/iqfile closed
+[PHY]I ru thread RU 0 rf device stopped
+```
+
+###Playback/replay mode
+The option works only for 5MHz bandwidth because the information stored in the iq's file header regarding bandwidth is not yet properly processed. 
+ In this version,  mismatch between file content and run time parameters might lead to unpredictable results. In addition a file recorded on a AVX2-capable processor cannot be replayed on a non-AVX2-capable processor (this is to be further investigated).
+options for replay mode are:
+* `subframes-replay` Activate replay mode
+* `subframes-file` Path of the file used for subframes replay (default is `/tmp/iqfile`)
+* `subframes-loops` Number of iterations to replay the entire subframes file (default is 5)
+* `subframes-read-delay` Delay in microseconds to read a subframe in replay mode (default 200)
+* `subframes-write-delay` Delay in milliseconds to write a subframe in replay mode (default 15)
+
+>iq player session example:
+```bash
+./lte-softmodem -O libconfig:/usr/local/oai/conf/enb.nbiot.band7.tm1.50PRB.usrpb210.conf:dbgl5  --T_stdout 1   --log_config.global_log_options level,thread --eNBs.[0].component_carriers.[0].N_RB_DL 25   --device.recplay.subframes-replay 1
+[CONFIG] get parameters from libconfig /usr/local/oai/conf/enb.nbiot.band7.tm1.50PRB.usrpb210.conf , debug flags: 0x00000005
+................................
+..................................
+[PHY]I lte-softmodem rxdataF[0] 0x55f52df52f40 for RU 0
+[CONFIG] device.recplay.subframes-file set to default value "/tmp/iqfile"
+[CONFIG] subframes-record: 0
+[CONFIG] device.recplay.subframes-record set to default value
+[CONFIG] subframes-replay: 0
+[CONFIG] device.recplay.subframes-replay set to default value
+[CONFIG] subframes-max: 120000
+[CONFIG] device.recplay.subframes-max set to default value
+[CONFIG] subframes-loops: 5
+[CONFIG] device.recplay.subframes-loops set to default value
+[CONFIG] subframes-read-delay: 700
+[CONFIG] device.recplay.subframes-read-delay set to default value
+[CONFIG] subframes-write-delay: 15
+[CONFIG] device.recplay.subframes-write-delay set to default value
+[LIBCONFIG] device.recplay: 7/7 parameters successfully set, (7 to default value)
+[CONFIG] subframes-replay: 1
+[CONFIG] device.recplay 1 options set from command line
+[CONFIG] loader.oai_iqplayer.shlibversion set to default value ""
+[LIBCONFIG] loader.oai_iqplayer: 2/2 parameters successfully set, (1 to default value)
+[CONFIG] loader.oai_iqplayer 0 options set from command line
+[LOADER] library liboai_iqplayer.so successfully loaded
+[HW]I lte-softmodem Loading subframes using mmap() from /tmp/iqfile size=324433632 bytes ...
+[HW]I lte-softmodem Replay iqs from USRP B200 device, bandwidth 5.000000e+06
+[HW]I lte-softmodem Loaded 10550 subframes.
+[HW]I lte-softmodem iqplayer device initialized, replay /tmp/iqfile  for 5 iterations[HW]I lte-softmodem [RAU] has loaded USRP B200 device.
+.............................................
+.............................................
+[PHY]I ru thread max_I0 18, min_I0 12
+[PHY]I lte-softmodem prach_I0 = 0.0 dB
+[PHY]I ru thread max_I0 18, min_I0 0
+[HW]I ru thread starting subframes file with wrap_count=1 wrap_ts=81024000 ts=107616555
+[PHY]I lte-softmodem prach_I0 = 0.0 dB
+[PHY]I ru thread max_I0 18, min_I0 12
+[HW]I ru thread starting subframes file with wrap_count=2 wrap_ts=162048000 ts=188640555
+[PHY]I lte-softmodem prach_I0 = 0.0 dB
+[PHY]I ru thread max_I0 18, min_I0 0
+[HW]I ru thread starting subframes file with wrap_count=3 wrap_ts=243072000 ts=269664555
+[PHY]I lte-softmodem prach_I0 = 0.0 dB
+[PHY]I ru thread max_I0 19, min_I0 12
+[HW]I ru thread starting subframes file with wrap_count=4 wrap_ts=324096000 ts=350688555
+[PHY]I lte-softmodem prach_I0 = 0.0 dB
+[PHY]I ru thread max_I0 18, min_I0 12
+[HW]W ru thread iqplayer device terminating subframes replay  after 5 iteration
+/usr/local/oai/develop/openairinterface5g/targets/ARCH/iqplayer/iqplayer_lib.c:222 trx_iqplayer_read() Exiting OAI softmodem: replay ended, triggering process termination
+```
+
+## iq recorder and iq player implementation overview
+
+###configuration
+The iq's record/player is using the [configuration module](../../../../common/config/DOC/config.md). Configuration parameters supported by the record player are defined in the [record_player.h](../../COMMON/record_player.h) include file.
+ There are no specific sections for the recorder or the replayer, parameters are defined under the `device.recplay`section and the `read_recplayconfig` function is common to both the recorder and the player. `device.recplay` configuration section is read from oai code common to all devices:
+Implemented in [record_player.c](../../COMMON/record_player.c), the `read_recplayconfig` function is called from `load_lib` and reads the configuration parameters, saving them in a `recplay_conf_t` sub-structure of the oai device. It also allocates a `recplay_state_t` structure which will save the recorder or player data. 
+3GPP authentication algorithm doesn't allow session establishment via replaying iq's. When using the replayer, a softmodem parameter is set (`SOFTMODEM_RECPLAY_BIT` in the `optmask` bitmask of the `softmodem_params_t` structure. It allows bypassing or activating specific code in the softmodem to allow session establishment replay. This mechanism only works if in parallel specific code is also activated in the EPC, which is supported by the NOKIA LTE box.
+An easiest scenario is to use the record player in parallel with the noS1 mode, as described [here](../../../../doc/RUNMODEM.md) 
+
+### iq recorder
+most of the implementation is now located in the oai device common code:
+* The`load_lib` function in [common-lib.c](../../COMMON/common_lib.c) reads the record player parameters. 
+* Recorder specific functions are implemented in  `iqrecorder_end` saves the cached iq's to disk, it has to be called by the oai device in it's end function.
+* When recording is enabled, the device must implement iq's caching in it's read function. It also has to call the `iqrecorder_end ` function when  terminating to write iqs to a file on disk. Look at the USRP device ( [../usrp_lib.cpp](../../USRP/USERSPACE/LIB/usrp_lib.cpp) ) for  details.
+
+### iq player
+The replay feature is implemented as a oai device. 
+* The`load_lib` function in [common-lib.c](../../COMMON/common_lib.c) reads the record player parameters, this code is common with the recorder.
+* The player device is implemented in  [iqplayer_lib.c](../iqplayer_lib.c) which at build time creates the `liboai_iqplayer.so` shared library. Thi
+* s device is automatically, dynamicaly loaded when the player feature is activated at runtime when the boolean  `device.recplay.subframes-replay` option is set.
+
+### iq's file format
+The recorder adds a header containing the device type, the bandwith and a format identifier. Using these information when replaying a file has not yet been implemented, so the player only supports USRP B2xx device and 5MHz bandwith. 
+
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

From dd7e48ca694a112dcc2e29b66352d9ccb8ded986 Mon Sep 17 00:00:00 2001
From: Francois TABURET 
Date: Tue, 25 Feb 2020 16:06:37 +0100
Subject: [PATCH 276/343] Fixes typo discovered when reviewing from gitlab

---
 targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md b/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md
index 856e2ea27c..a6e4138e8e 100644
--- a/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md
+++ b/targets/ARCH/iqplayer/DOC/iqrecordplayer_usage.md
@@ -1,4 +1,4 @@
-#I/Q record-playback
+# I/Q record-playback
 ## using the iq recorder or iq player
 
 This feature provides I/Q record-playback as presented in the 4th OAI workshop. Tests have only been performed with a eNB, but the implementation should allow any softmodem executable to use the iq's record/player.
@@ -8,14 +8,16 @@ The I/Q record/playback feature is briefly described hereafter, it allows you to
 
 The record/replay  are activated and configured using oai configuration parameters
 
-###Record mode
+### Record mode
 options for record mode are:
 * `subframes-record` Activate record mode
 * `subframes-file` Path of the file used for subframes recording (default is `/tmp/iqfile`)
 * `subframes-max` Maximum count of subframes to be recorded in subframe file (default is 120000)
 
-Note that the value of --subframes-max parameter needs to be tuned according to your RAM capabilities. The default value is 120000, which allows for 120 seconds of record/replay but will require ~3.6GB of RAM and disk space. If RAM does not allow for the parameter value, an error message will be displayed and the run will be aborted. In record mode, subframes are copied in specific memory records not to disrupt regular behavior. When you estimate the recorded sequence is achieved, you should terminate the eNB/RRU by typing `CTRL-C`. At that time, up to the value of --subframes-max parameter will be written on disk. The eNB/RRU will indicate the exact count of subframes written to disk, which may be less (but not higher) that the value of --subframes-max parameter (120000 by default). The number of subframes written to disk is rounded to an integral number of frames. When replaying a file you should always specify the exact number of subframes, and thus use the exact number of subframes written during recording. You might experiment unexpected behavior if the number of subframes to be replayed does not match the number of subframes recorded. This might be improved in the future.
-Although it is possible to perform recording with a fronthaul setup, it is suggested to perform recording in full eNB mode and then replay in either full or split eNB.
+Note that the value of `--subframes-max` parameter needs to be tuned according to your RAM capabilities. The default value is 120000, which allows for 120 seconds of record/replay but will require ~3.6GB of RAM and disk space. 
+If RAM does not allow for the parameter value, an error message will be displayed and the run will be aborted. In record mode, to minimize pzerformance impact, 
+subframes are saved into memory and written to disk when the process is terminating . When you estimate the recorded sequence is achieved, you should terminate the eNB/RRU by typing `CTRL-C`. At that time, up to the value of `--subframes-max` subframes will be written on disk. The eNB/RRU will indicate the exact count of subframes written to disk, which may be less (but not higher) that the value of `--subframes-max` parameter (120000 by default). The number of subframes written to disk is rounded to an integral number of frames. 
+Although it is possible to perform recording with a fronthaul setup, it is suggested to perform recording in full eNB mode and then replay in either monolithic or split eNB.
 The option can be used while operating full eNB or RCC/RRU linked by NGFI IF5/IF4p5 fronthaul techniques. One of the advantage of the record/replay technique is that you can replay on a fronthauling setup a file that has been recorded in full eNB mode. This can easily asserts that the fronthauling underlying set up or technique is correct.
 
 >recording session example:
@@ -72,7 +74,7 @@ U[HW]I ru thread Writing file header to /tmp/iqfile
 [PHY]I ru thread RU 0 rf device stopped
 ```
 
-###Playback/replay mode
+### Playback/replay mode
 The option works only for 5MHz bandwidth because the information stored in the iq's file header regarding bandwidth is not yet properly processed. 
  In this version,  mismatch between file content and run time parameters might lead to unpredictable results. In addition a file recorded on a AVX2-capable processor cannot be replayed on a non-AVX2-capable processor (this is to be further investigated).
 options for replay mode are:
@@ -136,7 +138,7 @@ options for replay mode are:
 
 ## iq recorder and iq player implementation overview
 
-###configuration
+### configuration
 The iq's record/player is using the [configuration module](../../../../common/config/DOC/config.md). Configuration parameters supported by the record player are defined in the [record_player.h](../../COMMON/record_player.h) include file.
  There are no specific sections for the recorder or the replayer, parameters are defined under the `device.recplay`section and the `read_recplayconfig` function is common to both the recorder and the player. `device.recplay` configuration section is read from oai code common to all devices:
 Implemented in [record_player.c](../../COMMON/record_player.c), the `read_recplayconfig` function is called from `load_lib` and reads the configuration parameters, saving them in a `recplay_conf_t` sub-structure of the oai device. It also allocates a `recplay_state_t` structure which will save the recorder or player data. 

From 334519d16a9da34118c5568859eab6f68ae93ca9 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Wed, 26 Feb 2020 12:52:40 +0100
Subject: [PATCH 277/343] Fixed several bugs in UE initial sync procedures Now
 UE gets sync all time in rfsimulator. Yet to be tested with hardware.

---
 openair1/PHY/MODULATION/slot_fep_nr.c         | 175 ++++++++++++++++++
 .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c     |   6 +-
 openair1/PHY/NR_UE_TRANSPORT/pss_nr.c         |   6 +-
 3 files changed, 181 insertions(+), 6 deletions(-)

diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index d312e78f13..4bfc3ff30f 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -204,6 +204,181 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
   }
 
 
+#ifdef DEBUG_FEP
+  printf("slot_fep: done\n");
+#endif
+  return(0);
+}
+
+int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
+                unsigned char symbol,
+                unsigned char Ns,
+                int sample_offset,
+                int no_prefix)
+{
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  NR_UE_COMMON *common_vars   = &ue->common_vars;
+  unsigned char aa;
+  unsigned int nb_prefix_samples;
+  unsigned int nb_prefix_samples0;
+  unsigned int abs_symbol;
+  if (ue->is_synchronized) {
+    nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+    nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+  }
+  else {
+    nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+    nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+  }
+  //unsigned int subframe_offset;//,subframe_offset_F;
+  unsigned int slot_offset;
+  //int i;
+  unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
+  unsigned int rx_offset;
+
+
+  void (*dft)(int16_t *,int16_t *, int);
+  int tmp_dft_in[8192] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
+
+  switch (frame_parms->ofdm_symbol_size) {
+  case 128:
+    dft = dft128;
+    break;
+
+  case 256:
+    dft = dft256;
+    break;
+
+  case 512:
+    dft = dft512;
+    break;
+
+  case 1024:
+    dft = dft1024;
+    break;
+
+  case 1536:
+    dft = dft1536;
+    break;
+
+  case 2048:
+    dft = dft2048;
+    break;
+
+  case 3072:
+    dft = dft3072;
+    break;
+
+  case 4096:
+    dft = dft4096;
+    break;
+
+  case 8192:
+    dft = dft8192;
+    break;
+
+  default:
+    printf("unsupported ofdm symbol size \n");
+    assert(0);
+  }
+
+  if (no_prefix) {
+    slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
+  } else {
+    slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
+  }
+
+  /*if (l<0 || l>=7-frame_parms->Ncp) {
+    printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
+    return(-1);
+    }*/
+
+  if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
+    printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
+    return(-1);
+  }
+
+  for (aa=0; aanb_antennas_rx; aa++) {
+    memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
+
+    rx_offset = sample_offset + slot_offset - SOFFSET;
+    // Align with 256 bit
+    //    rx_offset = rx_offset&0xfffffff8;
+
+#ifdef DEBUG_FEP
+      //  if (ue->frame <100)
+    /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
+    		ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
+#endif
+
+    abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
+    
+    for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
+      rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
+
+    rx_offset += frame_parms->ofdm_symbol_size * symbol;
+
+    if (abs_symbol%(0x7<numerology_index)) {
+
+      rx_offset += nb_prefix_samples;
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
+               (short*) &common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *) &common_vars->rxdata[aa][rx_offset],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+#if UE_TIMING_TRACE
+          start_meas(&ue->rx_dft_stats);
+#endif
+
+        dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+#if UE_TIMING_TRACE
+        stop_meas(&ue->rx_dft_stats);
+#endif
+      }
+    } else {
+
+      rx_offset += nb_prefix_samples0;
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
+               (void *) &common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+#if UE_TIMING_TRACE
+      start_meas(&ue->rx_dft_stats);
+#endif
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *) &common_vars->rxdata[aa][rx_offset],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+
+        dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      }
+#if UE_TIMING_TRACE
+      stop_meas(&ue->rx_dft_stats);
+#endif
+
+
+    }
+
+    #ifdef DEBUG_FEP
+        //  if (ue->frame <100)
+        printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset);
+    #endif
+  }
+
+
 #ifdef DEBUG_FEP
   printf("slot_fep: done\n");
 #endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index d2dc8a95fd..bc687a917f 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -255,7 +255,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
 	double s_time = 1/(1.0e3*fp->samples_per_subframe);  // sampling time
 	double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset);  // offset rotation angle compensation per sample
 
-	int start = ue->ssb_offset;  // start for offset correction is at ssb_offset (pss time position)
+	int start = is*fp->samples_per_frame+ue->ssb_offset;  // start for offset correction is at ssb_offset (pss time position)
   	int end = start + 4*(fp->ofdm_symbol_size + fp->nb_prefix_samples);  // loop over samples in 4 symbols (ssb size), including prefix  
 
 	for(int n=start; nssb_offset,
+	            is*fp->samples_per_frame+ue->ssb_offset,
 	            0);
 
 #ifdef DEBUG_INITIAL_SYNCH
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index b13cd008b5..070d01b5a3 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -880,7 +880,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
 
           /* perform correlation of rx data and pss sequence ie it is a dot product */
           result  = dot_product64((short*)primary_synchro_time_nr[pss_index], 
-				  (short*) &(rxdata[ar][n])+(is*frame_parms->samples_per_frame), 
+				  (short*) &(rxdata[ar][n+is*frame_parms->samples_per_frame]), 
 				  frame_parms->ofdm_symbol_size, 
 				  shift);
 	  pss_corr_ue[pss_index][n] += abs64(result);
@@ -914,13 +914,13 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
 	  int64_t result1,result2;
 	  // Computing cross-correlation at peak on half the symbol size for first half of data
 	  result1  = dot_product64((short*)primary_synchro_time_nr[pss_source], 
-				  (short*) &(rxdata[0][peak_position])+(is*frame_parms->samples_per_frame), 
+				  (short*) &(rxdata[0][peak_position+is*frame_parms->samples_per_frame]), 
 				  frame_parms->ofdm_symbol_size>>1, 
 				  shift);
 	  // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size 
 	  // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
 	  result2  = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size), 
-				  (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)), 
+				  (short*) &(rxdata[0][peak_position+frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)]), 
 				  frame_parms->ofdm_symbol_size>>1, 
 				  shift);
 

From f59f8032f581c1f362cfb1cce970c088b610a612 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Wed, 26 Feb 2020 15:43:47 +0100
Subject: [PATCH 278/343] Removed DEFAULT_DLF from UE

---
 executables/nr-uesoftmodem.h   | 4 +---
 executables/softmodem-common.h | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 51a328fba3..7fad43e897 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -54,8 +54,6 @@
     {"usrp-args",                CONFIG_HLP_USRP_ARGS,   0,              strptr:(char **)&usrp_args,         defstrval:"type=b200", TYPE_STRING,   0}      \
   }
 
-#define DEFAULT_DLF 0
-
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            command line parameters common to eNodeB and UE                                                         */
 /*   optname                helpstr                 paramflags      XXXptr                                 defXXXval              type         numelt */
@@ -65,7 +63,7 @@
   {"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}, \
-  {"C" ,                    CONFIG_HLP_DLF,         0,              u64ptr:&(downlink_frequency[0][0]),    defuintval:DEFAULT_DLF,TYPE_UINT64, 0}, \
+  {"C" ,                    CONFIG_HLP_DLF,         0,              u64ptr:&(downlink_frequency[0][0]),    defuintval:0,TYPE_UINT64, 0}, \
   {"a" ,                    CONFIG_HLP_CHOFF,       0,              iptr:&chain_offset,                    defintval:0,           TYPE_INT,    0}, \
   {"d" ,                    CONFIG_HLP_SOFTS,       PARAMFLAG_BOOL, uptr:&do_forms,                        defintval:0,           TYPE_INT,    0}, \
   {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL, iptr:&threequarter_fs,                 defintval:0,           TYPE_INT,    0}, \
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index a8a05a5971..f0984056fa 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -100,8 +100,6 @@ extern "C"
 
 #define DEFAULT_RFCONFIG_FILE    "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
 
-#define DEFAULT_DLF 2680000000
-
 #define CMDLINE_PARAMS_DESC {  \
     {"rf-config-file",       CONFIG_HLP_RFCFGF,       0,              strptr:(char **)&RF_CONFIG_FILE,    defstrval:NULL,        TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
     {"phy-test",             CONFIG_HLP_PHYTST,       PARAMFLAG_BOOL, iptr:&PHY_TEST,                     defintval:0,           TYPE_INT,    0},                     \
@@ -109,7 +107,7 @@ extern "C"
     {"clock",                CONFIG_HLP_CLK,          0,              uptr:&CLOCK_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
     {"wait-for-sync",        NULL,                    PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC,                defintval:0,           TYPE_INT,    0},                     \
     {"single-thread-enable", CONFIG_HLP_NOSNGLT,      PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG,           defintval:0,           TYPE_INT,    0},                     \
-    {"C" ,                   CONFIG_HLP_DLF,          0,              u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT64,   0},                     \
+    {"C" ,                   CONFIG_HLP_DLF,          0,              u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64,   0},                     \
     {"a" ,                   CONFIG_HLP_CHOFF,        0,              iptr:&CHAIN_OFFSET,                 defintval:0,           TYPE_INT,    0},                     \
     {"d" ,                   CONFIG_HLP_SOFTS,        PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms,         defintval:0,           TYPE_INT8,   0},                     \
     {"q" ,                   CONFIG_HLP_STMON,        PARAMFLAG_BOOL, iptr:&opp_enabled,                  defintval:0,           TYPE_INT,    0},                     \

From a8301b9aacdc61690337c3f0f32cb293ddaa32e6 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Thu, 27 Feb 2020 15:50:53 +0100
Subject: [PATCH 279/343] More fixes for FR2

---
 executables/nr-ue.c                         | 35 ++++++++++++++-------
 openair1/PHY/MODULATION/slot_fep_nr.c       |  2 +-
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c |  4 +++
 3 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8a868b37ba..8b8b8be6eb 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -634,6 +634,22 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
   return 0;
 }
 
+inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
+  if (fp->numerology_index == 0)
+    return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
+  int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
+  num_samples += fp->ofdm_symbol_size;
+  return num_samples;
+}
+
+inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
+  int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
+  int next_slot_first_symbol = 0;
+  if (slot < (fp->slots_per_frame-1))
+    next_slot_first_symbol = get_firstSymSamp(slot+1, fp);
+  return rem_samples + next_slot_first_symbol;
+}
+
 void *UE_thread(void *arg) {
   //this thread should be over the processing thread to keep in real time
   PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
@@ -743,9 +759,9 @@ void *UE_thread(void *arg) {
     }*/
 #endif
 
+    int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
     for (int i=0; iframe_parms.nb_antennas_rx; i++)
-      rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
-               UE->frame_parms.nb_prefix_samples0+UE->frame_parms.
+      rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
                get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
 
     for (int i=0; iframe_parms.nb_antennas_tx; i++)
@@ -755,13 +771,11 @@ void *UE_thread(void *arg) {
     int readBlockSize, writeBlockSize;
 
     if (slot_nr<(nb_slot_frame - 1)) {
-      readBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms);
+      readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
       writeBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms);
     } else {
       UE->rx_offset_diff = computeSamplesShift(UE);
-      readBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms) -
-                    UE->frame_parms.ofdm_symbol_size -
-                    UE->frame_parms.nb_prefix_samples0 -
+      readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
                     UE->rx_offset_diff;
       writeBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms) -
                      UE->rx_offset_diff;
@@ -778,8 +792,7 @@ void *UE_thread(void *arg) {
                  UE->rfdevice.trx_write_func(&UE->rfdevice,
                      timestamp+
                      UE->frame_parms.get_samples_slot_timestamp(slot_nr,
-                     &UE->frame_parms,DURATION_RX_TO_TX) -
-                     UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
+                     &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp -
                      openair0_cfg[0].tx_sample_advance,
                      txp,
                      writeBlockSize,
@@ -788,7 +801,7 @@ void *UE_thread(void *arg) {
 
     if( slot_nr==(nb_slot_frame-1)) {
       // read in first symbol of next frame and adjust for timing drift
-      int first_symbols=writeBlockSize-readBlockSize;
+      int first_symbols=UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0; // first symbol of every frames
 
       if ( first_symbols > 0 )
         AssertFatal(first_symbols ==
@@ -803,8 +816,8 @@ void *UE_thread(void *arg) {
 
     curMsg->proc.timestamp_tx = timestamp+
                                 UE->frame_parms.get_samples_slot_timestamp(slot_nr,
-                                &UE->frame_parms,DURATION_RX_TO_TX) -
-                                UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
+                                &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp;
+
     notifiedFIFO_elt_t *res;
 
     while (nbSlotProcessing >= RX_NB_TH) {
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 4bfc3ff30f..f2e5d24bad 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -139,7 +139,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
     abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
     
     for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
-      rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
+      rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
 
     rx_offset += frame_parms->ofdm_symbol_size * symbol;
 
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 1a5498dc4c..4aec03e25f 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -1409,6 +1409,8 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_com
 
   // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
   switch (bwp_ul_NB_RB) {
+    case 32:  bw_scaling =  4; break;
+    case 66:  bw_scaling =  8; break;
     case 106: bw_scaling = 16; break;
     case 217: bw_scaling = 32; break;
     case 245: bw_scaling = 32; break;
@@ -3782,6 +3784,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
         // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
         switch (ue->frame_parms.N_RB_DL) {
+          case 32:  bw_scaling =  4; break;
+          case 66:  bw_scaling =  8; break;
           case 106: bw_scaling = 16; break;
           case 217: bw_scaling = 32; break;
           case 245: bw_scaling = 32; break;

From 4bfcef6e168e8fed305ebf4cff186d83763eed69 Mon Sep 17 00:00:00 2001
From: Raphael Defosseux 
Date: Thu, 27 Feb 2020 16:46:41 +0100
Subject: [PATCH 280/343] CI: fixing the infinite loop w/ UE crashes before
 "got sync" message

Signed-off-by: Raphael Defosseux 
---
 ci-scripts/main.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index e122339269..2a4da2818f 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -1104,6 +1104,9 @@ class SSHConnection():
 				if result is not None:
 					self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4)
 					time.sleep(3)
+				outterLoopCounter = outterLoopCounter - 1
+				if (outterLoopCounter == 0):
+					doOutterLoop = False
 				continue
 			if self.air_interface == 'nr':
 				fullSyncStatus = True

From f54175c9a00d4b54aabcbf1c4182833e3e2635b2 Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Thu, 27 Feb 2020 17:09:24 +0100
Subject: [PATCH 281/343] fix for test_case_list.xml file w.r.t. nr_dlsim
 tests. Still a few tests failing, but .xml syntax errors are fixed

---
 cmake_targets/autotests/test_case_list.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 78e4577d31..3a02cfe30c 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1089,7 +1089,7 @@
                                  (Test8: 217 PRB 100 PDSCH-PRBs),
                                  (Test9: 217 PRB 80 PDSCH-Offset),
                                  (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
-                                 (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28)
+                                 (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 27)
                                  (Test12: 106 PRBs 50 PDSCH-PRBs MCS Index 16)
       
       $OPENAIR_DIR/cmake_targets/build_oai
@@ -1107,7 +1107,7 @@
                   -n100 -R217 -b100 -s5
                   -n100 -R217 -a80 -s5
                   -n100 -R217 -a110 -s5 -b100
-                  -n100 -e287 -s20 
+                  -n100 -e27 -s20 
                   -n100 -e16 -s10 
       
       nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12
@@ -1256,7 +1256,7 @@
                       -n100 -m16 -s10
                       -n100 -m28 -s20
                       -n100 -m9 -R217 -r217 -s0
-                      -n100 -m9 -R273 -r273 -s0
+                      -n100 -m9 -R273 -r273 -s0
       nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5
       PUSCH test OK
       segmentation fault|assertion|exiting|fatal

From 5c041cc1537f5fb56e200d43bc3849335ebaf425 Mon Sep 17 00:00:00 2001
From: Florian Kaltenberger 
Date: Thu, 27 Feb 2020 18:06:10 +0100
Subject: [PATCH 282/343] removing deprecated nr-uesoftmodem command line
 parameters from CI test

---
 ci-scripts/runTestOnVM.sh                   | 2 +-
 ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 07ab50246b..c3010330f7 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -1260,7 +1260,7 @@ function start_rf_sim_nr_ue {
     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 --phy-test --rrc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
+        echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR}  ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --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
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index 5b55d4655a..bd723aa8b6 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -52,7 +52,7 @@
         
                 Initialize_OAI_UE
                 Initialize NR UE USRP
-		-C 3510000000 --numerology 1 -r 106 --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path ci-scripts/rrc-files
+		--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path ci-scripts/rrc-files
 		NR
         
 

From bf3621c5a80a04bd1099e5f1e24abd58b7936d47 Mon Sep 17 00:00:00 2001
From: Raphael Defosseux 
Date: Fri, 28 Feb 2020 11:53:25 +0100
Subject: [PATCH 283/343] CI: needs to append CI workspace path to UE RRC conf
 files

Signed-off-by: Raphael Defosseux 
---
 ci-scripts/main.py                          | 8 +++++++-
 ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml | 2 +-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 2a4da2818f..63e455c649 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -1043,6 +1043,12 @@ class SSHConnection():
 			logging.debug('Found a N3xx device --> resetting it')
 		self.command('cd ' + self.UESourceCodePath, '\$', 5)
 		# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
+		# in case of NR-UE, we may have rrc_config_path (Temporary?)
+		modifiedUeOptions = str(self.Initialize_OAI_UE_args)
+		if self.air_interface == 'nr':
+			result = re.search('--rrc_config_path ', modifiedUeOptions)
+			if result is not None:
+				modifiedUeOptions = modifiedUeOptions.replace('rrc_config_path ', 'rrc_config_path ' + self.UESourceCodePath + '/')
 		self.command('source oaienv', '\$', 5)
 		self.command('cd cmake_targets/ran_build/build', '\$', 5)
 		if self.air_interface == 'lte':
@@ -1057,7 +1063,7 @@ class SSHConnection():
 					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)
-		self.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		self.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
 		self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
 		self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
 		self.UELogFile = 'ue_' + self.testCase_id + '.log'
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index bd723aa8b6..30a8772df7 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -24,7 +24,7 @@
         run-oai-gnb-nr-ue
         Run-gNB-and-NR-UE
         tasks	
-	4
+	2
 	
 090101 000001 090102 000002 090108 090109
 	

From b4f46144fe376f75f61bf77d03efbb6f83660c45 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Fri, 28 Feb 2020 17:30:21 +0100
Subject: [PATCH 284/343] Fixed bugs in frame sync for UE UE is a bit more
 stable now

---
 executables/nr-ue.c                            | 9 ++++++---
 openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 8 +++++++-
 openair1/PHY/defs_nr_UE.h                      | 1 +
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8b8b8be6eb..212de80f06 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -666,6 +666,8 @@ void *UE_thread(void *arg) {
   int thread_idx=0;
   notifiedFIFO_t freeBlocks;
   initNotifiedFIFO_nothreadSafe(&freeBlocks);
+  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+
 
   for (int i=0; iproc.decoded_frame_rx+trashed_frames) % MAX_FRAME_NUMBER;
+        decoded_frame_rx=((((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx) +
+                         (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
         delNotifiedFIFO_elt(res);
       } else {
         readFrame(UE, ×tamp, true);
-        trashed_frames++;
+        trashed_frames+=2;
         continue;
       }
     }
@@ -722,7 +725,7 @@ void *UE_thread(void *arg) {
       // 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 begin of frame;
-      absolute_slot=decoded_frame_rx*nb_slot_frame + nb_slot_frame -1;
+      absolute_slot=decoded_frame_rx*nb_slot_frame -1;
       continue;
     }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index bc687a917f..61748a8e56 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -303,7 +303,13 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
         // sync at symbol ue->symbol_offset
         // computing the offset wrt the beginning of the frame
         sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
-        ue->rx_offset = ue->ssb_offset - sync_pos_frame;
+
+        if (ue->ssb_offset < sync_pos_frame)
+          ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
+        else
+          ue->rx_offset = ue->ssb_offset - sync_pos_frame;
+
+        ue->init_sync_frame = is;
       }   
 
       nr_gold_pdcch(ue,0, 2);
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 1ad0c7529e..4774bd4402 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -1012,6 +1012,7 @@ typedef struct {
   //  uint8_t               prach_timer;
   uint8_t               decode_SIB;
   uint8_t               decode_MIB;
+  uint8_t               init_sync_frame;
   /// temporary offset during cell search prior to MIB decoding
   int              ssb_offset;
   uint16_t	   symbol_offset; // offset in terms of symbols for detected ssb in sync

From 795f25bb17c238fb4ba8fdb0508cc45b82a7bf44 Mon Sep 17 00:00:00 2001
From: Raphael Defosseux 
Date: Mon, 2 Mar 2020 14:38:26 +0100
Subject: [PATCH 285/343] CI: new new method to run simulated HSS

Signed-off-by: Raphael Defosseux 
---
 ci-scripts/main.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index e122339269..95360cae8f 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -674,7 +674,8 @@ class SSHConnection():
 			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)
+			# based on Robert's feedback, new method to run simulated HSS
+			self.command('sudo su -c "cd /opt/hss_sim0609 && screen -dm -S simulated_hss ./starthss_real"', '\$', 5)
 		else:
 			logging.error('This option should not occur!')
 		self.close()

From 66555e18c77148f8eee8c97c30e663d717ba2837 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Mon, 2 Mar 2020 18:29:05 +0100
Subject: [PATCH 286/343] setting sf_ahead depending on slots duration

---
 executables/nr-gnb.c | 4 ++--
 executables/nr-ru.c  | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 84aa00210d..e7af164877 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -103,8 +103,8 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
 
 extern int transmission_mode;
 
-uint16_t sf_ahead=3;
-uint16_t sl_ahead;
+extern uint16_t sf_ahead;
+extern uint16_t sl_ahead;
 //pthread_t                       main_gNB_thread;
 
 time_stats_t softmodem_stats_mt; // main thread
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index fdf07d4f79..fe10988462 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -131,8 +131,8 @@ void configure_rru(int idx, void *arg);
 int attach_rru(RU_t *ru);
 int connect_rau(RU_t *ru);
 
-extern uint16_t sf_ahead;
-extern uint16_t sl_ahead;
+uint16_t sf_ahead;
+uint16_t sl_ahead;
 
 extern int emulate_rf;
 extern int numerology;
@@ -1454,6 +1454,7 @@ void *ru_thread( void *param ) {
     }
   }
 
+  sf_ahead = (uint16_t) ceil((float)6/(0x01<numerology_index));
   LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
   pthread_mutex_lock(&RC.ru_mutex);
   RC.ru_mask &= ~(1<idx);

From 52fa969730add97d56db3e7c659988f3b5eace2d Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Mon, 2 Mar 2020 18:29:52 +0100
Subject: [PATCH 287/343] fixing wrong writeBlockSize in UE

---
 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 212de80f06..8ee5414c36 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -775,12 +775,12 @@ void *UE_thread(void *arg) {
 
     if (slot_nr<(nb_slot_frame - 1)) {
       readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
-      writeBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms);
+      writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms);
     } else {
       UE->rx_offset_diff = computeSamplesShift(UE);
       readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
                     UE->rx_offset_diff;
-      writeBlockSize=UE->frame_parms.get_samples_per_slot(slot_nr,&UE->frame_parms) -
+      writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms) -
                      UE->rx_offset_diff;
     }
 

From a07a830a0fcabf08e4c831cb1a7f9ac6a7080022 Mon Sep 17 00:00:00 2001
From: Thomas Dreibholz 
Date: Tue, 3 Mar 2020 10:26:14 +0100
Subject: [PATCH 288/343] Check result of openair0_device_load() and exit when
 loading the device fails.

---
 targets/RT/USER/lte-ru.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index f88d98536d..aa359b28a9 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2342,7 +2342,11 @@ void init_RU_proc(RU_t *ru) {
     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);
+    ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
+    if (ret < 0) {
+       LOG_I(PHY,"Exiting, cannot load device\n");
+       exit(1);
+    }
 
     if (setup_RU_buffers(ru)!=0) {
       printf("Exiting, cannot initialize RU Buffers\n");

From 04789ff9f50c2250707280bfa588b2360a082884 Mon Sep 17 00:00:00 2001
From: Thomas Dreibholz 
Date: Tue, 3 Mar 2020 10:37:38 +0100
Subject: [PATCH 289/343] Made error message more informative.

---
 targets/RT/USER/lte-ru.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index aa359b28a9..43cb414bd3 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2344,7 +2344,7 @@ void init_RU_proc(RU_t *ru) {
     phy_init_RU(ru);
     ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
     if (ret < 0) {
-       LOG_I(PHY,"Exiting, cannot load device\n");
+       LOG_I(PHY,"Exiting, cannot load device. Make sure that your SDR board is connected!\n");
        exit(1);
     }
 

From 34c118c03e75059b0c6fd5207c403eec708e63ec Mon Sep 17 00:00:00 2001
From: Thomas Dreibholz 
Date: Tue, 3 Mar 2020 10:29:29 +0100
Subject: [PATCH 290/343] Error should create a log entry, not use printf().

---
 targets/RT/USER/lte-ru.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 43cb414bd3..fa08d96b5f 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2349,8 +2349,8 @@ void init_RU_proc(RU_t *ru) {
     }
 
     if (setup_RU_buffers(ru)!=0) {
-      printf("Exiting, cannot initialize RU Buffers\n");
-      exit(-1);
+      LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
+      exit(1);
     }
   }
 

From df8e9ddbb3f71f50fe00e5c1a4d4e3f278e76bdc Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Wed, 4 Mar 2020 11:21:14 +0100
Subject: [PATCH 291/343] update to the fix for initial sync

---
 executables/nr-ue.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8ee5414c36..10739d797c 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -666,8 +666,6 @@ void *UE_thread(void *arg) {
   int thread_idx=0;
   notifiedFIFO_t freeBlocks;
   initNotifiedFIFO_nothreadSafe(&freeBlocks);
-  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
-
 
   for (int i=0; imib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx) +
-                         (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+        decoded_frame_rx=(tmp->proc.decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
         delNotifiedFIFO_elt(res);
       } else {
         readFrame(UE, ×tamp, true);

From fbe0695b21a8238b9f3e3466632651feab15e28a Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Wed, 4 Mar 2020 12:41:56 +0100
Subject: [PATCH 292/343] some rfsim fixes

---
 executables/nr-ue.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 10739d797c..67f6169868 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -593,22 +593,21 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
     LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
     void *dummy_tx[UE->frame_parms.nb_antennas_tx];
 
-    for (int i=0; iframe_parms.nb_antennas_tx; i++)
-      dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
-
+    *timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
     for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
       int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
+      // we write before read becasue gNB waits for UE to write and both executions halt
+      // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
+      if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
       AssertFatal(unitTransfer ==
                   UE->rfdevice.trx_read_func(&UE->rfdevice,
                                              timestamp,
                                              (void **)UE->common_vars.rxdata,
                                              unitTransfer,
                                              UE->frame_parms.nb_antennas_rx),"");
+      *timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
     }
 
-    for (int i=0; iframe_parms.nb_antennas_tx; i++)
-      free(dummy_tx[i]);
-
 }
 
 int computeSamplesShift(PHY_VARS_NR_UE *UE) {

From a51dc94e8bed5a8cf6839ced6bbddceb5e9374cc Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 3 Mar 2020 19:18:49 +0100
Subject: [PATCH 293/343] Set correct UE ID in Kenb Refresh Req

NAS triggered the Kenb Refresh Req always for (hardcoded) UE 0. This
fixes this by setting the correct UE ID.

An effect of this was that the Kenb would always be set for UE 0,
regardless for which UE it was actually intended. This led for integrity
check failures for every UE with ID > 0.
---
 openair3/NAS/UE/EMM/SecurityModeControl.c | 2 +-
 openair3/NAS/UE/nas_itti_messaging.c      | 4 ++--
 openair3/NAS/UE/nas_itti_messaging.h      | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c
index 7bdd21572e..67bfaf784e 100644
--- a/openair3/NAS/UE/EMM/SecurityModeControl.c
+++ b/openair3/NAS/UE/EMM/SecurityModeControl.c
@@ -286,7 +286,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
       user->emm_data->security->selected_algorithms.encryption = seea;
       user->emm_data->security->selected_algorithms.integrity  = seia;
 #if  defined(NAS_BUILT_IN_UE)
-      nas_itti_kenb_refresh_req(security_data->kenb.value);
+      nas_itti_kenb_refresh_req(security_data->kenb.value, user->ueid);
 #endif
 
     }
diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c
index 55566700d7..885ebbdd81 100644
--- a/openair3/NAS/UE/nas_itti_messaging.c
+++ b/openair3/NAS/UE/nas_itti_messaging.c
@@ -100,7 +100,7 @@ int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const i
 
 extern unsigned char NB_eNB_INST;
 
-int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) {
+int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id) {
   MessageDef *message_p;
   message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ);
   memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
@@ -125,7 +125,7 @@ int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) {
     kenb[20], kenb[21], kenb[22], kenb[23],
     kenb[24], kenb[25], kenb[26], kenb[27],
     kenb[28], kenb[29], kenb[30], kenb[31]);
-  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
+  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p);
 }
 
 int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) {
diff --git a/openair3/NAS/UE/nas_itti_messaging.h b/openair3/NAS/UE/nas_itti_messaging.h
index d958317e5a..967bbb3059 100644
--- a/openair3/NAS/UE/nas_itti_messaging.h
+++ b/openair3/NAS/UE/nas_itti_messaging.h
@@ -48,7 +48,7 @@ int nas_itti_protected_msg(
 
 # if defined(NAS_BUILT_IN_UE)
 
-int nas_itti_kenb_refresh_req(const Byte_t kenb[32]);
+int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id);
 
 int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id);
 

From 05577be422c3324c6cdfe40ea9f9807ba9c5ae89 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Wed, 4 Mar 2020 09:58:00 +0100
Subject: [PATCH 294/343] Reduce logging verbosity and levels

---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 8 ++++----
 openair3/NAS/COMMON/UTIL/nas_log.h   | 9 +++++----
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 14974c2e15..4b331c1cb0 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -209,8 +209,8 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL
 	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length					 = 0;
 
 
-	          LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n");
-	          LOG_E(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
+	          //LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n");
+	          LOG_I(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
 	        	  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.preamble,
 	        	  UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti,
@@ -685,7 +685,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //,
 				if((dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index >= 0) &&(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)){
 				//if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
 
-					LOG_E(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems);
+					LOG_I(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems);
 
 					ue_send_sdu(Mod_id, 0, sfn, sf,
 							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
@@ -699,7 +699,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //,
 				}
 			}
 			else {
-				LOG_E(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf);
+				LOG_W(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf);
 				i++;
 			}
 		}
diff --git a/openair3/NAS/COMMON/UTIL/nas_log.h b/openair3/NAS/COMMON/UTIL/nas_log.h
index b41e34c51b..d1531fa6db 100644
--- a/openair3/NAS/COMMON/UTIL/nas_log.h
+++ b/openair3/NAS/COMMON/UTIL/nas_log.h
@@ -95,14 +95,15 @@ typedef enum {
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
 /****************************************************************************/
 
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
 #ifdef LOG_E
 # define LOG_TRACE(s, x, args...)                               \
 do {                                                            \
     switch (s) {                                                \
-        case ERROR:     LOG_E(NAS, " %s:%d  " x "\n", __FILE__, __LINE__, ##args); break;  \
-        case WARNING:   LOG_W(NAS, " %s:%d  " x "\n", __FILE__, __LINE__, ##args); break;  \
-        case INFO:      LOG_I(NAS, " %s:%d  " x "\n", __FILE__, __LINE__, ##args); break;  \
-        default:        LOG_D(NAS, " %s:%d  " x "\n", __FILE__, __LINE__, ##args); break;  \
+        case ERROR:     LOG_E(NAS, " %s:%d  " x "\n", __FILENAME__, __LINE__, ##args); break;  \
+        case WARNING:   LOG_W(NAS, " %s:%d  " x "\n", __FILENAME__, __LINE__, ##args); break;  \
+        case INFO:      LOG_I(NAS, " %s:%d  " x "\n", __FILENAME__, __LINE__, ##args); break;  \
+        default:        LOG_D(NAS, " %s:%d  " x "\n", __FILENAME__, __LINE__, ##args); break;  \
     }                                                           \
 } while (0)
 

From e72e1d87f2b45f0f22cf152b255f1c451a994a7c Mon Sep 17 00:00:00 2001
From: adk 
Date: Mon, 3 Feb 2020 17:02:30 +0100
Subject: [PATCH 295/343] added PUSCH PTRS structs (UE + gNB) and parameters
 initialization

---
 openair1/PHY/INIT/nr_init.c                   | 19 ++++++++++--
 openair1/PHY/INIT/nr_init_ue.c                | 25 ++++++++++++++--
 .../NR_ESTIMATION/nr_ul_channel_estimation.c  |  2 +-
 openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c    |  2 +-
 .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c  | 10 +++----
 openair1/PHY/NR_UE_TRANSPORT/dci_nr.c         |  2 +-
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    | 12 ++++----
 openair1/PHY/defs_gNB.h                       |  5 ++--
 openair1/PHY/defs_nr_UE.h                     |  4 ++-
 openair1/PHY/impl_defs_nr.h                   | 30 +++++++++++++++++--
 openair1/SCHED_NR/phy_procedures_nr_gNB.c     |  4 +--
 11 files changed, 87 insertions(+), 28 deletions(-)

diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index f0ad3cbaae..f10a7426dd 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -85,6 +85,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   nfapi_nr_config_request_t *cfg    = &gNB->gNB_config;
   NR_gNB_COMMON *const common_vars  = &gNB->common_vars;
   NR_gNB_PUSCH **const pusch_vars   = gNB->pusch_vars;
+  dmrs_UplinkConfig_t *dmrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig;
+  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   /*LTE_eNB_SRS *const srs_vars       = gNB->srs_vars;
   LTE_eNB_PRACH *const prach_vars   = &gNB->prach_vars;*/
 
@@ -154,9 +156,9 @@ 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_pos0;
-  gNB->dmrs_UplinkConfig.pusch_maxLength = pusch_len1;
+  dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
+  dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
+  dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
   //--------------------------------------------------------------------------------//
 
   nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
@@ -168,6 +170,17 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
   }
 
+  gNB->ptrs_configured = 0;
+
+  //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------//
+  ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
+  ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0;
+  ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0;
+  ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0;     // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
+  ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0;
+  ptrs_Uplink_Config->resourceElementOffset = 0;
+  //--------------------------------------------------------------------------------//
+
   /// Transport init necessary for NR synchro
   init_nr_transport(gNB);
 
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 461f441b2c..7b7954583d 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -659,6 +659,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   abstraction_flag = 0;
   fp->nb_antennas_tx = 1;
   fp->nb_antennas_rx=1;
+  dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
+  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
   //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
   nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,fp->N_RB_DL,n_ssb_crb,k_ssb);
@@ -711,9 +713,9 @@ 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_pos0;
-  ue->dmrs_UplinkConfig.pusch_maxLength = pusch_len1;
+  dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
+  dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
+  dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
   //-------------------------------------------------//
   ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1;
   ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0;
@@ -743,6 +745,23 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   ///////////
   ////////////////////////////////////////////////////////////////////////////////////////////
 
+  /////////////////////////PUSCH PTRS init/////////////////////////
+  ///////////
+
+  ue->ptrs_configured = 0; // flag to be toggled by RCC
+
+  //------------- config PTRS parameters--------------//
+  ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
+  ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0;
+  ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0;
+  ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0;     // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
+  ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0;
+  ptrs_Uplink_Config->resourceElementOffset = 0;
+  //-------------------------------------------------//
+
+  ///////////
+  ////////////////////////////////////////////////////////////////////////////////////////////
+
   for (i=0; i<10; i++)
     ue->tx_power_dBm[i]=-127;
 
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index ab6ccd929b..83c6f054cd 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -117,7 +117,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
   //------------------generate DMRS------------------//
 
-  length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength;
+  length_dmrs = dmrs_UplinkConfig->pusch_maxLength;
 
   nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs);
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index 9736e97e34..a158d5bf62 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -338,7 +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.length_dmrs    = gNB->dmrs_UplinkConfig.pusch_maxLength;
+  rel15_ul->ulsch_pdu_rel15.length_dmrs    = gNB->pusch_config.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_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index eb35fd7dc6..1def3d5033 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -1030,12 +1030,12 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                                       0,
                                       0,
                                       rel15_ul->number_symbols,
-                                      &gNB->dmrs_UplinkConfig,
+                                      &gNB->pusch_config.dmrs_UplinkConfig,
                                       mapping_type,
                                       frame_parms->ofdm_symbol_size);
 
     if (dmrs_symbol_flag == 1){
-      nb_re_pusch = rel15_ul->number_rbs * ((gNB->dmrs_UplinkConfig.pusch_dmrs_type==pusch_dmrs_type1)?6:8);
+      nb_re_pusch = rel15_ul->number_rbs * ((gNB->pusch_config.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;
@@ -1054,7 +1054,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                                   symbol,
                                   bwp_start_subcarrier,
                                   rel15_ul->number_rbs,
-                                  &gNB->dmrs_UplinkConfig);
+                                  &gNB->pusch_config.dmrs_UplinkConfig);
 
     //----------------------------------------------------------
     //--------------------- RBs extraction ---------------------
@@ -1073,7 +1073,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                                 gNB->pusch_vars[UE_id]->dmrs_symbol,
                                 rel15_ul->number_symbols,
                                 mapping_type,
-                                &gNB->dmrs_UplinkConfig);
+                                &gNB->pusch_config.dmrs_UplinkConfig);
 
     nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
                            frame_parms,
@@ -1081,7 +1081,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                            symbol,
                            dmrs_symbol_flag,
                            rel15_ul->number_rbs,
-                           gNB->dmrs_UplinkConfig.pusch_dmrs_type);
+                           gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type);
 
     if (first_symbol_flag==1) {
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 69077f0276..162ab6958f 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -1975,7 +1975,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue,
   PUSCH_Config_t pusch_config       = ue->pusch_config;
   PUCCH_Config_t pucch_config_dedicated       = ue->pucch_config_dedicated_nr[eNB_id];
   crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig = ue->crossCarrierSchedulingConfig;
-  dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->dmrs_UplinkConfig;
+  dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->pusch_config.dmrs_UplinkConfig;
   dmrs_DownlinkConfig_t dmrs_DownlinkConfig = ue->dmrs_DownlinkConfig;
   csi_MeasConfig_t csi_MeasConfig = ue->csi_MeasConfig;
   PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig= ue->PUSCH_ServingCellConfig;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index b912834f9d..bdcbe3327a 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -142,14 +142,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                             0,
                                             0,
                                             harq_process_ul_ue->number_of_symbols,
-                                            &UE->dmrs_UplinkConfig,
+                                            &UE->pusch_config.dmrs_UplinkConfig,
                                             mapping_type,
                                             frame_parms->ofdm_symbol_size);
 
-    ulsch_ue->length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength;
+    ulsch_ue->length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength;
     ulsch_ue->rnti        = n_rnti;
     ulsch_ue->Nid_cell    = Nid_cell;
-    ulsch_ue->nb_re_dmrs  = ((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
+    ulsch_ue->nb_re_dmrs  = ((UE->pusch_config.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;
 
@@ -277,7 +277,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
   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;
+  dmrs_type = UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type;
   ///////////
   ////////////////////////////////////////////////////////////////////////
 
@@ -313,7 +313,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                              0,
                              0,
                              harq_process_ul_ue->number_of_symbols,
-                             &UE->dmrs_UplinkConfig,
+                             &UE->pusch_config.dmrs_UplinkConfig,
                              mapping_type,
                              frame_parms->ofdm_symbol_size);
 
@@ -379,7 +379,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                  n,
                                  delta,
                                  harq_process_ul_ue->number_of_symbols,
-                                 &UE->dmrs_UplinkConfig,
+                                 &UE->pusch_config.dmrs_UplinkConfig,
                                  mapping_type,
                                  frame_parms->ofdm_symbol_size);
 
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 3c0f0db8da..91a50d7361 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -669,6 +669,9 @@ typedef struct PHY_VARS_gNB_s {
 
   /// PDSCH DMRS sequence
   uint32_t ****nr_gold_pdsch_dmrs;
+
+  /// flag to indicate if PTRS is configured
+  uint8_t ptrs_configured;
   
   /// PUSCH DMRS
   uint32_t nr_gold_pusch[2][20][2][NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD];
@@ -727,8 +730,6 @@ 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];
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index d72979262c..de4f886903 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -1012,6 +1012,9 @@ typedef struct {
   /// PUSCH DMRS sequence
   uint32_t ****nr_gold_pusch_dmrs;
 
+  /// flag to indicate if PTRS is configured
+  uint8_t ptrs_configured;
+
   uint32_t X_u[64][839];
 
   uint32_t high_speed_flag;
@@ -1143,7 +1146,6 @@ typedef struct {
 
   crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig;
   supplementaryUplink_t supplementaryUplink;
-  dmrs_UplinkConfig_t dmrs_UplinkConfig;
   dmrs_DownlinkConfig_t dmrs_DownlinkConfig;
   csi_MeasConfig_t csi_MeasConfig;
   PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig;
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index 6e13973dd9..3519b97278 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -510,9 +510,6 @@ typedef struct {
   uint8_t         startSymbolAndLength;
 } PUSCH_TimeDomainResourceAllocation_t;
 ////////////////////////////////////////////////////////////////////////////////################################
-typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS)
-
-} ptrs_UplinkConfig_t;
 typedef enum{
   maxCodeBlockGroupsPerTransportBlock_n2 = 2,
   maxCodeBlockGroupsPerTransportBlock_n4 = 4,
@@ -544,6 +541,12 @@ typedef enum {
   pusch_dmrs_pos2 = 2,
   pusch_dmrs_pos3 = 3,
 } pusch_dmrs_AdditionalPosition_t;
+typedef enum {
+  offset00 = 0,
+  offset01 = 1,
+  offset10 = 2,
+  offset11 = 3,
+} ptrs_resource_elementoffset_t;
 typedef enum {
   pdsch_len1 = 1,
   pdsch_len2 = 2
@@ -552,6 +555,22 @@ typedef enum {
   pusch_len1 = 1,
   pusch_len2 = 2
 } pusch_maxLength_t;
+typedef struct {
+  uint8_t ptrs_mcs1;
+  uint8_t ptrs_mcs2;
+  uint8_t ptrs_mcs3;
+} ptrs_time_density_t;
+typedef struct {
+  uint16_t n_rb0;
+  uint16_t n_rb1;
+} ptrs_frequency_density_t;
+typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS)
+  uint8_t  num_ptrs_ports;
+  ptrs_resource_elementoffset_t resourceElementOffset;
+  ptrs_time_density_t  timeDensity;
+  ptrs_frequency_density_t  frequencyDensity;
+  uint32_t  ul_ptrs_power;
+} ptrs_UplinkConfig_t;
 typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH
   pdsch_dmrs_type_t pdsch_dmrs_type;
   pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition;
@@ -563,6 +582,7 @@ typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodul
   pusch_dmrs_type_t pusch_dmrs_type;
   pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition;
   pusch_maxLength_t pusch_maxLength;
+  ptrs_UplinkConfig_t ptrs_UplinkConfig;
   uint16_t scramblingID0;
   uint16_t scramblingID1;
 } dmrs_UplinkConfig_t;
@@ -647,6 +667,10 @@ typedef struct {
  * resourceAllocation
  */
   ul_resourceAllocation_t ul_resourceAllocation;
+/*
+ * DMRS-Uplinkconfig
+ */
+  dmrs_UplinkConfig_t dmrs_UplinkConfig;
 /*
  * rgb_Size
  */
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index fb6d1a6c37..40bbe7322d 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -244,11 +244,11 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id
                                             0,
                                             0,
                                             number_symbols,
-                                            &gNB->dmrs_UplinkConfig,
+                                            &gNB->pusch_config.dmrs_UplinkConfig,
                                             mapping_type,
                                             frame_parms->ofdm_symbol_size);
 
-  nb_re_dmrs = ((gNB->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
+  nb_re_dmrs = ((gNB->pusch_config.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,

From 505d06e945856ad1e13e832957ae366dda7b1e86 Mon Sep 17 00:00:00 2001
From: adk 
Date: Thu, 13 Feb 2020 18:24:55 +0100
Subject: [PATCH 296/343] PUSCH PTRS generation

---
 cmake_targets/CMakeLists.txt                  |   2 +
 openair1/PHY/NR_REFSIG/ptrs_nr.c              | 429 ++++++++++++++++++
 openair1/PHY/NR_REFSIG/ptrs_nr.h              |  82 ++++
 .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h     |   2 +
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    |  74 ++-
 5 files changed, 583 insertions(+), 6 deletions(-)
 create mode 100644 openair1/PHY/NR_REFSIG/ptrs_nr.c
 create mode 100644 openair1/PHY/NR_REFSIG/ptrs_nr.h

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index c4d3d7e62e..6a0f6e1538 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1467,6 +1467,7 @@ set(PHY_SRC_UE
   ${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_REFSIG/ptrs_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
@@ -1513,6 +1514,7 @@ set(PHY_SRC_UE
   ${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/ptrs_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/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c
new file mode 100644
index 0000000000..9be37d2d95
--- /dev/null
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c
@@ -0,0 +1,429 @@
+/*
+ * 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
+ */
+
+/**********************************************************************
+*
+* FILENAME    :  ptrs_nr.c
+*
+* MODULE      :  phase tracking reference signals
+*
+* DESCRIPTION :  resource element mapping of ptrs sequences
+*                3GPP TS 38.211 and 3GPP TS 38.214
+*
+************************************************************************/
+
+#include 
+#include 
+#include "dmrs_nr.h"
+#include "PHY/NR_REFSIG/ptrs_nr.h"
+
+/***********************************************************************/
+
+
+ //#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+// TS 38.211 Table 6.4.1.2.2.1-1: The parameter kRE_ref.
+// The first 4 colomns are DM-RS Configuration type 1 and the last 4 colomns are DM-RS Configuration type 2.
+
+int16_t table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref [6][8] = {
+{ 0,            2,           6,          8,          0,          1,         6,         7},
+{ 2,            4,           8,         10,          1,          6,         7,         0},
+{ 1,            3,           7,          9,          2,          3,         8,         9},
+{ 3,            5,           9,         11,          3,          8,         9,         2},
+{-1,           -1,          -1,         -1,          4,          5,        10,        11},
+{-1,           -1,          -1,         -1,          5,         10,        11,         4},
+};
+
+
+/*******************************************************************
+*
+* NAME :         get_kRE_ref
+*
+* PARAMETERS :   dmrs_antenna_port      DMRS antenna port
+*                pusch_dmrs_type        PUSCH DMRS type
+*                resourceElementOffset  the parameter resourceElementOffset
+*
+* RETURN :       the parameter k_RE_ref
+*
+* DESCRIPTION :  3GPP TS 38.211 Table 6.4.1.2.2.1-1
+*
+*********************************************************************/
+
+int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t resourceElementOffset) {
+
+  uint8_t colomn;
+  int16_t k_RE_ref;
+
+  colomn = resourceElementOffset;
+
+  if (pusch_dmrs_type == 2)
+    colomn += 4;
+
+  k_RE_ref = table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref[dmrs_antenna_port][colomn];
+
+  AssertFatal(k_RE_ref>=0,"invalid k_RE_ref < 0. Check PTRS Configuration\n");
+
+  return k_RE_ref;
+}
+
+
+/*******************************************************************
+*
+* NAME :         get_K_ptrs
+*
+* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
+*                N_RB                   number of RBs scheduled for PUSCH
+*
+* RETURN :       the parameter K_ptrs
+*
+* DESCRIPTION :  3GPP TS 38.214 6.2.3 Table 6.2.3.1-2
+*
+*********************************************************************/
+
+uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
+
+	uint16_t nrb0, nrb1;
+
+	nrb0 = ptrs_UplinkConfig->frequencyDensity.n_rb0;
+	nrb1 = ptrs_UplinkConfig->frequencyDensity.n_rb1;
+
+	if (nrb0 == 0 || nrb0 == 0)
+		return 2;
+
+	if (N_RB < nrb0){
+		LOG_I(PHY,"PUSH PT-RS is not present.\n");
+		return 0;
+	}
+	else if (N_RB >= nrb0 && N_RB < nrb1)
+		return 2;
+	else
+		return 4;
+}
+
+/*******************************************************************
+*
+* NAME :         set_ptrs_symb_idx
+*
+* PARAMETERS :   ptrs_symbols           PTRS OFDM symbol indicies bit mask
+*                ptrs_UplinkConfig      PTRS uplink configuration
+*                dmrs_UplinkConfig      DMRS uplink configuration
+*                mapping_type           PUSCH time domain mapping type
+*                duration_in_symbols    number of scheduled PUSCH ofdm symbols
+*                start_symbol           first ofdm symbol of PUSCH within slot
+*                L_ptrs                 the parameter L_ptrs
+*                ofdm_symbol_size       FFT size
+*
+* RETURN :       sets the bit map of PTRS ofdm symbol indicies
+*
+* DESCRIPTION :  3GPP TS 38.211 6.4.1.2.2.1
+*
+*********************************************************************/
+
+void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
+                       ptrs_UplinkConfig_t *ptrs_UplinkConfig,
+                       dmrs_UplinkConfig_t *dmrs_UplinkConfig,
+                       uint8_t mapping_type,
+                       uint8_t duration_in_symbols,
+                       uint8_t start_symbol,
+                       uint8_t L_ptrs,
+                       uint16_t ofdm_symbol_size) {
+
+	uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2;
+	int16_t l_ref;
+
+	*ptrs_symbols = 0;
+	i = 0;
+	is_dmrs_symbol1 = 0;
+	is_dmrs_symbol2 = 0;
+	l_ref = start_symbol;
+	last_symbol = start_symbol + duration_in_symbols - 1;
+
+	while ( (l_ref + i*L_ptrs) <= last_symbol) {
+
+		is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref),
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         duration_in_symbols,
+                                         dmrs_UplinkConfig,
+                                         mapping_type,
+                                         ofdm_symbol_size);
+
+		is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         0,
+                                         duration_in_symbols,
+                                         dmrs_UplinkConfig,
+                                         mapping_type,
+                                         ofdm_symbol_size);
+
+		if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) {
+
+			if (dmrs_UplinkConfig->pusch_maxLength == 2)
+				l_ref = l_ref + i*L_ptrs + 1;
+			else
+				l_ref = l_ref + i*L_ptrs;
+
+			i = 1;
+
+			continue;
+
+		}
+
+		*ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs));
+		i++;
+	}
+}
+
+/*******************************************************************
+*
+* NAME :         get_L_ptrs
+*
+* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
+*                I_mcs                  MCS index used for PUSCH
+*
+* RETURN :       the parameter L_ptrs
+*
+* DESCRIPTION :  3GPP TS 38.214 6.2.3 Table 6.2.3.1-1
+*
+*********************************************************************/
+
+uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs) {
+
+	uint8_t mcs1, mcs2, mcs3;
+
+	mcs1 = ptrs_UplinkConfig->timeDensity.ptrs_mcs1;
+	mcs2 = ptrs_UplinkConfig->timeDensity.ptrs_mcs2;
+	mcs3 = ptrs_UplinkConfig->timeDensity.ptrs_mcs3;
+
+	if (mcs1 == 0 || mcs2 == 0 || mcs3 == 0)
+		return 1;
+
+	if (I_mcs < mcs1){
+		LOG_I(PHY,"PUSH PT-RS is not present.\n");
+		return 0;
+	}
+	else if (I_mcs >= mcs1 && I_mcs < mcs2)
+		return 4;
+	else if (I_mcs >= mcs2 && I_mcs < mcs3)
+		return 2;
+	else
+		return 1;
+}
+
+/*******************************************************************
+*
+* NAME :         is_ptrs_subcarrier
+*
+* PARAMETERS : k                      subcarrier index
+*              K_ptrs                 the parameter K_ptrs
+*              n_rnti                 UE CRNTI
+*              N_RB                   number of RBs scheduled for PUSCH
+*              k_RE_ref               the parameter k_RE_ref
+*              start_sc               first subcarrier index
+*              ofdm_symbol_size       FFT size
+*
+* RETURN :       1 if subcarrier k is PTRS, or 0 otherwise
+*
+* DESCRIPTION :  3GPP TS 38.211 6.4.1.2 Phase-tracking reference signal for PUSCH
+*
+*********************************************************************/
+
+uint8_t is_ptrs_subcarrier(uint16_t k, uint8_t K_ptrs, uint16_t n_rnti, uint16_t N_RB, int16_t k_RE_ref, uint16_t start_sc, uint16_t ofdm_symbol_size) {
+
+	uint16_t k_RB_ref, i, sc;
+
+	i = 0;
+	sc = 0;
+	k_RB_ref = 0;
+
+	if (N_RB % K_ptrs == 0)
+		k_RB_ref = n_rnti % K_ptrs;
+	else
+		k_RB_ref = n_rnti % (N_RB % K_ptrs);
+
+	while (k > sc){
+
+		sc = (start_sc + k_RE_ref + (i*K_ptrs + k_RB_ref)*NR_NB_SC_PER_RB)%ofdm_symbol_size;
+		i++;
+
+	}
+
+	if (k == sc)
+        return 1;
+	else
+        return 0;
+
+}
+
+/*******************************************************************
+*
+* NAME :         is_ptrs_symbol
+*
+* PARAMETERS : l                      ofdm symbol index within slot
+*              k                      subcarrier index
+*              n_rnti                 UE CRNTI
+*              N_RB                   number of RBs scheduled for PUSCH
+*              duration_in_symbols    number of scheduled PUSCH ofdm symbols
+*              dmrs_antenna_port      DMRS antenna port
+*              K_ptrs                 the parameter K_ptrs
+*              ptrs_symbols           bit mask of ptrs
+*              start_sc               first subcarrier index
+*              ofdm_symbol_size       FFT size
+*              pusch_dmrs_type        PUSCH DMRS type (1 or 2)
+*              ptrs_UplinkConfig      PTRS uplink configuration
+*
+* RETURN :       0 if symbol(k,l) is data, or 1 if symbol(k,l) is ptrs
+*
+* DESCRIPTION :  3GPP TS 38.211 6.4.1.2 Phase-tracking reference signal for PUSCH
+*
+*********************************************************************/
+
+uint8_t is_ptrs_symbol(uint8_t l,
+                       uint16_t k,
+                       uint16_t n_rnti,
+                       uint16_t N_RB,
+                       uint8_t duration_in_symbols,
+                       uint8_t dmrs_antenna_port,
+                       uint8_t K_ptrs,
+                       uint16_t ptrs_symbols,
+                       uint16_t start_sc,
+                       uint16_t ofdm_symbol_size,
+                       pusch_dmrs_type_t pusch_dmrs_type,
+                       ptrs_UplinkConfig_t *ptrs_UplinkConfig) {
+
+  uint8_t is_ptrs_freq, is_ptrs_time;
+  int16_t k_RE_ref;
+
+  is_ptrs_freq = 0;
+  is_ptrs_time = 0;
+
+  k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, ptrs_UplinkConfig->resourceElementOffset);
+
+  is_ptrs_freq = is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref, start_sc, ofdm_symbol_size);
+
+  if (is_ptrs_freq == 0)
+    return 0;
+
+  if (((ptrs_symbols>>l)&1) == 1)
+    is_ptrs_time = 1;
+
+  if (is_ptrs_time && is_ptrs_freq)
+    return 1;
+  else
+    return 0;
+
+}
+
+/*
+int main(int argc, char const *argv[])
+{
+
+	dmrs_UplinkConfig_t dmrs_Uplink_Config;
+	ptrs_UplinkConfig_t ptrs_Uplink_Config;
+	uint8_t resourceElementOffset;
+	uint8_t dmrs_antenna_port;
+	uint8_t L_ptrs, K_ptrs;
+	int16_t k_RE_ref;
+	uint16_t N_RB, ptrs_symbols, ofdm_symbol_size, k;
+	uint8_t duration_in_symbols, I_mcs;
+	uint8_t start_symbol, l;
+	uint8_t ptrs_symbol_flag;
+	uint16_t n_rnti;
+
+    dmrs_Uplink_Config.pusch_dmrs_type = pusch_dmrs_type1;
+    dmrs_Uplink_Config.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos1;
+    dmrs_Uplink_Config.pusch_maxLength = pusch_len2;
+
+    ptrs_Uplink_Config.timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
+    ptrs_Uplink_Config.timeDensity.ptrs_mcs2 = 0;
+    ptrs_Uplink_Config.timeDensity.ptrs_mcs3 = 0;
+    ptrs_Uplink_Config.frequencyDensity.n_rb0 = 0;     // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
+    ptrs_Uplink_Config.frequencyDensity.n_rb1 = 0;
+    ptrs_Uplink_Config.resourceElementOffset = 0;
+
+    n_rnti = 0x1234;
+    resourceElementOffset = 0;
+    ptrs_symbols = 0;
+	dmrs_antenna_port = 0;
+	N_RB = 50;
+	duration_in_symbols = 14;
+	ofdm_symbol_size = 2048;
+	I_mcs = 9;
+	start_symbol = 0;
+	ptrs_symbol_flag = 0;
+
+    k_RE_ref = get_kRE_ref(dmrs_antenna_port, dmrs_Uplink_Config.pusch_dmrs_type, resourceElementOffset);
+
+    K_ptrs = get_K_ptrs(&ptrs_Uplink_Config, N_RB);
+
+    L_ptrs = get_L_ptrs(&ptrs_Uplink_Config, I_mcs);
+
+    set_ptrs_symb_idx(&ptrs_symbols,
+                      &ptrs_Uplink_Config,
+                      &dmrs_Uplink_Config,
+                      1,
+                      duration_in_symbols,
+                      start_symbol,
+                      L_ptrs,
+                      ofdm_symbol_size);
+
+    printf("PTRS OFDM symbol indicies: ");
+
+    for (l = start_symbol; l < start_symbol + duration_in_symbols; l++){
+
+        ptrs_symbol_flag = is_ptrs_symbol(l,
+                                          0,
+                                          n_rnti,
+                                          N_RB,
+                                          duration_in_symbols,
+                                          dmrs_antenna_port,
+                                          K_ptrs,
+                                          ptrs_symbols,
+                                          dmrs_Uplink_Config.pusch_dmrs_type,
+                                          &ptrs_Uplink_Config);
+
+        if (ptrs_symbol_flag == 1)
+            printf(" %d ", l);
+
+    }
+
+    printf("\n");
+
+    printf("PTRS subcarrier indicies: ");
+
+    for (k = 0; k < N_RB*12; k++){
+
+        if (is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref) == 1)
+            printf(" %d ", k);
+
+    }
+
+    printf("\n");
+
+	return 0;
+}
+*/
\ No newline at end of file
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h
new file mode 100644
index 0000000000..f3b42fff30
--- /dev/null
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.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
+ */
+
+/**********************************************************************
+*
+* FILENAME    :  dmrs.h
+*
+* MODULE      :  demodulation reference signals
+*
+* DESCRIPTION :  generation of dmrs sequences for NR 5G
+*                3GPP TS 38.211
+*
+************************************************************************/
+
+#ifndef PTRS_NR_H
+#define PTRS_NR_H
+
+#include "PHY/defs_nr_UE.h"
+
+/************** CODE GENERATION ***********************************/
+
+/************** DEFINE ********************************************/
+
+
+/************* STRUCTURES *****************************************/
+
+
+/************** VARIABLES *****************************************/
+
+/************** FUNCTION ******************************************/
+
+int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t resourceElementOffset);
+
+uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB);
+
+void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
+                       ptrs_UplinkConfig_t *ptrs_UplinkConfig,
+                       dmrs_UplinkConfig_t *dmrs_UplinkConfig,
+                       uint8_t mapping_type,
+                       uint8_t duration_in_symbols,
+                       uint8_t start_symbol,
+                       uint8_t L_ptrs,
+                       uint16_t ofdm_symbol_size);
+
+uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs);
+
+uint8_t is_ptrs_subcarrier(uint16_t k, uint8_t K_ptrs, uint16_t n_rnti, uint16_t N_RB, int16_t k_RE_ref, uint16_t start_sc, uint16_t ofdm_symbol_size);
+
+uint8_t is_ptrs_symbol(uint8_t l,
+                       uint16_t k,
+                       uint16_t n_rnti,
+                       uint16_t N_RB,
+                       uint8_t duration_in_symbols,
+                       uint8_t dmrs_antenna_port,
+                       uint8_t K_ptrs,
+                       uint16_t ptrs_symbols,
+                       uint16_t start_sc,
+                       uint16_t ofdm_symbol_size,
+                       pusch_dmrs_type_t pusch_dmrs_type,
+                       ptrs_UplinkConfig_t *ptrs_UplinkConfig);
+
+
+
+#endif /* PTRS_NR_H */
\ No newline at end of file
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 39b037a600..a10b6231a0 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -240,6 +240,8 @@ typedef struct {
   int16_t Po_SRS;
   /// num active cba group
   uint8_t num_active_cba_groups;
+  /// bit mask of PT-RS ofdm symbol indicies
+  uint16_t ptrs_symbols;
   /// num dci found for cba
   //uint8_t num_cba_dci[10];
   /// allocated CBA RNTI
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index bdcbe3327a..3caaa6c99f 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -31,6 +31,7 @@
 */
 #include 
 #include "PHY/NR_REFSIG/dmrs_nr.h"
+#include "PHY/NR_REFSIG/ptrs_nr.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
 #include "PHY/MODULATION/nr_modulation.h"
@@ -105,19 +106,22 @@ 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], l_prime[2], delta;
-  uint16_t n_dmrs, code_rate, number_dmrs_symbols;
+  uint16_t n_dmrs, code_rate, number_dmrs_symbols, k;
   uint8_t dmrs_type;
   uint8_t mapping_type;
   int ap, start_symbol, Nid_cell, i;
   int sample_offsetF, N_RE_prime, N_PRB_oh;
   uint16_t n_rnti;
   uint8_t data_existing =0;
+  uint8_t L_ptrs, K_ptrs; // PTRS parameters
+  uint16_t beta_ptrs; // PTRS parameter related to power control
 
   NR_UE_ULSCH_t *ulsch_ue;
   NR_UL_UE_HARQ_t *harq_process_ul_ue;
   NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
   NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
   uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
+  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
 
   num_of_codewords = 1; // tmp assumption
   n_rnti = 0x1234;
@@ -281,6 +285,36 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   ///////////
   ////////////////////////////////////////////////////////////////////////
 
+
+  /////////////////////////PTRS parameters' initialization/////////////////////////
+  ///////////
+
+  int16_t mod_ptrs[(harq_process_ul_ue->nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation
+  K_ptrs = 0; // just to avoid a warning
+
+  if (UE->ptrs_configured == 1) {
+
+    K_ptrs = get_K_ptrs(ptrs_Uplink_Config, harq_process_ul_ue->nb_rb);
+
+    L_ptrs = get_L_ptrs(ptrs_Uplink_Config, harq_process_ul_ue->mcs);
+
+    beta_ptrs = 1; // temp value until power control is implemented
+
+    ulsch_ue->ptrs_symbols = 0;
+
+    set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols,
+                      ptrs_Uplink_Config,
+                      &UE->pusch_config.dmrs_UplinkConfig,
+                      1,
+                      harq_process_ul_ue->number_of_symbols,
+                      start_symbol,
+                      L_ptrs,
+                      frame_parms->ofdm_symbol_size);
+  }
+
+  ///////////
+  ////////////////////////////////////////////////////////////////////////////////
+
   /////////////////////////ULSCH layer mapping/////////////////////////
   ///////////
 
@@ -357,8 +391,8 @@ 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;
+    uint8_t is_dmrs, is_ptrs;
+    uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
 
     for (l=start_symbol; lnumber_of_symbols; l++) {
 
@@ -371,6 +405,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
         sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
 
         is_dmrs = 0;
+        is_ptrs = 0;
 
         is_dmrs = is_dmrs_symbol(l,
                                  k,
@@ -383,9 +418,26 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                  mapping_type,
                                  frame_parms->ofdm_symbol_size);
 
+        if (UE->ptrs_configured == 1){
+          is_ptrs = is_ptrs_symbol(l,
+                                   k,
+                                   ulsch_ue->rnti,
+                                   harq_process_ul_ue->nb_rb,
+                                   harq_process_ul_ue->number_of_symbols,
+                                   ap,
+                                   K_ptrs,
+                                   ulsch_ue->ptrs_symbols,
+                                   start_sc,
+                                   frame_parms->ofdm_symbol_size,
+                                   UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
+                                   ptrs_Uplink_Config);
+        }
+
         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
+          if (k == start_sc){
+            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;
@@ -401,9 +453,19 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
           k_prime++;
           k_prime&=1;
           n+=(k_prime)?0:1;
-        }
 
-        else {
+        }  else if (is_ptrs == 1) {
+
+          if (k == start_sc){
+            nr_modulation(pusch_dmrs[l][0], harq_process_ul_ue->nb_rb/2, DMRS_MOD_ORDER, mod_ptrs);
+          }
+
+          ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
+          ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15;
+
+          ptrs_idx++;
+
+          } else {
 
           ((int16_t*)txdataF[ap])[(sample_offsetF)<<1]       = ((int16_t *) ulsch_ue->y)[m<<1];
           ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];

From 00ff5e8a5cfe7fc8ee634a3af1cdc9daf82529be Mon Sep 17 00:00:00 2001
From: adk 
Date: Tue, 3 Mar 2020 11:33:07 +0100
Subject: [PATCH 297/343] PUSCH PTRS extraction and fixing nr_ulsim

---
 openair1/PHY/INIT/nr_init.c                   |  54 ++++----
 openair1/PHY/INIT/nr_init_ue.c                |   2 +-
 .../PHY/NR_TRANSPORT/nr_transport_proto.h     |  14 +-
 .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c  | 123 ++++++++++++++----
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    |   1 +
 openair1/PHY/defs_gNB.h                       |  14 ++
 openair1/SIMULATION/NR_PHY/ulsim.c            |   6 +-
 7 files changed, 153 insertions(+), 61 deletions(-)

diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index f10a7426dd..00fd616aa0 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -170,7 +170,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
   }
 
-  gNB->ptrs_configured = 0;
+  gNB->ptrs_configured = 1;
 
   //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------//
   ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
@@ -234,32 +234,36 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   for (int UE_id=0; UE_idrxdataF_ext           = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->rxdataF_ext2          = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_estimates       = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_estimates_ext   = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_estimates_time  = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->rxdataF_comp          = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_mag0             = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_magb0            = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_mag             = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_magb            = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->rho                   = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
+    pusch_vars[UE_id]->rxdataF_ext              = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->rxdataF_ext2             = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_estimates          = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_estimates_ext      = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_ptrs_estimates     = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_estimates_time     = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->rxdataF_comp             = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_mag0               = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_magb0              = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_mag                = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->ul_ch_magb               = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+    pusch_vars[UE_id]->rho                      = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
 
     for (i=0; inb_antennas_rx; i++) {
       // RK 2 times because of output format of FFT!
       // FIXME We should get rid of this
-      pusch_vars[UE_id]->rxdataF_ext[i]           = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->rxdataF_ext2[i]          = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_estimates[i]       = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_estimates_ext[i]   = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_estimates_time[i]  = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
-      pusch_vars[UE_id]->rxdataF_comp[i]          = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_mag0[i]             = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->ul_ch_magb0[i]            = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->ul_ch_mag[i]             = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->ul_ch_magb[i]            = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->rho[i]                   = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
+      pusch_vars[UE_id]->rxdataF_ext[i]                = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+      pusch_vars[UE_id]->rxdataF_ext2[i]               = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+      pusch_vars[UE_id]->ul_ch_estimates[i]            = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+      pusch_vars[UE_id]->ul_ch_estimates_ext[i]        = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+      pusch_vars[UE_id]->ul_ch_ptrs_estimates[i]       = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
+      pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i]   = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot );
+      pusch_vars[UE_id]->ul_ch_estimates_time[i]       = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
+      pusch_vars[UE_id]->rxdataF_comp[i]               = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+      pusch_vars[UE_id]->ul_ch_mag0[i]                 = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
+      pusch_vars[UE_id]->ul_ch_magb0[i]                = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
+      pusch_vars[UE_id]->ul_ch_mag[i]                  = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
+      pusch_vars[UE_id]->ul_ch_magb[i]                 = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
+      pusch_vars[UE_id]->rho[i]                        = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
     }
 
     pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear 
@@ -363,6 +367,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
       free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]);
       free_and_zero(pusch_vars[UE_id]->ul_ch_estimates[i]);
       free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext[i]);
+      free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates[i]);
+      free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i]);
       free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time[i]);
       free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]);
       free_and_zero(pusch_vars[UE_id]->ul_ch_mag0[i]);
@@ -376,6 +382,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
     free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
     free_and_zero(pusch_vars[UE_id]->ul_ch_estimates);
     free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext);
+    free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates);
+    free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext);
     free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time);
     free_and_zero(pusch_vars[UE_id]->rxdataF_comp);
     free_and_zero(pusch_vars[UE_id]->ul_ch_mag0);
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 7b7954583d..773d048942 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -748,7 +748,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   /////////////////////////PUSCH PTRS init/////////////////////////
   ///////////
 
-  ue->ptrs_configured = 0; // flag to be toggled by RCC
+  ue->ptrs_configured = 1; // flag to be toggled by RCC
 
   //------------- config PTRS parameters--------------//
   ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 4c8d8650e3..d3985bfd8b 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -65,20 +65,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
     @param is_dmrs_symbol, flag to indicate wether this OFDM symbol contains DMRS symbols or not.
 
 */
-void nr_ulsch_extract_rbs_single(int **rxdataF,
-                                 int **ul_ch_estimates,
-                                 int **rxdataF_ext,
-                                 int **ul_ch_estimates_ext,
-                                 uint32_t rxdataF_ext_offset,
-                                 // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
+void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
+                                 NR_gNB_PUSCH *pusch_vars,
                                  unsigned char symbol,
                                  unsigned short start_rb,
                                  unsigned short nb_rb_pusch,
+                                 uint16_t n_rnti,
                                  NR_DL_FRAME_PARMS *frame_parms,
-                                 uint8_t dmrs_symbol,
                                  uint16_t number_symbols,
                                  uint8_t mapping_type,
-                                 dmrs_UplinkConfig_t *dmrs_UplinkConfig);
+                                 uint8_t ptrs_configured,
+                                 dmrs_UplinkConfig_t *dmrs_UplinkConfig,
+                                 ptrs_UplinkConfig_t *ptrs_Uplink_Config);
 
 void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
                             NR_DL_FRAME_PARMS *frame_parms,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 1def3d5033..93cb721f36 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -4,6 +4,7 @@
 #include "PHY/impl_defs_top.h"
 #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
 #include "PHY/NR_REFSIG/dmrs_nr.h"
+#include "PHY/NR_REFSIG/ptrs_nr.h"
 #include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
 #include "PHY/defs_nr_common.h"
 
@@ -221,31 +222,32 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
 
 }
 
-void nr_ulsch_extract_rbs_single(int **rxdataF,
-                                 int **ul_ch_estimates,
-                                 int **rxdataF_ext,
-                                 int **ul_ch_estimates_ext,
-                                 uint32_t rxdataF_ext_offset,
-                                 // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
+void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
+                                 NR_gNB_PUSCH *pusch_vars,
                                  unsigned char symbol,
                                  unsigned short start_rb,
                                  unsigned short nb_rb_pusch,
+                                 uint16_t n_rnti,
                                  NR_DL_FRAME_PARMS *frame_parms,
-                                 uint8_t dmrs_symbol,
                                  uint16_t number_symbols,
                                  uint8_t mapping_type,
-                                 dmrs_UplinkConfig_t *dmrs_UplinkConfig)
+                                 uint8_t ptrs_configured,
+                                 dmrs_UplinkConfig_t *dmrs_UplinkConfig,
+                                 ptrs_UplinkConfig_t *ptrs_Uplink_Config)
 {
   unsigned short start_re, re, nb_re_pusch;
   unsigned char aarx;
+  uint8_t K_ptrs;
   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;
-
+  uint32_t ul_ch0_ptrs_ext_index = 0;
+  uint32_t ul_ch0_ptrs_index = 0;
+  uint8_t is_dmrs_symbol_flag, is_ptrs_symbol_flag,k_prime;
+  uint16_t n=0, num_ptrs_symbols;
   int16_t *rxF,*rxF_ext;
   int *ul_ch0,*ul_ch0_ext;
+  int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
 
 #ifdef DEBUG_RB_EXT
 
@@ -258,15 +260,23 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
   
   nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
   is_dmrs_symbol_flag = 0;
+  is_ptrs_symbol_flag = 0;
+  num_ptrs_symbols = 0;
+
+  K_ptrs = get_K_ptrs(ptrs_Uplink_Config, nb_rb_pusch);
 
   for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
     
     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
+    rxF_ext   = (int16_t *)&pusch_vars->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][dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
+    ul_ch0     = &pusch_vars->ul_ch_estimates[aarx][pusch_vars->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];
+    ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch];
+
+    ul_ch0_ptrs     = &pusch_vars->ul_ch_ptrs_estimates[aarx][pusch_vars->ptrs_symbol_index*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
+
+    ul_ch0_ptrs_ext = &pusch_vars->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch];
 
     n = 0;
     k_prime = 0;
@@ -283,15 +293,36 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
                                             dmrs_UplinkConfig,
                                             mapping_type,
                                             frame_parms->ofdm_symbol_size);
+
+      if (ptrs_configured == 1){
+        is_ptrs_symbol_flag = is_ptrs_symbol(symbol,
+                                             (start_re + re)%frame_parms->ofdm_symbol_size,
+                                             n_rnti,
+                                             nb_rb_pusch,
+                                             number_symbols,
+                                             aarx,
+                                             K_ptrs,
+                                             pusch_vars->ptrs_symbols,
+                                             start_re,
+                                             frame_parms->ofdm_symbol_size,
+                                             dmrs_UplinkConfig->pusch_dmrs_type,
+                                             ptrs_Uplink_Config);
+
+        if (is_ptrs_symbol_flag == 1)
+          num_ptrs_symbols++;
+
+      }
+
   #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 ) {
+      if ( is_dmrs_symbol_flag == 0 && is_ptrs_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_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
 
   #ifdef DEBUG_RB_EXT
         printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]);
@@ -299,6 +330,7 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
   #endif
 
         ul_ch0_ext_index++;
+        ul_ch0_ptrs_ext_index++;
         rxF_ext_index +=2;
       } else {
         k_prime++;
@@ -306,8 +338,12 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
         n+=(k_prime)?0:1;
       }
       ul_ch0_index++;
+      ul_ch0_ptrs_index++;
     }
   }
+
+  pusch_vars->ptrs_sc_per_ofdm_symbol = num_ptrs_symbols;
+
 }
 
 void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
@@ -1001,17 +1037,21 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                  unsigned char harq_pid)
 {
 
-  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;
+  uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
   uint32_t nb_re_pusch, bwp_start_subcarrier;
   uint8_t mapping_type;
+  uint8_t L_ptrs = 0; // PTRS parameter
   int avgs;
   int avg[4];
+  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;
+  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
 
   dmrs_symbol_flag = 0;
+  ptrs_symbol_flag = 0;
   first_symbol_flag = 0;
   mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
+  gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0;
 
   if (mapping_type == typeB) {
 
@@ -1019,6 +1059,20 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
       gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
       gNB->pusch_vars[UE_id]->dmrs_symbol = 0;
       first_symbol_flag = 1;
+
+      L_ptrs = get_L_ptrs(ptrs_Uplink_Config, rel15_ul->mcs);
+
+      gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
+
+      set_ptrs_symb_idx(&gNB->pusch_vars[UE_id]->ptrs_symbols,
+                        ptrs_Uplink_Config,
+                        &gNB->pusch_config.dmrs_UplinkConfig,
+                        1,
+                        rel15_ul->number_symbols,
+                        rel15_ul->start_symbol,
+                        L_ptrs,
+                        frame_parms->ofdm_symbol_size);
+
     }
 
     bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
@@ -1041,6 +1095,25 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
         nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
     }
 
+    if (gNB->ptrs_configured == 1)
+        ptrs_symbol_flag = is_ptrs_symbol(symbol,
+                                          0,
+                                          gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti,
+                                          rel15_ul->number_rbs,
+                                          rel15_ul->number_symbols,
+                                          0,
+                                          get_K_ptrs(ptrs_Uplink_Config, rel15_ul->number_rbs),
+                                          gNB->pusch_vars[UE_id]->ptrs_symbols,
+                                          0,
+                                          frame_parms->ofdm_symbol_size,
+                                          gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
+                                          ptrs_Uplink_Config);
+
+
+    if (ptrs_symbol_flag == 1){
+      gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
+    }
+
 
     //----------------------------------------------------------
     //--------------------- Channel estimation ---------------------
@@ -1061,19 +1134,17 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
     //----------------------------------------------------------
 
     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
+                                gNB->pusch_vars[UE_id],
                                 symbol,
                                 rel15_ul->start_rb,
                                 rel15_ul->number_rbs,
+                                gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti,
                                 frame_parms,
-                                gNB->pusch_vars[UE_id]->dmrs_symbol,
                                 rel15_ul->number_symbols,
                                 mapping_type,
-                                &gNB->pusch_config.dmrs_UplinkConfig);
+                                gNB->ptrs_configured,
+                                &gNB->pusch_config.dmrs_UplinkConfig,
+                                ptrs_Uplink_Config);
 
     nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
                            frame_parms,
@@ -1131,7 +1202,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                          symbol,
                          rel15_ul->Qm);
 
-    gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset +  nb_re_pusch;
+    gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset +  nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
   } else {
     LOG_E(PHY, "PUSCH mapping type A is not supported \n");
   }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 3caaa6c99f..26800ed584 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -546,6 +546,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
            frame_parms);
       }
     }
+
   ///////////
   ////////////////////////////////////////////////////
   return 0;
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 91a50d7361..3bca1138c0 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -375,6 +375,14 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
   int32_t **ul_ch_estimates_ext;
+  /// \brief Hold the PTRS phase estimates in frequency domain.
+  /// - first index: rx antenna id [0..nb_antennas_rx[
+  /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_ptrs_estimates;
+  /// \brief Uplink phase estimates extracted in PRBS.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_ptrs_estimates_ext;
   /// \brief Holds the compensated signal.
   /// - first index: rx antenna id [0..nb_antennas_rx[
   /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
@@ -416,6 +424,12 @@ typedef struct {
   int16_t *llr;
   // DMRS symbol index, to be updated every DMRS symbol within a slot.
   uint8_t dmrs_symbol;
+  // PTRS symbol index, to be updated every PTRS symbol within a slot.
+  uint8_t ptrs_symbol_index;
+  /// bit mask of PT-RS ofdm symbol indicies
+  uint16_t ptrs_symbols;
+  // PTRS subcarriers per OFDM symbol
+  uint16_t ptrs_sc_per_ofdm_symbol;
 } NR_gNB_PUSCH;
 
 
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index adfb09ea6e..36603c2ec0 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -428,7 +428,7 @@ int main(int argc, char **argv)
   uint16_t number_dmrs_symbols = 0;
   unsigned int available_bits;
   uint8_t nb_re_dmrs;
-  uint8_t length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength;
+  uint8_t length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength;
   unsigned char mod_order;
   uint16_t code_rate;
 
@@ -440,12 +440,12 @@ int main(int argc, char **argv)
                                             0,
                                             0,
                                             nb_symb_sch,
-                                            &UE->dmrs_UplinkConfig,
+                                            &UE->pusch_config.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;
+  nb_re_dmrs     = ((UE->pusch_config.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);

From f2bc346ab7d8a734bbbd7be6c17bb16dfc71a182 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Thu, 5 Mar 2020 10:14:46 +0100
Subject: [PATCH 298/343] Fixed bad array length for thread ID

---
 openair1/PHY/defs_nr_UE.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 4774bd4402..126e617202 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -898,7 +898,7 @@ typedef struct {
   //fapi_nr_dci_indication_t dci_ind;
 
   // point to the current rxTx thread index
-  uint8_t current_thread_id[40];
+  uint8_t current_thread_id[NR_MAX_SLOTS_PER_FRAME];
 
   t_nrPolar_params *polarList;
   NR_UE_PDSCH     *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads

From 8fbdfa39ec6051b29f65ee8a5beb273bd4a7e84f Mon Sep 17 00:00:00 2001
From: Thomas Schlichter 
Date: Thu, 5 Mar 2020 10:27:35 +0100
Subject: [PATCH 299/343] disable PUSCH PTRS for now

As adding PTRS leads to shortening of the coded data, redudandency is removed and the performance decreases on a pure AWGN channel.
So PTRS should only be enabled if phase noise is present.
---
 openair1/PHY/INIT/nr_init.c    | 2 +-
 openair1/PHY/INIT/nr_init_ue.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 00fd616aa0..bf8f857a04 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -170,7 +170,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
   }
 
-  gNB->ptrs_configured = 1;
+  gNB->ptrs_configured = 0;
 
   //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------//
   ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 773d048942..7b7954583d 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -748,7 +748,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   /////////////////////////PUSCH PTRS init/////////////////////////
   ///////////
 
-  ue->ptrs_configured = 1; // flag to be toggled by RCC
+  ue->ptrs_configured = 0; // flag to be toggled by RCC
 
   //------------- config PTRS parameters--------------//
   ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration

From 5f851d45b32b91b68412338503dc4aa52fb26b91 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Wed, 4 Mar 2020 15:45:16 +0100
Subject: [PATCH 300/343] Fill UE RX Indication Rel9 to prevent error message

---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 4b331c1cb0..bff50310b4 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -71,6 +71,8 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND
 	  //pdu->rx_indication_rel8.length         = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
 	  pdu->rx_indication_rel8.length         = buflen;
 	  pdu->rx_indication_rel8.offset         = 1;   // DJP - I dont understand - but broken unless 1 ????  0;  // filled in at the end of the UL_INFO formation
+	  pdu->rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG;
+	  pdu->rx_indication_rel9.timing_advance_r9 = 0;
 
 	  // ulsch_buffer is necessary to keep its value.
 	  //pdu->data                              = ulsch_buffer;

From c321f9b5a351d2c4c8073a3136d3a74cb3418cba Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 10:18:03 +0100
Subject: [PATCH 301/343] Make UE mem alloc for UL_INFO only once in PHY stub
 mode

---
 targets/RT/USER/lte-ue.c | 67 +++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 38 deletions(-)

diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 5a8afc2358..940d65282d 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -992,6 +992,19 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
   phy_stub_ticking->num_single_thread[ue_thread_id] = -1;
   UE = rtd->UE;
 
+  UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t));
+  UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_rx_indication_pdu_t));
+  UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
+  UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_crc_indication_pdu_t));
+  UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
+  UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_harq_indication_pdu_t));
+  UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0;
+  UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_sr_indication_pdu_t));
+  UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
+  UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list =  calloc(NB_UE_INST, sizeof(nfapi_cqi_indication_pdu_t));
+  UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = calloc(NB_UE_INST, sizeof(nfapi_cqi_indication_raw_pdu_t));
+  UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0;
+
   if(ue_thread_id == 0) {
     phy_stub_ticking->ticking_var = -1;
     proc->subframe_rx=proc->sub_frame_start;
@@ -1064,20 +1077,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
         initRefTimes(t3);
         pickTime(current);
         updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/
-      // Not sure whether we should put the memory allocation here and not sure how much memory
-      //we should allocate for each subframe cycle.
-      UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t));
-      UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t));
-      UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
-      UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t));
-      UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
-      UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t));
-      UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0;
-      UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t));
-      UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
-      UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list =  (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t));
-      UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t));
-      UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0;
 
       if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
         LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
@@ -1267,30 +1266,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
         UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
       }
 
-      // Free UL_INFO messages
-      //if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){
-      free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list);
-      UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL;
-      //}
-      //if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){
-      free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list);
-      UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL;
-      //}
-      //if(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list !=NULL){
-      free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list);
-      UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL;
-      //}
-      //if(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list!=NULL){
-      free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list);
-      UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL;
-      //}
-      free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list);
-      UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL;
-      free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list);
-      UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL;
-      free(UL_INFO);
-      UL_INFO = NULL;
-
       // De-allocate memory of nfapi requests copies before next subframe round
       if(dl_config_req!=NULL) {
         if(dl_config_req->vendor_extension!=NULL) {
@@ -1334,6 +1309,22 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
     }
   }
 
+  // Free UL_INFO messages
+  free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list);
+  UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL;
+  free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list);
+  UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL;
+  free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list);
+  UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL;
+  free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list);
+  UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL;
+  free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list);
+  UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL;
+  free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list);
+  UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL;
+  free(UL_INFO);
+  UL_INFO = NULL;
+
   // thread finished
   free(arg);
   return &UE_thread_rxtx_retval;

From 15a2767562fc6e3eba71c2776e67c6cd497636f6 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 11:39:38 +0100
Subject: [PATCH 302/343] Don't call fill_ulsch_cqi_indication_UE_MAC()

This functions fills the ULSCH CQI indication message incorrectly. Also,
it should only be triggered when the eNB requests CSI. We disable it
here and a subsequent commit enables it again.
---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index bff50310b4..6ba238aa75 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -489,7 +489,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
 		  }
 	  }
-	  fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
+	  //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
@@ -519,7 +519,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
 	  if(ulsch_harq_information!=NULL)
 		  fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
-	  fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
+	  //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {

From 8af8836c4beb8db31a57c8cdfbe0de859acb1c8c Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Wed, 4 Mar 2020 18:21:46 +0100
Subject: [PATCH 303/343] Call oai_nfapi_cqi_indication() to send
 cqi_indications

---
 targets/RT/USER/lte-ue.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 940d65282d..0b2f14d384 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -88,7 +88,7 @@ extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
 extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
                                  unsigned char _multicast_group, char *multicast_ifname);
 extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
-extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
+extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
 extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
 extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind);
 extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
@@ -1252,6 +1252,11 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
         UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
       }
 
+      if (UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis > 0) {
+        oai_nfapi_cqi_indication(&UL_INFO->cqi_ind);
+        UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0;
+      }
+
       if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) {
         //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
         oai_nfapi_harq_indication(&UL_INFO->harq_ind);

From b34a0e2f54e382a8e3f4fee776ffe325af4e782d Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 10:18:32 +0100
Subject: [PATCH 304/343] Increase (fixed) PHR for UE phy stub mode (L2 sim)

---
 openair2/LAYER2/MAC/ue_procedures.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 8518cba14c..1205851915 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -2158,7 +2158,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
   if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
     if(NFAPI_MODE==NFAPI_UE_STUB_PNF) {
       //Substitute with a static value for the MAC layer abstraction (phy_stub mode)
-      phr_p->PH = 40;
+      phr_p->PH = 60;
     } else {
       phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index);
     }

From c85d0878c1e128c4556cd00758fd6eac965328e6 Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Fri, 6 Mar 2020 13:40:03 +0100
Subject: [PATCH 305/343] Reverting the changes made in fo calculation While
 fixing bug in PSS index calculation in
 334519d16a9da34118c5568859eab6f68ae93ca9, I made changes in FO calculation as
 well. This is not nedeed and caused the FO to misbehave. Hence, reverting it.

---
 openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 070d01b5a3..09358e615c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -914,13 +914,13 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
 	  int64_t result1,result2;
 	  // Computing cross-correlation at peak on half the symbol size for first half of data
 	  result1  = dot_product64((short*)primary_synchro_time_nr[pss_source], 
-				  (short*) &(rxdata[0][peak_position+is*frame_parms->samples_per_frame]), 
+				  (short*) &(rxdata[0][peak_position])+(is*frame_parms->samples_per_frame), 
 				  frame_parms->ofdm_symbol_size>>1, 
 				  shift);
 	  // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size 
 	  // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
 	  result2  = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size), 
-				  (short*) &(rxdata[0][peak_position+frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)]), 
+				  (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)), 
 				  frame_parms->ofdm_symbol_size>>1, 
 				  shift);
 

From fcb211b014c0181c485e3d9591b4c78b2e445856 Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Fri, 6 Mar 2020 17:15:28 +0100
Subject: [PATCH 306/343] Fixing FO compensation in UE Actually there was a bug
 in FO compensation which I overlooked in last commit.

---
 openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 09358e615c..e8eceb77a6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -914,13 +914,13 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
 	  int64_t result1,result2;
 	  // Computing cross-correlation at peak on half the symbol size for first half of data
 	  result1  = dot_product64((short*)primary_synchro_time_nr[pss_source], 
-				  (short*) &(rxdata[0][peak_position])+(is*frame_parms->samples_per_frame), 
+				  (short*) &(rxdata[0][peak_position+is*frame_parms->samples_per_frame]), 
 				  frame_parms->ofdm_symbol_size>>1, 
 				  shift);
 	  // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size 
 	  // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
 	  result2  = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size), 
-				  (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)), 
+				  (short*) &(rxdata[0][peak_position+is*frame_parms->samples_per_frame])+frame_parms->ofdm_symbol_size, 
 				  frame_parms->ofdm_symbol_size>>1, 
 				  shift);
 

From 943f907ae1d3dc66b271c540fadf068413d6a429 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 16:02:52 +0100
Subject: [PATCH 307/343] Send correct ULSCH CQI indication message in L2 sim

---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 29 ++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 6ba238aa75..9aa3400a33 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -241,27 +241,32 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram
 	nfapi_cqi_indication_pdu_t *pdu         = &UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
 	nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
 
+	UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe;
+        // because of nfapi_vnf.c:733, set message id to 0, not NFAPI_RX_CQI_INDICATION;
+	UL_INFO->cqi_ind.header.message_id = 0;
+	UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG;
+
 	pdu->rx_ue_information.tl.tag          = NFAPI_RX_UE_INFORMATION_TAG;
 	pdu->rx_ue_information.rnti = rnti;
 	// Since we assume that CRC flag is always 0 (ACK) I guess that data_offset should always be 0.
-	pdu->cqi_indication_rel9.data_offset = 0;
+	pdu->cqi_indication_rel8.data_offset = 0;
 
 	// by default set O to rank 1 value
-	//pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0);
+	//pdu->cqi_indication_rel8.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0);
 	//  Not useful field for our case
-	pdu->cqi_indication_rel9.tl.tag = NFAPI_CQI_INDICATION_REL9_TAG;
-	pdu->cqi_indication_rel9.length = 0;
-	pdu->cqi_indication_rel9.ri[0]  = 0;
+	pdu->cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG;
+	pdu->cqi_indication_rel8.length = 1;
+	pdu->cqi_indication_rel8.ri  = 0;
 
 
-	pdu->cqi_indication_rel9.timing_advance = 0;
-  pdu->cqi_indication_rel9.number_of_cc_reported = 1;
-  pdu->ul_cqi_information.channel = 1; // PUSCH
+	pdu->cqi_indication_rel8.timing_advance = 0;
+	//pdu->cqi_indication_rel8.number_of_cc_reported = 1;
+	pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
+	pdu->ul_cqi_information.channel = 1; // PUSCH
 
-  // Not sure how to substitute this. This should be the actual CQI value? So can
-  // we hardcode it to a specific value?
-  //memcpy((void*)raw_pdu->pdu,ulsch_harq->o,pdu->cqi_indication_rel9.length);
-  raw_pdu->pdu[0] = 7;
+	// eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI
+	const int cqi = 15;
+	raw_pdu->pdu[0] = cqi << 4;
 
 
 

From 6866be7175ca86af7ab229c695ec475730589cca Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 15:28:36 +0100
Subject: [PATCH 308/343] Trigger ULSCH CQI ind only when instructed

---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 9aa3400a33..9357e354d4 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -494,8 +494,6 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
 		  }
 	  }
-	  //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
-
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
 
@@ -524,8 +522,6 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
 
 	  if(ulsch_harq_information!=NULL)
 		  fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
-	  //fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
-
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
 
@@ -812,8 +808,18 @@ int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id)
 
     if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE)
     {
-      LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE not used \n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
-
+      LOG_D(PHY,
+            "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - "
+            "NFAPI_HI_DCI0_DCI_PDU_TYPE\n",
+            NFAPI_SFNSF2DEC(req->sfn_sf),
+            i);
+      const nfapi_hi_dci0_dci_pdu_rel8_t *dci = &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8;
+      if (dci->rnti != UE_mac_inst[Mod_id].crnti)
+        continue;
+      const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
+      const int sf = NFAPI_SFNSF2SF(req->sfn_sf);
+      if (dci->cqi_csi_request)
+        fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti);
     }
     else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE)
     {

From 6ec6c8b261f99427724c0c428502638daeea6fbf Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 16:02:22 +0100
Subject: [PATCH 309/343] Request CQI in all NFAPI modes (i.e., also for L2
 sim)

---
 openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 49 ++++++++++-------------
 1 file changed, 22 insertions(+), 27 deletions(-)

diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index d240e35a87..7c3b536de2 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -1496,38 +1496,33 @@ schedule_ulsch_rnti(module_id_t   module_idP,
 
           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);
+              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) {
-                    case 1:
-                      if(subframeP == 1 || subframeP == 6) {
-                        cqi_req=0;
-                      }
+              /* 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) {
+                  case 1:
+                    if (subframeP == 1 || subframeP == 6)
+                      cqi_req = 0;
+                    break;
 
-                      break;
+                  case 3:
+                    if (subframeP == 1)
+                      cqi_req = 0;
+                    break;
 
-                    case 3:
-                      if(subframeP == 1) {
-                        cqi_req=0;
-                      }
-
-                      break;
-
-                    default:
-                      LOG_E(MAC," TDD config not supported\n");
-                      break;
-                  }
+                  default:
+                    LOG_E(MAC, " TDD config not supported\n");
+                    break;
                 }
+              }
 
-                if(cqi_req == 1) {
-                  UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP;
-                }
+              if (cqi_req == 1) {
+                UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP;
               }
             } else {
               LOG_D(MAC,"Clearing CQI request timer\n");

From 719667895c58bb691599707df0676f18d32c6a6a Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 18:24:49 +0100
Subject: [PATCH 310/343] Prevent memory leak in L2 sim due to NFAPI

---
 targets/RT/USER/lte-ue.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 0b2f14d384..75ed018434 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -1288,6 +1288,13 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
       }
 
       if(tx_request_pdu_list!=NULL) {
+        for (int i = 0; i < tx_req_num_elems; i++) {
+          for (int j = 0; j < tx_request_pdu_list[i].num_segments; j++) {
+            free(tx_request_pdu_list[i].segments[j].segment_data);
+            tx_request_pdu_list[i].segments[j].segment_data = NULL;
+          }
+        }
+        tx_req_num_elems = 0;
         free(tx_request_pdu_list);
         tx_request_pdu_list = NULL;
       }

From 34e7952944542212e0f2043afc2889a45d3a0eb9 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Thu, 5 Mar 2020 18:49:08 +0100
Subject: [PATCH 311/343] CI: Multi. UEs handled by 1 thread (no races) in
 l2sim

---
 ci-scripts/runTestOnVM.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index d46ed07bbb..4e1734da63 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -870,9 +870,9 @@ function start_l2_sim_ue {
     echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
     if [ $LOC_S1_CONFIGURATION -eq 0 ]
     then
-        echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread $LOC_NB_UES --nokrnmod 1 --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1
+        echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread 1 --nokrnmod 1 --log_config.global_log_options level,nocolor --noS1\" > ./my-lte-softmodem-run.sh " >> $1
     else
-        echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread $LOC_NB_UES --nokrnmod 1 --log_config.global_log_options level,nocolor\" > ./my-lte-softmodem-run.sh " >> $1
+        echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread 1 --nokrnmod 1 --log_config.global_log_options level,nocolor\" > ./my-lte-softmodem-run.sh " >> $1
     fi
     echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1
     echo "cat ./my-lte-softmodem-run.sh" >> $1

From fa7ace4b1d69ef904875246c649dae29ef1c63b3 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Fri, 6 Mar 2020 19:40:38 +0100
Subject: [PATCH 312/343] Reimplement dl_config_req_UE_MAC() more concisely

---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 256 ++++++++++++---------------
 1 file changed, 118 insertions(+), 138 deletions(-)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 9357e354d4..075ea30d00 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -644,154 +644,134 @@ int tx_req_UE_MAC(nfapi_tx_request_t* req)
 }
 
 
-int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, nfapi_tx_request_pdu_t* tx_request_pdu_list)
-{
-	//if (req!=NULL && tx_request_pdu_list!=NULL){
+int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) {
   int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
-  //Mod_id = 0; // Currently static (only for one UE) but this should change.
 
-  /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;*/
   nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
-  nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp;
 
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d sfn_sf:%d DCI:%d PDU:%d\n", __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2DEC(req->sfn_sf), req->dl_config_request_body.number_dci, req->dl_config_request_body.number_pdu);
+  for (int i = 0; i < req->dl_config_request_body.number_pdu; i++) {
+    if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) {
+      const rnti_t rnti = dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti;
+      const int rnti_type = dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type;
+      /* We assume the DCI DL PDU is followed by the DLSCH (the standard is
+       * more free), so advance by one more and directly process the
+       * following DLSCH PDU */
+      i++;
+      AssertFatal(i < req->dl_config_request_body.number_pdu,
+                  "Need PDU following DCI at index %d, but not found\n",
+                  i);
+      nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp = &dl_config_pdu_list[i];
+      if (dl_config_pdu_tmp->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
+        LOG_E(MAC, "expected DLSCH PDU at index %d\n", i);
+        continue;
+      }
+      if (rnti != dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) {
+        LOG_I(MAC,
+              "%s(): sfn/sf %d DLSCH PDU RNTI %x does not match DCI RNTI %x\n",
+              __func__,
+              NFAPI_SFNSF2DEC(req->sfn_sf),
+              rnti,
+              dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti);
+        continue;
+      }
+      const int pdu_index = dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index;
+      if (pdu_index < 0 && pdu_index >= tx_req_num_elems) {
+        LOG_E(MAC,
+              "dl_config_req_UE_MAC 2: Problem with receiving data: "
+              "sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n",
+              NFAPI_SFNSF2DEC(req->sfn_sf),
+              i,
+              dl_config_pdu_list[i].pdu_size,
+              dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
+        continue;
+      }
+      if (rnti_type == 1) {
+        // C-RNTI (Normal DLSCH case)
+        if (UE_mac_inst[Mod_id].crnti != rnti) {
+          LOG_D(MAC,
+                "sfn/sf %d/%d DCI not for UE %d/RNTI %x but for RNTI %x, "
+                "skipping\n",
+                sfn, sf, Mod_id, UE_mac_inst[Mod_id].crnti, rnti);
+          continue;
+        }
 
+        LOG_D(MAC,
+              "%s() Received data: sfn/sf:%d PDU[%d] "
+              "size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n",
+              __func__,
+              NFAPI_SFNSF2DEC(req->sfn_sf),
+              i,
+              dl_config_pdu_list[i].pdu_size,
+              dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index,
+              tx_req_num_elems);
+        ue_send_sdu(Mod_id, 0, sfn, sf,
+            tx_request_pdu_list[pdu_index].segments[0].segment_data,
+            tx_request_pdu_list[pdu_index].segments[0].segment_length,
+            0);
+      } else if (rnti_type == 2) {
+        if (rnti == 0xFFFF) { /* SI-RNTI */
+          if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED) {
+            /* this check is in the code before refactoring, but I don't know
+             * why. Leave it in here for the moment */
+            continue;
+          }
 
-
-  //LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%d%d dl_pdu:%d tx_req:%d hi_dci0:%d ul_cfg:%d num_pdcch_symbols:%d\n",
-  //	frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu, eNB->pdcch_vars[subframe&1].num_pdcch_symbols);
-
-  for (int i=0;idl_config_request_body.number_pdu;i++)
-  {
-    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size);
-	  //LOG_E(MAC, "dl_config_req_UE_MAC 2 Received real ones: sfn/sf:%d.%d PDU[%d] size:%d\n", sfn, sf, i, dl_config_pdu_list[i].pdu_size);
-
-    if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)
-    {
-		if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1) {
-			// C-RNTI (Normal DLSCH case)
-			dl_config_pdu_tmp = &dl_config_pdu_list[i+1];
-			if (dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && UE_mac_inst[Mod_id].crnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti){
-
-				/*nfapi_tx_request_pdu_t *ptr = tx_request_pdu_list;
-				ptr += dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index*(sizeof(nfapi_tx_request_pdu_t));
-				nfapi_tx_request_pdu_t temp;
-				memset(&temp, 0, sizeof(nfapi_tx_request_pdu_t));
-				//if (!memcmp(&temp, ptr, sizeof(temp)) ...
-				if( *(char*)ptr != 0){
-				//if(tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data!= NULL && tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length >0){
-				*/
-
-				// to avoid unexpected error , add check pdu_index is more than 0.
-				if((dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index >= 0) &&(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)){
-				//if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
-
-					LOG_I(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems);
-
-					ue_send_sdu(Mod_id, 0, sfn, sf,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length,
-							0);
-					i++;
-				}
-				else{
-					LOG_E(MAC,"dl_config_req_UE_MAC 2: Problem with receiving data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
-					i++;
-				}
-			}
-			else {
-				LOG_W(MAC,"[UE %d] Frame %d, subframe %d : DLSCH PDU from NFAPI not for this UE \n",Mod_id, sfn,sf);
-				i++;
-			}
-		}
-		else if (dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 2) {
-			dl_config_pdu_tmp = &dl_config_pdu_list[i+1];
-			if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFF && UE_mac_inst[Mod_id].UE_mode[0] != NOT_SYNCHED){ //&& UE_mac_inst[Mod_id].UE_mode[0] != NOT_SYNCHED
-
-				if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){
-				//if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
-					ue_decode_si(Mod_id, 0, sfn, 0,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length);
-					i++;
-				}
-				else{
-					LOG_E(MAC,"dl_config_req_UE_MAC 3: Problem with receiving SI: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
-					i++;
-				}
-			}
-			else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti == 0xFFFE){
-				// P_RNTI case
-				//pdu = Tx_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data;
-
-				if (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){
-				//if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){
-					ue_decode_p(Mod_id, 0, sfn, 0,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length);
-					i++;
-				}
-				else{
-					LOG_E(MAC,"dl_config_req_UE_MAC: Problem with receiving Paging: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
-					i++;
-				}
-			}
-			else if(dl_config_pdu_tmp->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
-				// RA-RNTI case
-				LOG_E(MAC,"dl_config_req_UE_MAC 4 Received RAR? \n");
-				// RNTI parameter not actually used. Provided only to comply with existing function definition.
-				// Not sure about parameters to fill the preamble index.
-				//rnti_t c_rnti = UE_mac_inst[Mod_id].crnti;
-				rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI;
-				if ((UE_mac_inst[Mod_id].UE_mode[0] != PUSCH) &&
-				  (UE_mac_inst[Mod_id].RA_prach_resources.Msg3!=NULL) && (ra_rnti== dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) &&
-				  //(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL)) {
-				  (dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)) {
-					LOG_E(MAC,"dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n", UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex);
-					ue_process_rar(Mod_id, 0, sfn,
-							ra_rnti, //RA-RNTI
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
-							&dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //t-crnti
-							UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex,
-							tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data);
-					UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
-					UE_mac_inst[Mod_id].first_ULSCH_Tx = 1; //Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first ULSCH Txon for the UE)
-				}
-				i++;
-			}
-			else {
-				LOG_E(MAC,"[UE %d] Frame %d, subframe %d : Cannot extract DLSCH PDU from NFAPI 2\n",Mod_id, sfn, sf);
-				i++;
-			}
-
-		}
-    }
-    else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE)
-    {
-    	// BCH case
-    	// Last parameter is 1 if first time synchronization and zero otherwise. Not sure which value to put
-    	// for our case.
-    	//LOG_E(MAC,"dl_config_req_UE_MAC 4 Received MIB: sfn/sf: %d.%d \n", sfn, sf);
-    	if(UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){
-    		dl_phy_sync_success(Mod_id,sfn,0, 1);
-    		LOG_E(MAC,"dl_config_req_UE_MAC 5 Received MIB: UE_mode: %d, sfn/sf: %d.%d\n", UE_mac_inst[Mod_id].UE_mode[0], sfn, sf);
-    		UE_mac_inst[Mod_id].UE_mode[0]=PRACH;
-    	}
-    	else
-    		dl_phy_sync_success(Mod_id,sfn,0, 0);
-
-    }
-
-    else
-    {
-      //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_config_pdu_list[i].pdu_type);
+          ue_decode_si(Mod_id, 0, sfn, 0,
+              tx_request_pdu_list[pdu_index].segments[0].segment_data,
+              tx_request_pdu_list[pdu_index].segments[0].segment_length);
+        } else if (rnti == 0xFFFE) { /* PI-RNTI */
+          LOG_I(MAC, "%s() Received paging message: sfn/sf:%d PDU[%d]\n",
+                __func__, NFAPI_SFNSF2DEC(req->sfn_sf), i);
+          ue_decode_p(Mod_id, 0, sfn, 0,
+                      tx_request_pdu_list[pdu_index].segments[0].segment_data,
+                      tx_request_pdu_list[pdu_index].segments[0].segment_length);
+        } else if (rnti == 0x0002) { /* RA-RNTI */
+          LOG_E(MAC, "%s(): Received RAR?\n", __func__);
+          // RNTI parameter not actually used. Provided only to comply with
+          // existing function definition.  Not sure about parameters to fill
+          // the preamble index.
+          const rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI;
+          DevAssert(ra_rnti == 0x0002);
+          if (UE_mac_inst[Mod_id].UE_mode[0] != PUSCH
+              && UE_mac_inst[Mod_id].RA_prach_resources.Msg3 != NULL
+              && ra_rnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) {
+            LOG_E(MAC,
+                  "dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n",
+                  UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex);
+            ue_process_rar(Mod_id, 0, sfn,
+                ra_rnti, //RA-RNTI
+                tx_request_pdu_list[pdu_index].segments[0].segment_data,
+                &dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //t-crnti
+                UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex,
+                tx_request_pdu_list[pdu_index].segments[0].segment_data);
+            UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
+            // Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first
+            // ULSCH Txon for the UE)
+            UE_mac_inst[Mod_id].first_ULSCH_Tx = 1;
+          }
+        } else {
+          LOG_W(MAC, "can not handle special RNTI %x\n", rnti);
+        }
+      }
+    } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) {
+      // BCH case: Last parameter is 1 if first time synchronization and zero
+      // otherwise.  Not sure which value to put for our case.
+      if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){
+        dl_phy_sync_success(Mod_id, sfn, 0, 1);
+        LOG_E(MAC,
+              "%s(): Received MIB: UE_mode: %d, sfn/sf: %d.%d\n",
+              __func__,
+              UE_mac_inst[Mod_id].UE_mode[0],
+              sfn,
+              sf);
+        UE_mac_inst[Mod_id].UE_mode[0] = PRACH;
+      } else {
+        dl_phy_sync_success(Mod_id, sfn, 0, 0);
+      }
     }
   }
-
   return 0;
-
 }
 
 

From 84482489e4b393f4442747c2b766fe87c2bed761 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Sun, 8 Mar 2020 18:22:53 +0100
Subject: [PATCH 313/343] Reformat phy_stub_UE.c with clang-format

---
 openair2/PHY_INTERFACE/phy_stub_UE.c | 1418 ++++++++++++++------------
 1 file changed, 743 insertions(+), 675 deletions(-)

diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 075ea30d00..bf2bbf7429 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -1,14 +1,29 @@
+/*
+ * 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 "openair1/PHY/defs.h"
-//#include "openair2/PHY_INTERFACE/IF_Module.h"
-//#include "openair1/PHY/extern.h"
 #include "openair2/LAYER2/MAC/mac_extern.h"
 #include "openair2/LAYER2/MAC/mac.h"
 #include "openair2/LAYER2/MAC/mac_proto.h"
-//#include "openair2/LAYER2/MAC/vars.h"
 #include "openair1/SCHED_UE/sched_UE.h"
 #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h"
-//#include "common/ran_context.h"
 #include "openair2/PHY_INTERFACE/phy_stub_UE.h"
 #include "openair2/ENB_APP/L1_paramdef.h"
 #include "openair2/ENB_APP/enb_paramdef.h"
@@ -16,14 +31,12 @@
 #include "common/config/config_load_configmodule.h"
 #include "common/config/config_userapi.h"
 
-//#define DEADLINE_SCHEDULER 1
-
-
-extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
-extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
 extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
-void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
-
+void configure_nfapi_pnf(char *vnf_ip_addr,
+                         int vnf_p5_port,
+                         char *pnf_ip_addr,
+                         int pnf_p7_port,
+                         int vnf_p7_port);
 
 UL_IND_t *UL_INFO = NULL;
 nfapi_tx_request_pdu_t* tx_request_pdu_list = NULL;
@@ -31,8 +44,6 @@ nfapi_dl_config_request_t* dl_config_req = NULL;
 nfapi_ul_config_request_t* ul_config_req = NULL;
 nfapi_hi_dci0_request_t* hi_dci0_req = NULL;
 
-//extern uint8_t nfapi_pnf;
-//UL_IND_t *UL_INFO;
 extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10];
 //extern int timer_subframe;
 //extern int timer_frame;
@@ -42,608 +53,661 @@ extern uint16_t sf_ahead;
 void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
 void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
 
+void fill_rx_indication_UE_MAC(module_id_t Mod_id,
+                               int frame,
+                               int subframe,
+                               UL_IND_t *UL_INFO,
+                               uint8_t *ulsch_buffer,
+                               uint16_t buflen,
+                               uint16_t rnti,
+                               int index) {
+  nfapi_rx_indication_pdu_t *pdu;
+  int timing_advance_update;
 
+  pthread_mutex_lock(&fill_ul_mutex.rx_mutex);
 
-void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t* UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index)
-{
-	  nfapi_rx_indication_pdu_t *pdu;
+  UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe;
+  UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
+  UL_INFO->rx_ind.vendor_extension = ul_config_req->vendor_extension;
 
-	  int timing_advance_update;
+  pdu = &UL_INFO->rx_ind.rx_indication_body
+             .rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus];
+  // pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index];
 
+  // pdu->rx_ue_information.handle          = eNB->ulsch[UE_id]->handle;
+  pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
+  pdu->rx_ue_information.rnti = rnti;
+  pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
+  pdu->rx_indication_rel8.length = buflen;
+  pdu->rx_indication_rel8.offset = 1;
+  pdu->rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG;
+  pdu->rx_indication_rel9.timing_advance_r9 = 0;
 
-	  // pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-	  // change for mutiple UE's simulation.
-	  pthread_mutex_lock(&fill_ul_mutex.rx_mutex);
+  // ulsch_buffer is necessary to keep its value.
+  pdu->data = malloc(buflen);
+  memcpy(pdu->data, ulsch_buffer, buflen);
+  // estimate timing advance for MAC
+  timing_advance_update = 0; // Don't know what to put here
+  pdu->rx_indication_rel8.timing_advance = timing_advance_update;
 
+  int SNRtimes10 = 640;
 
-	  UL_INFO->rx_ind.sfn_sf                    = frame<<4| subframe;
-	  UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
-	  UL_INFO->rx_ind.vendor_extension		     = ul_config_req->vendor_extension;
-
-
-	  pdu                                    = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus];
-	  //pdu                                    = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index];
-
-	  //  pdu->rx_ue_information.handle          = eNB->ulsch[UE_id]->handle;
-	  pdu->rx_ue_information.tl.tag          = NFAPI_RX_UE_INFORMATION_TAG;
-	  pdu->rx_ue_information.rnti            = rnti;
-	  pdu->rx_indication_rel8.tl.tag         = NFAPI_RX_INDICATION_REL8_TAG;
-	  //pdu->rx_indication_rel8.length         = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
-	  pdu->rx_indication_rel8.length         = buflen;
-	  pdu->rx_indication_rel8.offset         = 1;   // DJP - I dont understand - but broken unless 1 ????  0;  // filled in at the end of the UL_INFO formation
-	  pdu->rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG;
-	  pdu->rx_indication_rel9.timing_advance_r9 = 0;
-
-	  // ulsch_buffer is necessary to keep its value.
-	  //pdu->data                              = ulsch_buffer;
-	  pdu->data = malloc(buflen);
-	  memcpy(pdu->data,ulsch_buffer,buflen);
-	  // estimate timing advance for MAC
-	  //sync_pos                               = lte_est_timing_advance_pusch(eNB,UE_id);
-	  timing_advance_update                  = 0;  // Don't know what to put here
-	  pdu->rx_indication_rel8.timing_advance = timing_advance_update;
-
-		  int SNRtimes10 = 640;
-
-	  if      (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0;
-	  else if (SNRtimes10 >  635) pdu->rx_indication_rel8.ul_cqi=255;
-	  else                        pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5;
-
-
-	  UL_INFO->rx_ind.rx_indication_body.number_of_pdus++;
-	  UL_INFO->rx_ind.sfn_sf = frame<<4 | subframe;
-	  // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-	  // change for mutiple UE's simulation.
-	  pthread_mutex_unlock(&fill_ul_mutex.rx_mutex);
-
+  if (SNRtimes10 < -640)
+    pdu->rx_indication_rel8.ul_cqi = 0;
+  else if (SNRtimes10 > 635)
+    pdu->rx_indication_rel8.ul_cqi = 255;
+  else
+    pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5;
 
+  UL_INFO->rx_ind.rx_indication_body.number_of_pdus++;
+  UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe;
+  pthread_mutex_unlock(&fill_ul_mutex.rx_mutex);
 }
 
-void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti) {
-
-
-  // change for mutiple UE's simulation.
-  //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
+void fill_sr_indication_UE_MAC(int Mod_id,
+                               int frame,
+                               int subframe,
+                               UL_IND_t *UL_INFO,
+                               uint16_t rnti) {
   pthread_mutex_lock(&fill_ul_mutex.sr_mutex);
 
-  nfapi_sr_indication_t       *sr_ind = &UL_INFO->sr_ind;
-  nfapi_sr_indication_body_t  *sr_ind_body =    &sr_ind->sr_indication_body;
-  nfapi_sr_indication_pdu_t *pdu =   &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs];
-  UL_INFO->sr_ind.vendor_extension		     = ul_config_req->vendor_extension;
+  nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind;
+  nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body;
+  nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs];
+  UL_INFO->sr_ind.vendor_extension = ul_config_req->vendor_extension;
 
-  //nfapi_sr_indication_pdu_t *pdu =   &UL_INFO->sr_ind.sr_indication_body.sr_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus];
-
-  sr_ind->sfn_sf = frame<<4|subframe;
+  sr_ind->sfn_sf = frame << 4 | subframe;
   sr_ind->header.message_id = NFAPI_RX_SR_INDICATION;
 
   sr_ind_body->tl.tag = NFAPI_SR_INDICATION_BODY_TAG;
 
-  pdu->instance_length                                = 0; // don't know what to do with this
+  pdu->instance_length = 0; // don't know what to do with this
   //  pdu->rx_ue_information.handle                       = handle;
-  pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
-  pdu->rx_ue_information.rnti                         = rnti; //UE_mac_inst[Mod_id].crnti
-
-
-  // dependency from PHY not sure how to substitute this. Should we hardcode it?
-  //int SNRtimes10 = dB_fixed_times10(stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
-  int SNRtimes10 = 640;
+  pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
+  pdu->rx_ue_information.rnti = rnti; // UE_mac_inst[Mod_id].crnti
 
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
-
-
-  if      (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
-  else if (SNRtimes10 >  635) pdu->ul_cqi_information.ul_cqi=255;
-  else                        pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5;
   pdu->ul_cqi_information.channel = 0;
 
-  //UL_INFO->rx_ind.rx_indication_body.number_of_pdus++;
+  int SNRtimes10 = 640;
+  if (SNRtimes10 < -640)
+    pdu->ul_cqi_information.ul_cqi = 0;
+  else if (SNRtimes10 > 635)
+    pdu->ul_cqi_information.ul_cqi = 255;
+  else
+    pdu->ul_cqi_information.ul_cqi = (640 + SNRtimes10) / 5;
+
+  // UL_INFO->rx_ind.rx_indication_body.number_of_pdus++;
   sr_ind_body->number_of_srs++;
-  // change for mutiple UE's simulation.
-  // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
   pthread_mutex_unlock(&fill_ul_mutex.sr_mutex);
 }
 
-
-void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti) {
-
-  // change for mutiple UE's simulation.
-  //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
+void fill_crc_indication_UE_MAC(int Mod_id,
+                                int frame,
+                                int subframe,
+                                UL_IND_t *UL_INFO,
+                                uint8_t crc_flag,
+                                int index,
+                                uint16_t rnti) {
   pthread_mutex_lock(&fill_ul_mutex.crc_mutex);
 
-  // REMEMBER HAVE EXCHANGED THE FOLLOWING TWO LINES HERE!
-  nfapi_crc_indication_pdu_t *pdu =   &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs];
+  nfapi_crc_indication_pdu_t *pdu =
+      &UL_INFO->crc_ind.crc_indication_body
+           .crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs];
 
-  UL_INFO->crc_ind.sfn_sf                    = frame<<4| subframe;
-  UL_INFO->crc_ind.vendor_extension		     = ul_config_req->vendor_extension;
-  UL_INFO->crc_ind.header.message_id              = NFAPI_CRC_INDICATION;
+  UL_INFO->crc_ind.sfn_sf = frame << 4 | subframe;
+  UL_INFO->crc_ind.vendor_extension = ul_config_req->vendor_extension;
+  UL_INFO->crc_ind.header.message_id = NFAPI_CRC_INDICATION;
   UL_INFO->crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG;
 
-  pdu->instance_length                                = 0; // don't know what to do with this
-  //  pdu->rx_ue_information.handle                       = handle;
-  pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
+  pdu->instance_length = 0;
+  pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
 
-  //pdu->rx_ue_information.rnti                         = UE_mac_inst[Mod_id].crnti;
-  pdu->rx_ue_information.rnti                         = rnti;
-  pdu->crc_indication_rel8.tl.tag                     = NFAPI_CRC_INDICATION_REL8_TAG;
-  pdu->crc_indication_rel8.crc_flag                   = crc_flag;
+  pdu->rx_ue_information.rnti = rnti;
+  pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG;
+  pdu->crc_indication_rel8.crc_flag = crc_flag;
 
   UL_INFO->crc_ind.crc_indication_body.number_of_crcs++;
 
-  LOG_D(PHY, "%s() rnti:%04x pdus:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs);
+  LOG_D(PHY,
+        "%s() rnti:%04x pdus:%d\n",
+        __FUNCTION__,
+        pdu->rx_ue_information.rnti,
+        UL_INFO->crc_ind.crc_indication_body.number_of_crcs);
 
-  // change for mutiple UE's simulation.
-  // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
   pthread_mutex_unlock(&fill_ul_mutex.crc_mutex);
 }
 
-void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) {
+void fill_rach_indication_UE_MAC(int Mod_id,
+                                 int frame,
+                                 int subframe,
+                                 UL_IND_t *UL_INFO,
+                                 uint8_t ra_PreambleIndex,
+                                 uint16_t ra_RNTI) {
+  LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n");
 
-	LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n");
+  pthread_mutex_lock(&fill_ul_mutex.rach_mutex);
 
-	// change for mutiple UE's simulation.
-	// pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-	pthread_mutex_lock(&fill_ul_mutex.rach_mutex);
+  UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1;
 
-	// memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4.
-	// UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
+  UL_INFO->rach_ind.header.message_id = NFAPI_RACH_INDICATION;
+  UL_INFO->rach_ind.sfn_sf = frame << 4 | subframe;
+  UL_INFO->rach_ind.vendor_extension = NULL;
 
-	    UL_INFO->rach_ind.rach_indication_body.number_of_preambles                 = 1;
+  UL_INFO->rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG;
 
-	    //eNB->UL_INFO.rach_ind.preamble_list                       = &eNB->preamble_list[0];
-	    UL_INFO->rach_ind.header.message_id                         = NFAPI_RACH_INDICATION;
-	    UL_INFO->rach_ind.sfn_sf                                    = frame<<4 | subframe;
-	    UL_INFO->rach_ind.vendor_extension							= NULL;
+  const int np = UL_INFO->rach_ind.rach_indication_body.number_of_preambles;
+  UL_INFO->rach_ind.rach_indication_body.preamble_list =
+      calloc(np, sizeof(nfapi_preamble_pdu_t));
+  UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.tl.tag =
+      NFAPI_PREAMBLE_REL8_TAG;
+  UL_INFO->rach_ind.rach_indication_body.preamble_list[0]
+      .preamble_rel8.timing_advance = 0; // Not sure about that
 
-	    UL_INFO->rach_ind.rach_indication_body.tl.tag                              = NFAPI_RACH_INDICATION_BODY_TAG;
+  // The two following should get extracted from the call to
+  // get_prach_resources().
+  UL_INFO->rach_ind.rach_indication_body.preamble_list[0]
+      .preamble_rel8.preamble = ra_PreambleIndex;
+  UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti =
+      ra_RNTI;
+  // UL_INFO->rach_ind.rach_indication_body.number_of_preambles++;
 
+  UL_INFO->rach_ind.rach_indication_body.preamble_list[0]
+      .preamble_rel13.rach_resource_type = 0;
+  UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length = 0;
 
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list = (nfapi_preamble_pdu_t*)malloc(UL_INFO->rach_ind.rach_indication_body.number_of_preambles*sizeof(nfapi_preamble_pdu_t));
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.tl.tag   		= NFAPI_PREAMBLE_REL8_TAG;
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance = 0; // Not sure about that
+  LOG_I(PHY,
+        "UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, "
+        "rach_resource_type %d\n",
+        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.preamble,
+        UL_INFO->rach_ind.rach_indication_body.preamble_list[0]
+            .preamble_rel8.rnti,
+        UL_INFO->rach_ind.rach_indication_body.preamble_list[0]
+            .preamble_rel13.rach_resource_type);
 
-	    //The two following should get extracted from the call to get_prach_resources().
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble = ra_PreambleIndex;
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti 	  = ra_RNTI;
-	    //UL_INFO->rach_ind.rach_indication_body.number_of_preambles++;
-
-
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type = 0;
-	    UL_INFO->rach_ind.rach_indication_body.preamble_list[0].instance_length					 = 0;
-
-
-	          //LOG_E(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n");
-	          LOG_I(PHY,"UE Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
-	        	  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.preamble,
-	        	  UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti,
-	        	  UL_INFO->rach_ind.rach_indication_body.preamble_list[0].preamble_rel13.rach_resource_type);
-
-	          // This function is currently defined only in the nfapi-RU-RAU-split so we should call it when we merge
-	          // with that branch.
-	          oai_nfapi_rach_ind(&UL_INFO->rach_ind);
-	          free(UL_INFO->rach_ind.rach_indication_body.preamble_list);
-
-	         // memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4.
-	          //free(UL_INFO);
-
-	        //}
-	      // change for mutiple UE's simulation.
-	      // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-	      pthread_mutex_unlock(&fill_ul_mutex.rach_mutex);
+  // This function is currently defined only in the nfapi-RU-RAU-split so we
+  // should call it when we merge with that branch.
+  oai_nfapi_rach_ind(&UL_INFO->rach_ind);
+  free(UL_INFO->rach_ind.rach_indication_body.preamble_list);
 
+  pthread_mutex_unlock(&fill_ul_mutex.rach_mutex);
 }
 
-void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) {
+void fill_ulsch_cqi_indication_UE_MAC(int Mod_id,
+                                      uint16_t frame,
+                                      uint8_t subframe,
+                                      UL_IND_t *UL_INFO,
+                                      uint16_t rnti) {
+  pthread_mutex_lock(&fill_ul_mutex.cqi_mutex);
+  nfapi_cqi_indication_pdu_t *pdu =
+      &UL_INFO->cqi_ind.cqi_indication_body
+           .cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
+  nfapi_cqi_indication_raw_pdu_t *raw_pdu =
+      &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list
+           [UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
 
-	// change for mutiple UE's simulation.
-	//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-	pthread_mutex_lock(&fill_ul_mutex.cqi_mutex);
-	nfapi_cqi_indication_pdu_t *pdu         = &UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
-	nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
+  UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe;
+  // because of nfapi_vnf.c:733, set message id to 0, not
+  // NFAPI_RX_CQI_INDICATION;
+  UL_INFO->cqi_ind.header.message_id = 0;
+  UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG;
 
-	UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe;
-        // because of nfapi_vnf.c:733, set message id to 0, not NFAPI_RX_CQI_INDICATION;
-	UL_INFO->cqi_ind.header.message_id = 0;
-	UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG;
+  pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
+  pdu->rx_ue_information.rnti = rnti;
+  // Since we assume that CRC flag is always 0 (ACK) I guess that data_offset
+  // should always be 0.
+  pdu->cqi_indication_rel8.data_offset = 0;
 
-	pdu->rx_ue_information.tl.tag          = NFAPI_RX_UE_INFORMATION_TAG;
-	pdu->rx_ue_information.rnti = rnti;
-	// Since we assume that CRC flag is always 0 (ACK) I guess that data_offset should always be 0.
-	pdu->cqi_indication_rel8.data_offset = 0;
-
-	// by default set O to rank 1 value
-	//pdu->cqi_indication_rel8.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0);
-	//  Not useful field for our case
-	pdu->cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG;
-	pdu->cqi_indication_rel8.length = 1;
-	pdu->cqi_indication_rel8.ri  = 0;
-
-
-	pdu->cqi_indication_rel8.timing_advance = 0;
-	//pdu->cqi_indication_rel8.number_of_cc_reported = 1;
-	pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
-	pdu->ul_cqi_information.channel = 1; // PUSCH
-
-	// eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI
-	const int cqi = 15;
-	raw_pdu->pdu[0] = cqi << 4;
+  pdu->cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG;
+  pdu->cqi_indication_rel8.length = 1;
+  pdu->cqi_indication_rel8.ri = 0;
 
+  pdu->cqi_indication_rel8.timing_advance = 0;
+  // pdu->cqi_indication_rel8.number_of_cc_reported = 1;
+  pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
+  pdu->ul_cqi_information.channel = 1; // PUSCH
 
+  // eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI
+  const int cqi = 15;
+  raw_pdu->pdu[0] = cqi << 4;
 
   UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis++;
-  // change for mutiple UE's simulation.
-  //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
   pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex);
 }
 
-void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti)
-{
-
-  // change for mutiple UE's simulation.
-  //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
+void fill_ulsch_harq_indication_UE_MAC(
+    int Mod_id,
+    int frame,
+    int subframe,
+    UL_IND_t *UL_INFO,
+    nfapi_ul_config_ulsch_harq_information *harq_information,
+    uint16_t rnti) {
   pthread_mutex_lock(&fill_ul_mutex.harq_mutex);
 
-  nfapi_harq_indication_pdu_t *pdu =   &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs];
-  int i;
+  nfapi_harq_indication_pdu_t *pdu =
+      &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list
+           [UL_INFO->harq_ind.harq_indication_body.number_of_harqs];
 
   UL_INFO->harq_ind.header.message_id = NFAPI_HARQ_INDICATION;
-  UL_INFO->harq_ind.sfn_sf = frame<<4|subframe;
-  UL_INFO->harq_ind.vendor_extension		     = ul_config_req->vendor_extension;
+  UL_INFO->harq_ind.sfn_sf = frame << 4 | subframe;
+  UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension;
 
-  UL_INFO->harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG;
+  UL_INFO->harq_ind.harq_indication_body.tl.tag =
+      NFAPI_HARQ_INDICATION_BODY_TAG;
 
-  pdu->instance_length                                = 0; // don't know what to do with this
+  pdu->instance_length = 0; // don't know what to do with this
   //  pdu->rx_ue_information.handle                       = handle;
-  pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
-  pdu->rx_ue_information.rnti                         = rnti;
+  pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
+  pdu->rx_ue_information.rnti = rnti;
 
   // For now we consider only FDD
-  //if (eNB->frame_parms.frame_type == FDD) {
-    pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
-    pdu->harq_indication_fdd_rel13.mode = 0;
-    pdu->harq_indication_fdd_rel13.number_of_ack_nack = harq_information->harq_information_rel10.harq_size;
+  // if (eNB->frame_parms.frame_type == FDD) {
+  pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
+  pdu->harq_indication_fdd_rel13.mode = 0;
+  pdu->harq_indication_fdd_rel13.number_of_ack_nack =
+      harq_information->harq_information_rel10.harq_size;
 
-    // Could this be wrong? Is the number_of_ack_nack field equivalent to O_ACK?
-    //pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
+  // Could this be wrong? Is the number_of_ack_nack field equivalent to O_ACK?
+  // pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
 
-    for (i=0;iharq_information_rel10.harq_size;i++) {
-
-      pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 1; // Assuming always an ACK (No NACK or DTX)
-
-    }
+  for (int i = 0; i < harq_information->harq_information_rel10.harq_size; i++) {
+    pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 1; // Assume always ACK (No NACK or DTX)
+  }
 
   UL_INFO->harq_ind.harq_indication_body.number_of_harqs++;
-  // change for mutiple UE's simulation.
-  //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
-  pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);}
-
+  pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);
+}
 
 void fill_uci_harq_indication_UE_MAC(int Mod_id,
 			      int frame,
 			      int subframe,
 			      UL_IND_t *UL_INFO,
 			      nfapi_ul_config_harq_information *harq_information,
-			      uint16_t rnti
-			      /*uint8_t tdd_mapping_mode,
-			      uint16_t tdd_multiplexing_mask*/) {
-
-
-  // change for mutiple UE's simulation.
-  //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
+			      uint16_t rnti) {
   pthread_mutex_lock(&fill_ul_mutex.harq_mutex);
 
-  nfapi_harq_indication_t *ind       = &UL_INFO->harq_ind;
+  nfapi_harq_indication_t *ind = &UL_INFO->harq_ind;
   nfapi_harq_indication_body_t *body = &ind->harq_indication_body;
-  nfapi_harq_indication_pdu_t *pdu =   &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs];
+  nfapi_harq_indication_pdu_t *pdu =
+      &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body
+                               .number_of_harqs];
 
-  UL_INFO->harq_ind.vendor_extension		     = ul_config_req->vendor_extension;
+  UL_INFO->harq_ind.vendor_extension = ul_config_req->vendor_extension;
 
-  ind->sfn_sf = frame<<4|subframe;
+  ind->sfn_sf = frame << 4 | subframe;
   ind->header.message_id = NFAPI_HARQ_INDICATION;
 
   body->tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG;
-  pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
+  pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
 
-  pdu->instance_length                                = 0; // don't know what to do with this
-  //  pdu->rx_ue_information.handle                       = handle;
-  pdu->rx_ue_information.rnti                         = rnti;
+  pdu->instance_length = 0; // don't know what to do with this
+  pdu->rx_ue_information.rnti = rnti;
 
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
 
   int SNRtimes10 = 640;
 
-
-  if      (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
-  else if (SNRtimes10 >  635) pdu->ul_cqi_information.ul_cqi=255;
-  else                        pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5;
+  if (SNRtimes10 < -640)
+    pdu->ul_cqi_information.ul_cqi = 0;
+  else if (SNRtimes10 > 635)
+    pdu->ul_cqi_information.ul_cqi = 255;
+  else
+    pdu->ul_cqi_information.ul_cqi = (640 + SNRtimes10) / 5;
   pdu->ul_cqi_information.channel = 0;
-  if(harq_information->harq_information_rel9_fdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG){
-      if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
-          (harq_information->harq_information_rel9_fdd.harq_size == 1)) {
-
-      pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
+  if (harq_information->harq_information_rel9_fdd.tl.tag
+      == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG) {
+    if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0)
+        && (harq_information->harq_information_rel9_fdd.harq_size == 1)) {
+      pdu->harq_indication_fdd_rel13.tl.tag =
+          NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
       pdu->harq_indication_fdd_rel13.mode = 0;
       pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1;
 
-      //AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
-      pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; // Assuming always an ACK (No NACK or DTX)
+      // AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4,
+      // "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
+      pdu->harq_indication_fdd_rel13.harq_tb_n[0] =
+          1; // Assuming always an ACK (No NACK or DTX)
 
-
-    }
-    else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
-                 (harq_information->harq_information_rel9_fdd.harq_size == 2)) {
-      pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
+    } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0)
+               && (harq_information->harq_information_rel9_fdd.harq_size
+                   == 2)) {
+      pdu->harq_indication_fdd_rel13.tl.tag =
+          NFAPI_HARQ_INDICATION_FDD_REL13_TAG;
       pdu->harq_indication_fdd_rel13.mode = 0;
       pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2;
-      pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; // Assuming always an ACK (No NACK or DTX)
-      pdu->harq_indication_fdd_rel13.harq_tb_n[1] = 1; // Assuming always an ACK (No NACK or DTX)
-
+      pdu->harq_indication_fdd_rel13.harq_tb_n[0] =
+          1; // Assuming always an ACK (No NACK or DTX)
+      pdu->harq_indication_fdd_rel13.harq_tb_n[1] =
+          1; // Assuming always an ACK (No NACK or DTX)
     }
-  }else if(harq_information->harq_information_rel10_tdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG ){
-      if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) &&
-          (harq_information->harq_information_rel10_tdd.harq_size == 1)) {
-        pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
-        pdu->harq_indication_tdd_rel13.mode = 0;
-        pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
-        pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
-
-      }  else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) &&
-                  (harq_information->harq_information_rel10_tdd.harq_size == 2)) {
-        pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
-        pdu->harq_indication_tdd_rel13.mode = 0;
-        pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
-        pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
-        pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = 1;
-
-      }
-  } else AssertFatal(1==0,"only format 1a/b for now, received \n");
+  } else if (harq_information->harq_information_rel10_tdd.tl.tag
+             == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG) {
+    if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 0)
+        && (harq_information->harq_information_rel10_tdd.harq_size == 1)) {
+      pdu->harq_indication_tdd_rel13.tl.tag =
+          NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
+      pdu->harq_indication_tdd_rel13.mode = 0;
+      pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
+      pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
 
+    } else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1)
+               && (harq_information->harq_information_rel10_tdd.harq_size
+                   == 2)) {
+      pdu->harq_indication_tdd_rel13.tl.tag =
+          NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
+      pdu->harq_indication_tdd_rel13.mode = 0;
+      pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
+      pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
+      pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = 1;
+    }
+  } else
+    AssertFatal(1 == 0, "only format 1a/b for now, received \n");
 
   UL_INFO->harq_ind.harq_indication_body.number_of_harqs++;
-  LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
-  // change for mutiple UE's simulation.
-  //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
+  LOG_D(PHY,
+        "Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n",
+        UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
   pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);
-
 }
 
-
 void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
-                         nfapi_ul_config_request_pdu_t *ul_config_pdu,
-                         uint16_t frame,uint8_t subframe,uint8_t srs_present, int index)
-{
-
+                                nfapi_ul_config_request_pdu_t *ul_config_pdu,
+                                uint16_t frame,
+                                uint8_t subframe,
+                                uint8_t srs_present,
+                                int index) {
   if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) {
-    LOG_D(PHY,"Applying UL config for UE, rnti %x for frame %d, subframe %d\n",
-         (ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8).rnti,frame,subframe);
-    uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
+    LOG_D(PHY,
+          "Applying UL config for UE, rnti %x for frame %d, subframe %d\n",
+          (ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8).rnti,
+          frame,
+          subframe);
+    uint8_t ulsch_buffer[5477] __attribute__((aligned(32)));
     uint16_t buflen = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size;
 
     uint16_t rnti = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti;
-    uint8_t access_mode=SCHEDULED_ACCESS;
-    if(buflen>0){
-    	if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case
-    		LOG_D(MAC, "handle_nfapi_ul_pdu_UE_MAC 2.2, Mod_id:%d, SFN/SF: %d/%d \n", Mod_id, frame, subframe);
-    		fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-    		fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
-    		Msg3_transmitted(Mod_id, 0, frame, 0);
-    		//  Modification
-    		UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
-    		UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+    uint8_t access_mode = SCHEDULED_ACCESS;
+    if (buflen > 0) {
+      if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case
+        LOG_D(MAC,
+              "handle_nfapi_ul_pdu_UE_MAC 2.2, Mod_id:%d, SFN/SF: %d/%d \n",
+              Mod_id,
+              frame,
+              subframe);
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  UE_mac_inst[Mod_id].RA_prach_resources.Msg3,
+                                  buflen,
+                                  rnti,
+                                  index);
+        Msg3_transmitted(Mod_id, 0, frame, 0);
+        //  Modification
+        UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+        UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
 
-    		// This should be done after the reception of the respective hi_dci0
-    		//UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-    	}
-    	else {
-    		ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
-    		fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-    		fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
-    	}
+        // This should be done after the reception of the respective hi_dci0
+        // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+      } else {
+        ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  ulsch_buffer,
+                                  buflen,
+                                  rnti,
+                                  index);
+      }
     }
   }
 
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) {
+    // AssertFatal((UE_id =
+    // find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
+    //            "No available UE ULSCH for rnti
+    //            %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
+    uint8_t ulsch_buffer[5477] __attribute__((aligned(32)));
+    uint16_t buflen =
+        ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
+    nfapi_ul_config_ulsch_harq_information *ulsch_harq_information =
+        &ul_config_pdu->ulsch_harq_pdu.harq_information;
+    uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
+    uint8_t access_mode = SCHEDULED_ACCESS;
+    if (buflen > 0) {
+      if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  UE_mac_inst[Mod_id].RA_prach_resources.Msg3,
+                                  buflen,
+                                  rnti,
+                                  index);
+        Msg3_transmitted(Mod_id, 0, frame, 0);
+        // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+        // Modification
+        UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+        UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+      } else {
+        ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  ulsch_buffer,
+                                  buflen,
+                                  rnti,
+                                  index);
+      }
+    }
+    if (ulsch_harq_information != NULL)
+      fill_ulsch_harq_indication_UE_MAC(
+          Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
 
-	  //AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
-    //            "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
-	  uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
-	  uint16_t buflen = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
-	  nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information;
-	  uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
-	  uint8_t access_mode=SCHEDULED_ACCESS;
-	  if(buflen>0){
-		  if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case
-			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
-			  Msg3_transmitted(Mod_id, 0, frame, 0);
-			  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-			  // Modification
-			  UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
-			  UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-		  }
-		  else {
-			  ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
-			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
-		  }
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) {
+    uint8_t ulsch_buffer[5477] __attribute__((aligned(32)));
+    uint16_t buflen = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
 
-	  }
-	  if(ulsch_harq_information!=NULL)
-		  fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
+    uint16_t rnti = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
+    uint8_t access_mode = SCHEDULED_ACCESS;
+    if (buflen > 0) {
+      if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  UE_mac_inst[Mod_id].RA_prach_resources.Msg3,
+                                  buflen,
+                                  rnti,
+                                  index);
+        Msg3_transmitted(Mod_id, 0, frame, 0);
+        // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+        // Modification
+        UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+        UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+      } else {
+        ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  ulsch_buffer,
+                                  buflen,
+                                  rnti,
+                                  index);
+      }
+    }
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
+    uint8_t ulsch_buffer[5477] __attribute__((aligned(32)));
+    uint16_t buflen = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
+    nfapi_ul_config_ulsch_harq_information *ulsch_harq_information =
+        &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
 
+    uint16_t rnti = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
+    uint8_t access_mode = SCHEDULED_ACCESS;
+    if (buflen > 0) {
+      if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  UE_mac_inst[Mod_id].RA_prach_resources.Msg3,
+                                  buflen,
+                                  rnti,
+                                  index);
+        Msg3_transmitted(Mod_id, 0, frame, 0);
+        // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+        // Modification
+        UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+        UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+      } else {
+        ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
+        fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
+        fill_rx_indication_UE_MAC(Mod_id,
+                                  frame,
+                                  subframe,
+                                  UL_INFO,
+                                  ulsch_buffer,
+                                  buflen,
+                                  rnti,
+                                  index);
+      }
+    }
+
+    if (ulsch_harq_information != NULL)
+      fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
+    uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
+
+    nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information;
+    if (ulsch_harq_information != NULL)
+      fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) {
+    AssertFatal(1 == 0, "NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n");
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) {
+    AssertFatal(1 == 0,
+                "NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n");
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
+    AssertFatal(1 == 0,
+                "NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n");
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
+    uint16_t rnti =
+        ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
+
+    if (ue_get_SR(Mod_id, 0, frame, 0, rnti, subframe))
+      fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
+
+  } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
+    // AssertFatal((UE_id =
+    // find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
+    //            "No available UE UCI for rnti
+    //            %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti);
+
+    uint16_t rnti =
+        ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
+
+    // We fill the sr_indication only if ue_get_sr() would normally instruct PHY
+    // to send a SR.
+    if (ue_get_SR(Mod_id, 0, frame, 0, rnti, subframe))
+      fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
+
+    nfapi_ul_config_harq_information *ulsch_harq_information =
+        &ul_config_pdu->uci_sr_harq_pdu.harq_information;
+    if (ulsch_harq_information != NULL)
+      fill_uci_harq_indication_UE_MAC(
+          Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
   }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) {
-	 uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
-	  uint16_t buflen = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
-
-	  uint16_t rnti = ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
-	  uint8_t access_mode=SCHEDULED_ACCESS;
-	  if(buflen>0){
-		  if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case
-			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
-			  Msg3_transmitted(Mod_id, 0, frame, 0);
-			  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-			  // Modification
-			  UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
-			  UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-		  }
-		  else {
-			  ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
-			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
-		  }
-	  }
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
-
-	  uint8_t ulsch_buffer[5477] __attribute__ ((aligned(32)));
-	  uint16_t buflen = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.size;
-	  nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
-
-	  uint16_t rnti = ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti;
-	  uint8_t access_mode=SCHEDULED_ACCESS;
-	  if(buflen>0){
-		  if(UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){ // Msg3 case
-			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, UE_mac_inst[Mod_id].RA_prach_resources.Msg3,buflen, rnti, index);
-			  Msg3_transmitted(Mod_id, 0, frame, 0);
-			  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-			  // Modification
-			  UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
-			  UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-		  }
-		  else {
-			  ue_get_sdu( Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode);
-			  fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti);
-			  fill_rx_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_buffer,buflen, rnti, index);
-		  }
-	  }
-
-	  if(ulsch_harq_information!=NULL)
-		  fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti);
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
-
-	  uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
-
-	  nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information;
-	  if(ulsch_harq_information != NULL)
-		  fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti);
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) {
-    AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n");
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) {
-    AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n");
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
-    AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n");
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
-
-	  uint16_t rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
-
-	  if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe))
-		  fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti);
-
-  }
-  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
-    //AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
-    //            "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti);
-
-	  uint16_t rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
-
-	  // We fill the sr_indication only if ue_get_sr() would normally instruct PHY to send a SR.
-	  if (ue_get_SR(Mod_id ,0,frame, 0, rnti, subframe))
-		  fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,rnti);
-
-	  nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information;
-	  if (ulsch_harq_information != NULL)
-		  fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO,ulsch_harq_information, rnti);
-
-  }
-
 }
 
-
-
-
-
-
-int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int timer_frame, int timer_subframe, module_id_t Mod_id)
-{
-	//if (req!=NULL){ // && req->ul_config_request_body.ul_config_pdu_list !=NULL){
-  LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
-      __FUNCTION__,
-      NFAPI_SFNSF2DEC(req->sfn_sf),
-      req->ul_config_request_body.number_of_pdus,
-      req->ul_config_request_body.rach_prach_frequency_resources,
-      req->ul_config_request_body.srs_present
-      );
+int ul_config_req_UE_MAC(nfapi_ul_config_request_t *req,
+                         int timer_frame,
+                         int timer_subframe,
+                         module_id_t Mod_id) {
+  LOG_D(PHY,
+        "[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d "
+        "rach_prach_frequency_resources:%d srs_present:%u\n",
+        __FUNCTION__,
+        NFAPI_SFNSF2DEC(req->sfn_sf),
+        req->ul_config_request_body.number_of_pdus,
+        req->ul_config_request_body.rach_prach_frequency_resources,
+        req->ul_config_request_body.srs_present);
 
   int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
 
+  LOG_D(MAC,
+        "ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d, SFN/SF: "
+        "%d/%d \n",
+        req->ul_config_request_body.number_of_pdus,
+        timer_frame,
+        timer_subframe);
 
-  LOG_D(MAC, "ul_config_req_UE_MAC() TOTAL NUMBER OF UL_CONFIG PDUs: %d, SFN/SF: %d/%d \n", req->ul_config_request_body.number_of_pdus, timer_frame, timer_subframe);
-
-
-
-  for (int i=0;iul_config_request_body.number_of_pdus;i++)
-  {
-
-    if (
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti) ||
-    		(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE && req->ul_config_request_body.ul_config_pdu_list[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == UE_mac_inst[Mod_id].crnti)
-       )
-    {
-
-      handle_nfapi_ul_pdu_UE_MAC(Mod_id,&req->ul_config_request_body.ul_config_pdu_list[i],sfn,sf,req->ul_config_request_body.srs_present, i);
-
-    }
-    else
-    {
-      //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type);
+  const rnti_t rnti = UE_mac_inst[Mod_id].crnti;
+  for (int i = 0; i < req->ul_config_request_body.number_of_pdus; i++) {
+    nfapi_ul_config_request_pdu_t* pdu = &req->ul_config_request_body.ul_config_pdu_list[i];
+    const int pdu_type = pdu->pdu_type;
+    if (   (pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE
+            && pdu->ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)
+        || (pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE
+            && pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)
+        || (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE
+            && pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)
+        || (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE
+            && pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)
+        || (pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE
+            && pdu->uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)
+        || (pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE
+            && pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)
+        || (pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
+            && pdu->uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) {
+      handle_nfapi_ul_pdu_UE_MAC(
+          Mod_id, pdu, sfn, sf, req->ul_config_request_body.srs_present, i);
+    } else {
+      // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n",
+      // __FUNCTION__, i, ul_config_pdu_list[i].pdu_type);
     }
   }
 
-//	}
-
   return 0;
 }
 
+int tx_req_UE_MAC(nfapi_tx_request_t *req) {
+  LOG_D(PHY,
+        "%s() SFN/SF:%d/%d PDUs:%d\n",
+        __FUNCTION__,
+        NFAPI_SFNSF2SFN(req->sfn_sf),
+        NFAPI_SFNSF2SF(req->sfn_sf),
+        req->tx_request_body.number_of_pdus);
 
-
-int tx_req_UE_MAC(nfapi_tx_request_t* req)
-{
-
-  LOG_D(PHY,"%s() SFN/SF:%d/%d PDUs:%d\n", __FUNCTION__, NFAPI_SFNSF2SFN(req->sfn_sf), NFAPI_SFNSF2SF(req->sfn_sf), req->tx_request_body.number_of_pdus);
-
-
-    for (int i=0; itx_request_body.number_of_pdus; i++)
-    {
-      LOG_D(PHY,"%s() SFN/SF:%d/%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n",
+  for (int i = 0; i < req->tx_request_body.number_of_pdus; i++) {
+    LOG_D(PHY,
+          "%s() SFN/SF:%d/%d number_of_pdus:%d [PDU:%d] pdu_length:%d "
+          "pdu_index:%d num_segments:%d\n",
           __FUNCTION__,
-          NFAPI_SFNSF2SFN(req->sfn_sf), NFAPI_SFNSF2SF(req->sfn_sf),
+          NFAPI_SFNSF2SFN(req->sfn_sf),
+          NFAPI_SFNSF2SF(req->sfn_sf),
           req->tx_request_body.number_of_pdus,
           i,
           req->tx_request_body.tx_pdu_list[i].pdu_length,
           req->tx_request_body.tx_pdu_list[i].pdu_index,
-          req->tx_request_body.tx_pdu_list[i].num_segments
-          );
-
-    }
+          req->tx_request_body.tx_pdu_list[i].num_segments);
+  }
 
   return 0;
 }
 
-
 int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) {
   int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
@@ -774,271 +838,272 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) {
   return 0;
 }
 
+int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t *req, module_id_t Mod_id) {
+  if (req != NULL && req->hi_dci0_request_body.hi_dci0_pdu_list != NULL) {
+    LOG_D(PHY,
+          "[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d "
+          "number_of_hi:%d\n",
+          NFAPI_SFNSF2DEC(req->sfn_sf),
+          req->hi_dci0_request_body.number_of_dci,
+          req->hi_dci0_request_body.number_of_hi);
 
-int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id)
-{
-	if (req!=NULL && req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
-  LOG_D(PHY,"[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
-
-
-
-  for (int i=0; ihi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++)
-  {
-    LOG_D(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
-
-    if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE)
-    {
+    for (int i = 0; i < req->hi_dci0_request_body.number_of_dci
+                            + req->hi_dci0_request_body.number_of_hi;
+         i++) {
       LOG_D(PHY,
-            "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - "
-            "NFAPI_HI_DCI0_DCI_PDU_TYPE\n",
+            "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n",
             NFAPI_SFNSF2DEC(req->sfn_sf),
             i);
-      const nfapi_hi_dci0_dci_pdu_rel8_t *dci = &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8;
-      if (dci->rnti != UE_mac_inst[Mod_id].crnti)
-        continue;
-      const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
-      const int sf = NFAPI_SFNSF2SF(req->sfn_sf);
-      if (dci->cqi_csi_request)
-        fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti);
-    }
-    else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE)
-    {
-      //LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
 
-      nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i];
+      if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type
+          == NFAPI_HI_DCI0_DCI_PDU_TYPE) {
+        LOG_D(PHY,
+              "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - "
+              "NFAPI_HI_DCI0_DCI_PDU_TYPE\n",
+              NFAPI_SFNSF2DEC(req->sfn_sf),
+              i);
+        const nfapi_hi_dci0_dci_pdu_rel8_t *dci =
+            &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8;
+        if (dci->rnti != UE_mac_inst[Mod_id].crnti)
+          continue;
+        const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
+        const int sf = NFAPI_SFNSF2SF(req->sfn_sf);
+        if (dci->cqi_csi_request)
+          fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti);
+      } else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type
+                 == NFAPI_HI_DCI0_HI_PDU_TYPE) {
+        nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu =
+            &req->hi_dci0_request_body.hi_dci0_pdu_list[i];
 
-      // This is meaningful only after ACKnowledging the first ULSCH Txon (i.e. Msg3)
-      if(hi_dci0_req_pdu->hi_pdu.hi_pdu_rel8.hi_value == 1 && UE_mac_inst[Mod_id].first_ULSCH_Tx == 1){
-    	  //LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ 2 sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
-    	  //UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
-    	  //UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+        // This is meaningful only after ACKnowledging the first ULSCH Txon
+        // (i.e. Msg3)
+        if (hi_dci0_req_pdu->hi_pdu.hi_pdu_rel8.hi_value == 1
+            && UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) {
+          // LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ 2 sfn_sf:%d PDU[%d] -
+          // NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
+          // UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
+          // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
+        }
+
+      } else {
+        LOG_E(PHY,
+              "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu "
+              "type:%d\n",
+              NFAPI_SFNSF2DEC(req->sfn_sf),
+              i,
+              req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type);
       }
-
-    }
-    else
-    {
-      LOG_E(PHY,"[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type);
     }
   }
 
-  }
-
-
   return 0;
 }
 
+// The following set of memcpy functions should be getting called as callback
+// functions from pnf_p7_subframe_ind.
+int memcpy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7,
+                         nfapi_dl_config_request_t *req) {
+  dl_config_req = (nfapi_dl_config_request_t *)malloc(sizeof(nfapi_dl_config_request_t));
 
+  // UE_mac_inst[Mod_id].dl_config_req->header = req->header;
+  dl_config_req->sfn_sf = req->sfn_sf;
 
+  dl_config_req->vendor_extension = req->vendor_extension;
 
+  dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci;
+  dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
+  dl_config_req->dl_config_request_body.number_pdsch_rnti = req->dl_config_request_body.number_pdsch_rnti;
+  dl_config_req->dl_config_request_body.number_pdu = req->dl_config_request_body.number_pdu;
 
-// The following set of memcpy functions should be getting called as callback functions from
-// pnf_p7_subframe_ind.
-int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req)
-{
+  dl_config_req->dl_config_request_body.tl.tag = req->dl_config_request_body.tl.tag;
+  dl_config_req->dl_config_request_body.tl.length = req->dl_config_request_body.tl.length;
 
-	//for (Mod_id=0; Mod_idheader = req->header;
-	dl_config_req->sfn_sf = req->sfn_sf;
-
-	dl_config_req->vendor_extension = req->vendor_extension;
-
-	dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci;
-	dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
-	dl_config_req->dl_config_request_body.number_pdsch_rnti = req->dl_config_request_body.number_pdsch_rnti;
-	dl_config_req->dl_config_request_body.number_pdu = req->dl_config_request_body.number_pdu;
-
-	dl_config_req->dl_config_request_body.tl.tag = req->dl_config_request_body.tl.tag;
-	dl_config_req->dl_config_request_body.tl.length = req->dl_config_request_body.tl.length;
-
-	dl_config_req->dl_config_request_body.dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*) calloc(req->dl_config_request_body.number_pdu, sizeof(nfapi_dl_config_request_pdu_t));
-	for(int i=0; idl_config_request_body.number_pdu; i++) {
-		dl_config_req->dl_config_request_body.dl_config_pdu_list[i] = req->dl_config_request_body.dl_config_pdu_list[i];
-	}
-
-	//}
-
-	return 0;
+  dl_config_req->dl_config_request_body.dl_config_pdu_list =
+      calloc(req->dl_config_request_body.number_pdu,
+             sizeof(nfapi_dl_config_request_pdu_t));
+  for (int i = 0; i < dl_config_req->dl_config_request_body.number_pdu; i++) {
+    dl_config_req->dl_config_request_body.dl_config_pdu_list[i] =
+        req->dl_config_request_body.dl_config_pdu_list[i];
+  }
 
+  return 0;
 }
 
-int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req)
-{
+int memcpy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7,
+                         nfapi_ul_config_request_t *req) {
+  ul_config_req = malloc(sizeof(nfapi_ul_config_request_t));
 
-	//for (Mod_id=0; Mod_idsfn_sf = req->sfn_sf;
+  ul_config_req->vendor_extension = req->vendor_extension;
 
-		ul_config_req = (nfapi_ul_config_request_t*)malloc(sizeof(nfapi_ul_config_request_t));
+  ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus;
+  ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources;
+  ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present;
 
-	ul_config_req->sfn_sf = req->sfn_sf;
-	ul_config_req->vendor_extension = req->vendor_extension;
+  ul_config_req->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag;
+  ul_config_req->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length;
 
+  ul_config_req->ul_config_request_body.ul_config_pdu_list =
+      calloc(req->ul_config_request_body.number_of_pdus,
+             sizeof(nfapi_ul_config_request_pdu_t));
+  for (int i = 0; i < ul_config_req->ul_config_request_body.number_of_pdus; i++) {
+    ul_config_req->ul_config_request_body.ul_config_pdu_list[i] =
+        req->ul_config_request_body.ul_config_pdu_list[i];
+  }
 
-	ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus;
-	ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources;
-	ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present;
-
-	ul_config_req->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag;
-	ul_config_req->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length;
-
-	//LOG_D(MAC, "memcpy_ul_config_req 1 #ofULPDUs: %d \n", UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.number_of_pdus); //req->ul_config_request_body.number_of_pdus);
-	ul_config_req->ul_config_request_body.ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*) malloc(req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
-	for(int i=0; iul_config_request_body.number_of_pdus; i++) {
-			ul_config_req->ul_config_request_body.ul_config_pdu_list[i] = req->ul_config_request_body.ul_config_pdu_list[i];
-		}
-	//}
-
-	return 0;
+  return 0;
 }
 
+int memcpy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
+  tx_req_num_elems = req->tx_request_body.number_of_pdus;
+  tx_request_pdu_list = calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t));
+  for (int i = 0; i < tx_req_num_elems; i++) {
+    tx_request_pdu_list[i].num_segments = req->tx_request_body.tx_pdu_list[i].num_segments;
+    tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index;
+    tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length;
+    for (int j = 0; j < req->tx_request_body.tx_pdu_list[i].num_segments; j++) {
+      tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length;
+      if (tx_request_pdu_list[i].segments[j].segment_length > 0) {
+        tx_request_pdu_list[i].segments[j].segment_data = calloc(
+            tx_request_pdu_list[i].segments[j].segment_length, sizeof(uint8_t));
+        memcpy(tx_request_pdu_list[i].segments[j].segment_data,
+               req->tx_request_body.tx_pdu_list[i].segments[j].segment_data,
+               tx_request_pdu_list[i].segments[j].segment_length);
+      }
+    }
+  }
 
-
-
-int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
-{
-
-	tx_req_num_elems = req->tx_request_body.number_of_pdus;
-	tx_request_pdu_list = (nfapi_tx_request_pdu_t*) calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t));
-	for (int i=0; itx_request_body.tx_pdu_list[i].num_segments;
-		tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index;
-		tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length;
-		for (int j=0; jtx_request_body.tx_pdu_list[i].num_segments; j++){
-			//*tx_request_pdu_list[i].segments[j].segment_data = *req->tx_request_body.tx_pdu_list[i].segments[j].segment_data;
-			tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length;
-			if(tx_request_pdu_list[i].segments[j].segment_length > 0){
-				tx_request_pdu_list[i].segments[j].segment_data = (uint8_t*)malloc(tx_request_pdu_list[i].segments[j].segment_length*sizeof (uint8_t));
-			memcpy(tx_request_pdu_list[i].segments[j].segment_data, req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, tx_request_pdu_list[i].segments[j].segment_length);
-			}
-		}
-
-	}
-
-	return 0;
+  return 0;
 }
 
-int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req)
-{
+int memcpy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7,
+                       nfapi_hi_dci0_request_t *req) {
+  hi_dci0_req = (nfapi_hi_dci0_request_t *)malloc(sizeof(nfapi_hi_dci0_request_t));
 
-	//if(req!=0){
+  hi_dci0_req->sfn_sf = req->sfn_sf;
+  hi_dci0_req->vendor_extension = req->vendor_extension;
 
-	//for (Mod_id=0; Mod_idhi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci;
+  hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi;
+  hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf;
 
-	hi_dci0_req->sfn_sf = req->sfn_sf;
-	hi_dci0_req->vendor_extension = req->vendor_extension;
+  // UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl =
+  // req->hi_dci0_request_body.tl;
+  hi_dci0_req->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag;
+  hi_dci0_req->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length;
 
-	hi_dci0_req->hi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci;
-	hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi;
-	hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf;
+  int total_pdus = hi_dci0_req->hi_dci0_request_body.number_of_dci
+                   + hi_dci0_req->hi_dci0_request_body.number_of_hi;
 
-	//UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl = req->hi_dci0_request_body.tl;
-	hi_dci0_req->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag;
-	hi_dci0_req->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length;
+  hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list =
+      calloc(total_pdus, sizeof(nfapi_hi_dci0_request_pdu_t));
 
-	int total_pdus = hi_dci0_req->hi_dci0_request_body.number_of_dci + hi_dci0_req->hi_dci0_request_body.number_of_hi;
-
-	hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*) malloc(total_pdus*sizeof(nfapi_hi_dci0_request_pdu_t));
-
-	for(int i=0; ihi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i];
-		//LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type, UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type);
-	}
-
-	//}
-		return 0;
+  for (int i = 0; i < total_pdus; i++) {
+    hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i];
+    // LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d
+    // \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type,
+    // UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type);
+  }
+  return 0;
 }
 
-
-
 void UE_config_stub_pnf(void) {
-  int               j;
+  int j;
   paramdef_t L1_Params[] = L1PARAMS_DESC;
-  paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
+  paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST, NULL, 0};
 
-  config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL);
+  config_getlist(&L1_ParamList, L1_Params, sizeof(L1_Params) / sizeof(paramdef_t), NULL);
   if (L1_ParamList.numelt > 0) {
-	  for (j=0; j
Date: Fri, 6 Mar 2020 15:15:02 +0100
Subject: [PATCH 314/343] CI: adding back more testing (ping and iperf) to L2
 simulator

Signed-off-by: Raphael Defosseux 
---
 ci-scripts/runTestOnVM.sh | 86 ++++++++++++++++++++++++++++++++-------
 1 file changed, 72 insertions(+), 14 deletions(-)

diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 4e1734da63..09859133cc 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -613,8 +613,11 @@ function start_epc {
         echo "############################################################"
         echo "echo \"cd /opt/hss_sim0609\"" > $LOC_EPC_VM_CMDS
         echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
-        echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS
-        echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS
+        echo "sudo rm -f hss.log" >> $LOC_EPC_VM_CMDS
+        #echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS
+        #echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS
+        echo "echo \"screen -dm -S simulated_hss ./starthss_real\"" >> $LOC_EPC_VM_CMDS
+        echo "sudo su -c \"screen -dm -S simulated_hss ./starthss_real\"" >> $LOC_EPC_VM_CMDS
 
         echo "echo \"cd /opt/ltebox/tools/\"" >> $LOC_EPC_VM_CMDS
         echo "cd /opt/ltebox/tools/" >> $LOC_EPC_VM_CMDS
@@ -905,8 +908,9 @@ function start_l2_sim_ue {
     else
         echo "L2-SIM UE is sync'ed w/ eNB"
     fi
-    local max_interfaces_to_check=1
-    if [ $LOC_S1_CONFIGURATION -eq 0 ]; then max_interfaces_to_check=$LOC_NB_UES; fi
+    local max_interfaces_to_check=$LOC_NB_UES
+    #local max_interfaces_to_check=1
+    #if [ $LOC_S1_CONFIGURATION -eq 0 ]; then max_interfaces_to_check=$LOC_NB_UES; fi
     local j="1"
     while [ $j -le $max_interfaces_to_check ]
     do
@@ -2214,15 +2218,41 @@ function run_test_on_vm {
 
                 if [ $S1_NOS1_CFG -eq 1 ]
                 then
-                    get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1
 
                     echo "############################################################"
                     echo "${CN_CONFIG} : Pinging the EPC from UE(s)"
                     echo "############################################################"
-                    PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc.log
-                    ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE 1 0
-                    scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
-                    check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+                    echo " --- Sequentially ---"
+                    local j="1"
+                    while [ $j -le $INT_NB_UES ]
+                    do
+                        PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc_seq_from_ue${j}.log
+                        ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE ${j} 0
+                        scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+                        check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+                        j=$[$j+1]
+                    done
+                    if [ $INT_NB_UES -gt 1 ]
+                    then
+                        echo " --- In parallel ---"
+                        j="1"
+                        while [ $j -le $INT_NB_UES ]
+                        do
+                            PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc_para_from_ue${j}.log
+                            ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE ${j} 1
+                            j=$[$j+1]
+                        done
+                        sleep 25
+                        j="1"
+                        while [ $j -le $INT_NB_UES ]
+                        do
+                            PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc_para_from_ue${j}.log
+                            scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+                            tail -3 $ARCHIVES_LOC/$PING_LOG_FILE
+                            check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+                            j=$[$j+1]
+                        done
+                    fi
                 else
                     get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR
 
@@ -2267,10 +2297,38 @@ function run_test_on_vm {
                     echo "############################################################"
                     echo "${CN_CONFIG} : Pinging the UE(s) from EPC"
                     echo "############################################################"
-                    PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_ue.log
-                    ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0
-                    scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
-                    check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+                    echo " --- Sequentially ---"
+                    local j="1"
+                    while [ $j -le $INT_NB_UES ]
+                    do
+                        get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j
+                        PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_epc_seq_ue${j}.log
+                        ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0
+                        scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+                        check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+                        j=$[$j+1]
+                    done
+                    if [ $INT_NB_UES -gt 1 ]
+                    then
+                        echo " --- In parallel ---"
+                        j="1"
+                        while [ $j -le $INT_NB_UES ]
+                        do
+                            get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j
+                            PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_epc_para_ue${j}.log
+                            ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 1
+                            j=$[$j+1]
+                        done
+                        sleep 25
+                        j="1"
+                        while [ $j -le $INT_NB_UES ]
+                        do
+                            PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_epc_para_ue${j}.log
+                            scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+                            check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+                            j=$[$j+1]
+                        done
+                    fi
                 else
                     echo "############################################################"
                     echo "${CN_CONFIG} : Pinging the UE(s) from eNB"
@@ -2310,7 +2368,7 @@ function run_test_on_vm {
                     fi
                 fi
 
-                if [ $S1_NOS1_CFG -eq 2 ]
+                if [ $S1_NOS1_CFG -eq 0 ]
                 then
                     get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR
                     echo "############################################################"

From c6182d3ee29af828deefa4aceb454dda6b21b99a Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Tue, 10 Mar 2020 12:26:00 +0100
Subject: [PATCH 315/343] updated frame_idx in UE

---
 executables/nr-ue.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 67f6169868..f73807bdf2 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -665,6 +665,7 @@ void *UE_thread(void *arg) {
   int thread_idx=0;
   notifiedFIFO_t freeBlocks;
   initNotifiedFIFO_nothreadSafe(&freeBlocks);
+  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
 
   for (int i=0; imsgData;
 
         if (tmp->proc.decoded_frame_rx != -1)
-          decoded_frame_rx=tmp->proc.decoded_frame_rx;
+          decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+          //decoded_frame_rx=tmp->proc.decoded_frame_rx;
 
         pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
       }
@@ -851,7 +853,8 @@ void *UE_thread(void *arg) {
       processingData_t *tmp=(processingData_t *)res->msgData;
 
       if (tmp->proc.decoded_frame_rx != -1)
-        decoded_frame_rx=tmp->proc.decoded_frame_rx;
+        decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+        //decoded_frame_rx=tmp->proc.decoded_frame_rx;
 
       pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
     }

From 0de3c7347527fcf28712a4cbf0277da35b4104f3 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Mon, 9 Mar 2020 14:25:19 +0100
Subject: [PATCH 316/343] Place MBMS tun fd into single int

---
 .../SIMULATION/ETH_TRANSPORT/netlink_init.c   | 20 +++++++++----------
 openair1/SIMULATION/ETH_TRANSPORT/proto.h     |  2 +-
 openair2/LAYER2/PDCP_v10.1.0/pdcp.c           |  6 +++---
 openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c      |  6 +++---
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c
index dfb5578ba6..9b4aba46c3 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c
+++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c
@@ -58,7 +58,7 @@ 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];
+int nas_sock_mbms_fd;
 
 struct msghdr nas_msg_tx;
 struct msghdr nas_msg_rx;
@@ -95,21 +95,20 @@ static int tun_alloc(char *dev) {
 }
 
 
-int netlink_init_mbms_tun(char *ifprefix, int num_if) {
+int netlink_init_mbms_tun(char *ifprefix) {
   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);
+    sprintf(ifname, "oaitun_%.3s1",ifprefix); // added "1": for historical reasons
+    nas_sock_mbms_fd = tun_alloc(ifname);
 
-    if (nas_sock_mbms_fd[i] == -1) {
+    if (nas_sock_mbms_fd == -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);
+    printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd);
+    ret = fcntl(nas_sock_mbms_fd,F_SETFL,O_NONBLOCK);
 
     if (ret == -1) {
       printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno));
@@ -123,7 +122,7 @@ int netlink_init_mbms_tun(char *ifprefix, int num_if) {
     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));
+    ret = bind(nas_sock_mbms_fd, (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 */
@@ -165,7 +164,8 @@ int netlink_init_tun(char *ifprefix, int num_if) {
       exit(1);
     }
 
-    printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_fd[i]);
+    printf("[NETLINK]Opened socket %s with fd nas_sock_fd[%d]=%d\n",
+           ifname, i, nas_sock_fd[i]);
     ret = fcntl(nas_sock_fd[i],F_SETFL,O_NONBLOCK);
 
     if (ret == -1) {
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h
index 02f7925d93..e6159199d4 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h
+++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h
@@ -63,6 +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);
+int netlink_init_mbms_tun(char *ifsuffix);
 
 #endif /* EMU_PROTO_H_ */
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 254d741ae8..b0e6143de1 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -2299,14 +2299,14 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
       netlink_init_tun("ue",num_if);
       if (IS_SOFTMODEM_NOS1)
     	  nas_config(1, 1, 2, "ue");
-      netlink_init_mbms_tun("uem",num_if);
+      netlink_init_mbms_tun("uem");
       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");
       if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
-      	netlink_init_mbms_tun("enm",1);
+        netlink_init_mbms_tun("enm");
       	nas_config_mbms(1, 2, 1, "enm"); 
       	LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
       }
@@ -2318,7 +2318,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
   }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);
+            netlink_init_mbms_tun("enm");
              nas_config_mbms_s1(1, 2, 1, "enm"); 
          }else
              LOG_E(PDCP, "ENB pdcp will not use tun interface\n");
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index a441ff220e..d203408e55 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -77,7 +77,7 @@ extern struct iovec nas_iov_rx;
 
 extern int nas_sock_fd[MAX_MOBILES_PER_ENB];
 
-extern int nas_sock_mbms_fd[8];
+extern int nas_sock_mbms_fd;
 
 extern int mbms_rab_id;
 
@@ -133,7 +133,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const  ctxt_pP) {
     } 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 );
        if(rb_id == mbms_rab_id){
-       ret = write(nas_sock_mbms_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
+       ret = write(nas_sock_mbms_fd, &(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
@@ -299,7 +299,7 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const  ctxt_p
   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);
+    len = read(nas_sock_mbms_fd, &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;

From 8928cfe57d9f7100c7902a44a6fa853cc24543c5 Mon Sep 17 00:00:00 2001
From: frtabu 
Date: Wed, 11 Mar 2020 17:32:13 +0100
Subject: [PATCH 317/343] move ldpc coder/decoder into a shared lib dymically
 loaded. Also fix a record player bug

---
 cmake_targets/CMakeLists.txt                  |  39 +-
 common/config/config_userapi.c                |   3 +-
 common/utils/telnetsrv/telnetsrv.c            |  20 +-
 openair1/PHY/CODING/TESTBENCH/ldpctest.c      |  22 +-
 .../CODING/nrLDPC_decoder/nrLDPC_decoder.c    |   4 +-
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_init.h   |   2 +-
 .../CODING/nrLDPC_decoder/nrLDPC_init_mem.h   |   1 -
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h  |   2 +-
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_types.h  |   5 +-
 .../{nrLDPC_defs.h => nrLDPCdecoder_defs.h}   |   2 +-
 openair1/PHY/CODING/nrLDPC_defs.h             |  59 ++
 openair1/PHY/CODING/nrLDPC_encoder/defs.h     |  54 --
 .../nrLDPC_encoder/ldpc_encode_parity_check.c | 201 ++++++
 .../PHY/CODING/nrLDPC_encoder/ldpc_encoder.c  | 252 +++++--
 .../PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c | 667 ------------------
 .../nrLDPC_encoder/ldpc_encoder_optim.c       | 146 ++++
 .../ldpc_generate_coefficient.c               | 244 +------
 .../nrLDPC_decoder.h => nrLDPC_extern.h}      |  39 +-
 openair1/PHY/CODING/nrLDPC_load.c             |  76 ++
 openair1/PHY/INIT/nr_init.c                   |   2 +
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c   |   9 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |   3 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |   3 +-
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |   7 +-
 openair1/PHY/defs_gNB.h                       |   2 +-
 targets/ARCH/COMMON/common_lib.c              |  35 +-
 targets/ARCH/COMMON/common_lib.h              |  18 +
 targets/ARCH/COMMON/record_player.h           |  15 +-
 targets/ARCH/iqplayer/iqplayer_lib.c          |  14 +-
 targets/RT/USER/lte-ru.c                      |   4 +-
 30 files changed, 888 insertions(+), 1062 deletions(-)
 rename openair1/PHY/CODING/nrLDPC_decoder/{nrLDPC_defs.h => nrLDPCdecoder_defs.h} (99%)
 create mode 100644 openair1/PHY/CODING/nrLDPC_defs.h
 delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/defs.h
 create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c
 delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
 create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
 rename openair1/PHY/CODING/{nrLDPC_decoder/nrLDPC_decoder.h => nrLDPC_extern.h} (60%)
 create mode 100644 openair1/PHY/CODING/nrLDPC_load.c

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index c4d3d7e62e..496417936a 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1298,14 +1298,35 @@ set(PHY_SMALLBLOCKSRC
 set(PHY_TURBOIF
   ${OPENAIR1_DIR}/PHY/CODING/coding_load.c
 )
-set(PHY_LDPCSRC
+
+set(PHY_LDPC_ORIG_SRC
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
-  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
-  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
 )
 
+set(PHY_LDPC_OPTIM_SRC
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
+)
+set(PHY_LDPC_OPTIM8SEG_SRC
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c
+)
+set(PHY_LDPC_OPTIM8SEGMULTI_SRC
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
+)
+set(PHY_NR_CODINGIF
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c;
+)
+
+add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} )
+add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} )
+add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} )
+add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
+
 add_library(coding MODULE ${PHY_TURBOSRC} )
+
 set(PHY_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
@@ -1484,10 +1505,9 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/TOOLS/lut.c
   ${PHY_POLARSRC}
   ${PHY_SMALLBLOCKSRC}
-  ${PHY_LDPCSRC}
+  ${PHY_NR_CODINGIF}
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c 
   )
-
   set(PHY_NR_UE_SRC
   ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
   ${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c
@@ -1535,7 +1555,7 @@ set(PHY_SRC_UE
   #  ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
   ${PHY_POLARSRC}
   ${PHY_SMALLBLOCKSRC}
-  ${PHY_LDPCSRC}
+  ${PHY_NR_CODINGIF}
   )
 
 
@@ -2588,7 +2608,7 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LI
 target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES})
 target_link_libraries (nr-softmodem ${T_LIB})
 
-
+add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
 # nr-uesoftmodem is  UE implementation
 #######################################
 
@@ -2629,7 +2649,7 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_
 target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES})
 target_link_libraries (nr-uesoftmodem ${T_LIB})
 
-
+add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
 
 # USIM process
 #################
@@ -2696,10 +2716,13 @@ target_link_libraries(smallblocktest
   )
 
 add_executable(ldpctest  
+  ${PHY_NR_CODINGIF}
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
   )
+add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) 
+
 target_link_libraries(ldpctest
   -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} dl
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index 67fdc2c920..c951905101 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -45,7 +45,8 @@
 
 configmodule_interface_t *config_get_if(void) {
   if (cfgptr == NULL) {
-    CONFIG_PRINTF_ERROR("[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__);
+  	if (isLogInitDone())
+       LOG_W(ENB_APP,"[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__);
   }
 
   return cfgptr;
diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c
index 10163b22b5..06a5d350c7 100644
--- a/common/utils/telnetsrv/telnetsrv.c
+++ b/common/utils/telnetsrv/telnetsrv.c
@@ -377,6 +377,14 @@ int setgetvar(int moduleindex,char getorset,char *params) {
             client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
             break;
 
+          case TELNET_VARTYPE_INT8:
+            client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));
+            break;
+            
+          case TELNET_VARTYPE_UINT:
+            client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+            break;
+            
           case TELNET_VARTYPE_DOUBLE:
             client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
             break;
@@ -405,7 +413,17 @@ int setgetvar(int moduleindex,char getorset,char *params) {
             *(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0);
             client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
             break;
-
+            
+          case TELNET_VARTYPE_INT8:
+            *(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0);
+            client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+            break;
+            
+          case TELNET_VARTYPE_UINT:
+            *(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0);
+            client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+            break;
+ 
           case TELNET_VARTYPE_DOUBLE:
             *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
             client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index 95ee3fed17..552af99c41 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -25,8 +25,7 @@
 #include 
 #include "assertions.h"
 #include "SIMULATION/TOOLS/sim.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
 
 #define MAX_NUM_DLSCH_SEGMENTS 16
@@ -85,6 +84,7 @@ typedef struct {
 RAN_CONTEXT_t RC;
 PHY_VARS_UE ***PHY_vars_UE_g;
 uint16_t NB_UE_INST = 1;
+nrLDPC_encoderfunc_t encoder_orig;
 
 short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
 
@@ -286,16 +286,19 @@ int test_ldpc(short No_iteration,
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
   //  printf("puncture:%d\n",no_punctured_columns);
   removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
+  encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS;
+ 
+  impp.gen_code=1;
   if (ntrials==0)
-    ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1);
-
+    encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp);
+  impp.gen_code=0;
   for (trial=0; trial < ntrials; trial++)
   {
 	segment_bler = 0;
     //// encoder
     start_meas(&time);
     for(j=0;j
 #include 
-#include "nrLDPC_defs.h"
+#include "nrLDPCdecoder_defs.h"
 #include "nrLDPC_types.h"
 #include "nrLDPC_init.h"
 #include "nrLDPC_mPass.h"
@@ -47,7 +47,7 @@
 
 static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler);
 
-int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
+int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
 {
     uint32_t numLLR;
     uint32_t numIter = 0;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h
index 82462c6d95..ea031dc2da 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h
@@ -32,7 +32,7 @@
 #define __NR_LDPC_INIT__H__
 
 #include "nrLDPC_lut.h"
-#include "nrLDPC_defs.h"
+#include "nrLDPCdecoder_defs.h"
 
 /**
    \brief Initializes the decoder and sets correct LUTs
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
index bdaa118e1f..3292c0debe 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
@@ -32,7 +32,6 @@
 #define __NR_LDPC_INIT_MEM__H__
 
 #include 
-#include "nrLDPC_defs.h"
 #include "nrLDPC_types.h"
 
 #ifndef malloc32_clear
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
index 66715618d0..7d0f5f077a 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
@@ -32,7 +32,7 @@
 #define __NR_LDPC_MPASS__H__
 
 #include 
-#include "nrLDPC_defs.h"
+#include "nrLDPCdecoder_defs.h"
 
 /**
    \brief Circular memcpy
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
index 34322a7780..e5b99246d5 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
@@ -32,8 +32,7 @@
 #define __NR_LDPC_TYPES__H__
 
 #include "PHY/TOOLS/time_meas.h"
-#include "nrLDPC_defs.h"
-
+#include "nrLDPCdecoder_defs.h"
 // ==============================================================================
 // TYPES
 
@@ -103,4 +102,6 @@ typedef struct nrLDPC_procBuf {
     int8_t* llrProcBuf; /**< LLR processing buffer */
 } t_nrLDPC_procBuf;
 
+
+
 #endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
similarity index 99%
rename from openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h
rename to openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
index 940d842550..69fc88752f 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
@@ -19,7 +19,7 @@
  *      contact@openairinterface.org
  */
 
-/*!\file nrLDPC_defs.h
+/*!\file nrLDPCdecoder_defs.h
  * \brief Defines all constants and buffers for the LDPC decoder
  * \author Sebastian Wagner (TCL Communications) Email: 
  * \date 27-03-2018
diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h
new file mode 100644
index 0000000000..b96067f4b6
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_defs.h
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+//============================================================================================================================
+// encoder interface
+#ifndef __NRLDPC_DEFS__H__
+#define __NRLDPC_DEFS__H__
+#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+/**
+   \brief LDPC encoder
+   \param 1 input
+   \param 2 channel_input
+   \param 3 int Zc
+   \param 4 int Kb
+   \param 5 short block_length
+   \param 6 short BG
+   \param 7 int n_segment
+   \param 8 unsigned int macro_num
+   \param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput
+*/
+typedef struct {
+	int n_segments;          // optim8seg
+	unsigned int macro_num; // optim8segmulti
+	unsigned char gen_code; //orig
+	time_stats_t *tinput;
+	time_stats_t *tprep;
+	time_stats_t *tparity;
+	time_stats_t *toutput;
+}encoder_implemparams_t;
+#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL}
+typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*);
+//============================================================================================================================
+// decoder interface
+/**
+   \brief LDPC decoder API type definition
+   \param p_decParams LDPC decoder parameters
+   \param p_llr Input LLRs
+   \param p_llrOut Output vector
+   \param p_profiler LDPC profiler statistics
+*/
+typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
+#endif
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/defs.h b/openair1/PHY/CODING/nrLDPC_encoder/defs.h
deleted file mode 100644
index 85cb852fe5..0000000000
--- a/openair1/PHY/CODING/nrLDPC_encoder/defs.h
+++ /dev/null
@@ -1,54 +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 defs.h
- * \brief LDPC encoder forward declarations
- * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
- * \email openair_tech@eurecom.fr
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#include "PHY/TOOLS/time_meas.h"
-
-/*ldpc_encoder.c*/
-int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length);
-
-/*ldpc_encoder2.c*/
-void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb);
-int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-
-/*ldpc_generate_coefficient.c*/
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,unsigned char gen_code);
-
-/*
-int encode_parity_check_part(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb);
-int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length);
-int ldpc_encoder(unsigned char *test_input,unsigned char *channel_input,short block_length, double rate);
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,unsigned char gen_code);
-int ldpc_encoder_multi_segment(unsigned char **test_input,unsigned char **channel_input,short block_length,double rate,uint8_t n_segments);
-int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,int nom_rate,int denom_rate,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-*/
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c
new file mode 100644
index 0000000000..738fd49b7d
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c
@@ -0,0 +1,201 @@
+/*
+ * 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 ldpc_encode_parity_check.c
+ * \brief Parity check function used by ldpc encoders
+ * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
+ * \email openair_tech@eurecom.fr
+ * \date 27-03-2018
+ * \version 1.0
+ * \note
+ * \warning
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+
+
+//#define DEBUG_LDPC
+
+#include "ldpc384_byte.c"
+#include "ldpc352_byte.c"
+#include "ldpc320_byte.c"
+#include "ldpc288_byte.c"
+#include "ldpc256_byte.c"
+#include "ldpc240_byte.c"
+#include "ldpc224_byte.c"
+#include "ldpc208_byte.c"
+#include "ldpc192_byte.c"
+#include "ldpc176_byte.c"
+#include "ldpc_BG2_Zc384_byte.c"
+#include "ldpc_BG2_Zc352_byte.c"
+#include "ldpc_BG2_Zc320_byte.c"
+#include "ldpc_BG2_Zc288_byte.c"
+#include "ldpc_BG2_Zc256_byte.c"
+#include "ldpc_BG2_Zc240_byte.c"
+#include "ldpc_BG2_Zc224_byte.c"
+#include "ldpc_BG2_Zc208_byte.c"
+#include "ldpc_BG2_Zc192_byte.c"
+#include "ldpc_BG2_Zc176_byte.c"
+#include "ldpc_BG2_Zc160_byte.c"
+#include "ldpc_BG2_Zc144_byte.c"
+#include "ldpc_BG2_Zc128_byte.c"
+#include "ldpc_BG2_Zc120_byte.c"
+#include "ldpc_BG2_Zc112_byte.c"
+#include "ldpc_BG2_Zc104_byte.c"
+#include "ldpc_BG2_Zc96_byte.c"
+#include "ldpc_BG2_Zc88_byte.c"
+#include "ldpc_BG2_Zc80_byte.c"
+#include "ldpc_BG2_Zc72_byte.c"
+
+
+
+static inline void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb)
+{
+
+  if (BG==1)
+  {
+    switch (Zc)
+    {
+    case 2: break;
+    case 3: break;
+    case 4: break;
+    case 5: break;
+    case 6: break;
+    case 7: break;
+    case 8: break;
+    case 9: break;
+    case 10: break;
+    case 11: break;
+    case 12: break;
+    case 13: break;
+    case 14: break;
+    case 15: break;
+    case 16: break;
+    case 18: break;
+    case 20: break;
+    case 22: break;
+    case 24: break;      
+    case 26: break;
+    case 28: break;
+    case 30: break;
+    case 32: break;
+    case 36: break;
+    case 40: break;
+    case 44: break;
+    case 48: break;
+    case 52: break;
+    case 56: break;
+    case 60: break;
+    case 64: break;
+    case 72: break;
+    case 80: break;   
+    case 88: break;   
+    case 96: break;
+    case 104: break;
+    case 112: break;
+    case 120: break;
+    case 128: break;
+    case 144: break;
+    case 160: break;
+    case 176: ldpc176_byte(c,d); break;
+    case 192: ldpc192_byte(c,d); break;
+    case 208: ldpc208_byte(c,d); break;
+    case 224: ldpc224_byte(c,d); break;
+    case 240: ldpc240_byte(c,d); break;
+    case 256: ldpc256_byte(c,d); break;
+    case 288: ldpc288_byte(c,d); break;
+    case 320: ldpc320_byte(c,d); break;
+    case 352: ldpc352_byte(c,d); break;
+    case 384: ldpc384_byte(c,d); break;
+    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
+    }
+  }
+  else if (BG==2) {
+    switch (Zc)
+    {
+    case 2: break;
+    case 3: break;
+    case 4: break;
+    case 5: break;
+    case 6: break;
+    case 7: break;
+    case 8: break;
+    case 9: break;
+    case 10: break;
+    case 11: break;
+    case 12: break;
+    case 13: break;
+    case 14: break;
+    case 15: break;
+    case 16: break;
+    case 18: break;
+    case 20: break;
+    case 22: break;
+    case 24: break;      
+    case 26: break;
+    case 28: break;
+    case 30: break;
+    case 32: break;
+    case 36: break;
+    case 40: break;
+    case 44: break;
+    case 48: break;
+    case 52: break;
+    case 56: break;
+    case 60: break;
+    case 64: break;
+    case 72: ldpc_BG2_Zc72_byte(c,d); break;
+    case 80: ldpc_BG2_Zc80_byte(c,d); break;   
+    case 88: ldpc_BG2_Zc88_byte(c,d); break;   
+    case 96: ldpc_BG2_Zc96_byte(c,d); break;
+    case 104: ldpc_BG2_Zc104_byte(c,d); break;
+    case 112: ldpc_BG2_Zc112_byte(c,d); break;
+    case 120: ldpc_BG2_Zc120_byte(c,d); break;
+    case 128: ldpc_BG2_Zc128_byte(c,d); break;
+    case 144: ldpc_BG2_Zc144_byte(c,d); break;
+    case 160: ldpc_BG2_Zc160_byte(c,d); break;
+    case 176: ldpc_BG2_Zc176_byte(c,d); break;
+    case 192: ldpc_BG2_Zc192_byte(c,d); break;
+    case 208: ldpc_BG2_Zc208_byte(c,d); break;
+    case 224: ldpc_BG2_Zc224_byte(c,d); break;
+    case 240: ldpc_BG2_Zc240_byte(c,d); break;
+    case 256: ldpc_BG2_Zc256_byte(c,d); break;
+    case 288: ldpc_BG2_Zc288_byte(c,d); break;
+    case 320: ldpc_BG2_Zc320_byte(c,d); break;
+    case 352: ldpc_BG2_Zc352_byte(c,d); break;
+    case 384: ldpc_BG2_Zc384_byte(c,d); break;
+    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
+    }
+  }
+  else {
+    AssertFatal(0,"BG %d is not supported yet\n",BG);
+  } 
+
+}
+
+
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
index 6ded22d8ca..76f92574ba 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
@@ -37,77 +37,247 @@
 #include 
 #include 
 #include "defs.h"
+#include "assertions.h"
+#include "openair1/PHY/CODING/nrLDPC_defs.h"
+#include "ldpc_generate_coefficient.c"
 
-short *choose_generator_matrix(short BG,short Zc);
-extern short no_shift_values_BG1[1012],pointer_shift_values_BG1[1012],no_shift_values_BG2[2109],pointer_shift_values_BG2[2019];
 
-int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length)
+int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code)
 {
-  short *Gen_shift_values=choose_generator_matrix(BG,Zc);
-  short *no_shift_values, *pointer_shift_values;
-  int no_punctured_columns;
-  short nrows,ncols,rate=3;
-  int i1,i2,i3,i4,i5,temp_prime;
+  unsigned char c[22*384]; //padded input, unpacked, max size
+  unsigned char d[68*384]; //coded output, unpacked, max size
   unsigned char channel_temp,temp;
+  short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
 
+  short nrows = 46;//parity check bits
+  short ncols = 22;//info bits
+
+
+  int i,i1,i2,i3,i4,i5,temp_prime,var;
+  int no_punctured_columns,removed_bit,rate=3;
+  int nind=0;
+  int indlist[1000];
+  int indlist2[1000];
+
+  //determine number of bits in codeword
+  //if (block_length>3840)
+     if (BG==1)
+       {
+         nrows=46; //parity check bits
+         ncols=22; //info bits
+         rate=3;
+       }
+       //else if (block_length<=3840)
+      else if	(BG==2)
+       {
+         //BG=2;
+         nrows=42; //parity check bits
+         ncols=10; // info bits
+         rate=5;
+         }
+
+  Gen_shift_values=choose_generator_matrix(BG,Zc);
+  if (Gen_shift_values==NULL) {
+    printf("ldpc_encoder_orig: could not find generator matrix\n");
+    return(-1);
+  }
+
+  //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb);
+
+  // load base graph of generator matrix
   if (BG==1)
   {
     no_shift_values=(short *) no_shift_values_BG1;
     pointer_shift_values=(short *) pointer_shift_values_BG1;
-      nrows=46; //parity check bits
-      ncols=22; //info bits
-      rate=3;
   }
   else if (BG==2)
   {
     no_shift_values=(short *) no_shift_values_BG2;
     pointer_shift_values=(short *) pointer_shift_values_BG2;
-      nrows=42; //parity check bits
-      ncols=10; //info bits
-      rate=5;
   }
   else {
-    printf("problem with BG\n");
-    return(-1);
+    AssertFatal(0,"BG %d is not supported yet\n",BG);
   }
-
-
+  
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate);
+  //printf("%d\n",no_punctured_columns);
+  //printf("%d\n",removed_bit);
+  // unpack input
+  memset(c,0,sizeof(unsigned char) * ncols * Zc);
+  memset(d,0,sizeof(unsigned char) * nrows * Zc);
 
-  //printf("no_punctured_columns = %d\n",no_punctured_columns);
-
-  for (i2=0; i2 < Zc; i2++)
+  for (i=0; i>7&1;
+    c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7));
+  }
 
-    //rotate matrix here
-    for (i5=0; i5 < Kb; i5++)
-    {
-      temp = c[i5*Zc];
-      memmove(&c[i5*Zc], &c[i5*Zc+1], (Zc-1)*sizeof(unsigned char));
-      c[i5*Zc+Zc-1] = temp;
+  // parity check part
+
+  if (gen_code==1)
+  {
+    char fname[100];
+    sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc);
+    FILE *fd=fopen(fname,"w");
+    AssertFatal(fd!=NULL,"cannot open %s\n",fname);
+    sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc);
+    FILE *fd2=fopen(fname,"w");
+    AssertFatal(fd2!=NULL,"cannot open %s\n",fname);
+
+    int shift;
+    char data_type[100];
+    char xor_command[100];
+    int mask;
+
+
+
+
+    fprintf(fd,"#include \"PHY/sse_intrin.h\"\n");
+    fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n");
+
+    if ((Zc&31)==0) {
+      shift=5; // AVX2 - 256-bit SIMD
+      mask=31;
+      strcpy(data_type,"__m256i");
+      strcpy(xor_command,"_mm256_xor_si256");
     }
+    else if ((Zc&15)==0) {
+      shift=4; // SSE4 - 128-bit SIMD
+      mask=15;
+      strcpy(data_type,"__m128i");
+      strcpy(xor_command,"_mm_xor_si128");
 
-    // calculate each row in base graph
-    for (i1=0; i1 < nrows-no_punctured_columns; i1++)
+    }
+    else if ((Zc&7)==0) {
+      shift=3; // MMX  - 64-bit SIMD
+      mask=7;
+      strcpy(data_type,"__m64");
+      strcpy(xor_command,"_mm_xor_si64"); 
+    }
+    else {
+      shift=0;                 // no SIMD
+      mask=0;
+      strcpy(data_type,"uint8_t");
+      strcpy(xor_command,"scalar_xor");
+      fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n");
+      fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n");
+    }
+    fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc);
+    fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc);
+    fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc);
+    fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc);
+    fprintf(fd,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
+    fprintf(fd2,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
+    fprintf(fd,"  %s *c2,*d2;\n\n",data_type);
+    fprintf(fd2,"  %s *c2,*d2;\n\n",data_type);
+    fprintf(fd,"  int i2;\n");
+    fprintf(fd2,"  int i2;\n");
+    fprintf(fd,"  for (i2=0; i2<%d; i2++) {\n",Zc>>shift);
+    if (shift > 0)
+      fprintf(fd2,"  for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1));
+    for (i2=0; i2 < 1; i2++)
     {
-      channel_temp=0;
-      for (i3=0; i3 < Kb; i3++)
-      {
-        temp_prime=i1 * ncols + i3;
+      //t=Kb*Zc+i2;
+    
+      // calculate each row in base graph
+     
 
-        for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
+      fprintf(fd,"     c2=&csimd[i2];\n");
+      fprintf(fd,"     d2=&dsimd[i2];\n");
+      fprintf(fd2,"     c2=&csimd[i2];\n");
+      fprintf(fd2,"     d2=&dsimd[i2];\n");
+
+      for (i1=0; i1 < nrows; i1++)
+
+      {
+        channel_temp=0;
+        fprintf(fd,"\n//row: %d\n",i1);
+        fprintf(fd2,"\n//row: %d\n",i1);
+	fprintf(fd,"     d2[%d]=",(Zc*i1)>>shift);
+	fprintf(fd2,"     d2[%d]=",(Zc*i1)>>(shift-1));
+
+        nind=0;
+
+        for (i3=0; i3 < ncols; i3++)
         {
-          channel_temp = channel_temp ^ c[ i3*Zc + Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ] ];
+          temp_prime=i1 * ncols + i3;
+
+
+	  for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
+	    {
+	          
+	      var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc);
+	      int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc;
+	      
+	      indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift);
+	      indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1));
+	      
+	    }
+	  
+
         }
+	for (i4=0;i4gen_code);
+}
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
deleted file mode 100644
index ef207b6cdc..0000000000
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
+++ /dev/null
@@ -1,667 +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 ldpc_encoder2.c
- * \brief Defines the optimized LDPC encoder
- * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
- * \email openair_tech@eurecom.fr
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "assertions.h"
-#include "common/utils/LOG/log.h"
-#include "PHY/TOOLS/time_meas.h"
-#include "defs.h"
-
-//#define DEBUG_LDPC
-
-#include "ldpc384_byte.c"
-#include "ldpc352_byte.c"
-#include "ldpc320_byte.c"
-#include "ldpc288_byte.c"
-#include "ldpc256_byte.c"
-#include "ldpc240_byte.c"
-#include "ldpc224_byte.c"
-#include "ldpc208_byte.c"
-#include "ldpc192_byte.c"
-#include "ldpc176_byte.c"
-#include "ldpc_BG2_Zc384_byte.c"
-#include "ldpc_BG2_Zc352_byte.c"
-#include "ldpc_BG2_Zc320_byte.c"
-#include "ldpc_BG2_Zc288_byte.c"
-#include "ldpc_BG2_Zc256_byte.c"
-#include "ldpc_BG2_Zc240_byte.c"
-#include "ldpc_BG2_Zc224_byte.c"
-#include "ldpc_BG2_Zc208_byte.c"
-#include "ldpc_BG2_Zc192_byte.c"
-#include "ldpc_BG2_Zc176_byte.c"
-#include "ldpc_BG2_Zc160_byte.c"
-#include "ldpc_BG2_Zc144_byte.c"
-#include "ldpc_BG2_Zc128_byte.c"
-#include "ldpc_BG2_Zc120_byte.c"
-#include "ldpc_BG2_Zc112_byte.c"
-#include "ldpc_BG2_Zc104_byte.c"
-#include "ldpc_BG2_Zc96_byte.c"
-#include "ldpc_BG2_Zc88_byte.c"
-#include "ldpc_BG2_Zc80_byte.c"
-#include "ldpc_BG2_Zc72_byte.c"
-
-
-
-void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb)
-{
-
-  if (BG==1)
-  {
-    switch (Zc)
-    {
-    case 2: break;
-    case 3: break;
-    case 4: break;
-    case 5: break;
-    case 6: break;
-    case 7: break;
-    case 8: break;
-    case 9: break;
-    case 10: break;
-    case 11: break;
-    case 12: break;
-    case 13: break;
-    case 14: break;
-    case 15: break;
-    case 16: break;
-    case 18: break;
-    case 20: break;
-    case 22: break;
-    case 24: break;      
-    case 26: break;
-    case 28: break;
-    case 30: break;
-    case 32: break;
-    case 36: break;
-    case 40: break;
-    case 44: break;
-    case 48: break;
-    case 52: break;
-    case 56: break;
-    case 60: break;
-    case 64: break;
-    case 72: break;
-    case 80: break;   
-    case 88: break;   
-    case 96: break;
-    case 104: break;
-    case 112: break;
-    case 120: break;
-    case 128: break;
-    case 144: break;
-    case 160: break;
-    case 176: ldpc176_byte(c,d); break;
-    case 192: ldpc192_byte(c,d); break;
-    case 208: ldpc208_byte(c,d); break;
-    case 224: ldpc224_byte(c,d); break;
-    case 240: ldpc240_byte(c,d); break;
-    case 256: ldpc256_byte(c,d); break;
-    case 288: ldpc288_byte(c,d); break;
-    case 320: ldpc320_byte(c,d); break;
-    case 352: ldpc352_byte(c,d); break;
-    case 384: ldpc384_byte(c,d); break;
-    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
-    }
-  }
-  else if (BG==2) {
-    switch (Zc)
-    {
-    case 2: break;
-    case 3: break;
-    case 4: break;
-    case 5: break;
-    case 6: break;
-    case 7: break;
-    case 8: break;
-    case 9: break;
-    case 10: break;
-    case 11: break;
-    case 12: break;
-    case 13: break;
-    case 14: break;
-    case 15: break;
-    case 16: break;
-    case 18: break;
-    case 20: break;
-    case 22: break;
-    case 24: break;      
-    case 26: break;
-    case 28: break;
-    case 30: break;
-    case 32: break;
-    case 36: break;
-    case 40: break;
-    case 44: break;
-    case 48: break;
-    case 52: break;
-    case 56: break;
-    case 60: break;
-    case 64: break;
-    case 72: ldpc_BG2_Zc72_byte(c,d); break;
-    case 80: ldpc_BG2_Zc80_byte(c,d); break;   
-    case 88: ldpc_BG2_Zc88_byte(c,d); break;   
-    case 96: ldpc_BG2_Zc96_byte(c,d); break;
-    case 104: ldpc_BG2_Zc104_byte(c,d); break;
-    case 112: ldpc_BG2_Zc112_byte(c,d); break;
-    case 120: ldpc_BG2_Zc120_byte(c,d); break;
-    case 128: ldpc_BG2_Zc128_byte(c,d); break;
-    case 144: ldpc_BG2_Zc144_byte(c,d); break;
-    case 160: ldpc_BG2_Zc160_byte(c,d); break;
-    case 176: ldpc_BG2_Zc176_byte(c,d); break;
-    case 192: ldpc_BG2_Zc192_byte(c,d); break;
-    case 208: ldpc_BG2_Zc208_byte(c,d); break;
-    case 224: ldpc_BG2_Zc224_byte(c,d); break;
-    case 240: ldpc_BG2_Zc240_byte(c,d); break;
-    case 256: ldpc_BG2_Zc256_byte(c,d); break;
-    case 288: ldpc_BG2_Zc288_byte(c,d); break;
-    case 320: ldpc_BG2_Zc320_byte(c,d); break;
-    case 352: ldpc_BG2_Zc352_byte(c,d); break;
-    case 384: ldpc_BG2_Zc384_byte(c,d); break;
-    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
-    }
-  }
-  else {
-    AssertFatal(0,"BG %d is not supported yet\n",BG);
-  } 
-
-}
-
-
-int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
-{
-
-  short nrows=0,ncols=0;
-  int i,i1,rate=3;
-  int no_punctured_columns,removed_bit;
-
-  int simd_size;
-
-  //determine number of bits in codeword
-   //if (block_length>3840)
-   if (BG==1)
-     {
-       //BG=1;
-       nrows=46; //parity check bits
-       ncols=22; //info bits
-       rate=3;
-     }
-     //else if (block_length<=3840)
-    else if	(BG==2)
-     {
-       //BG=2;
-       nrows=42; //parity check bits
-       ncols=10; // info bits
-       rate=5;
-
-       }
-
-
-#ifdef DEBUG_LDPC
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length);
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0],test_input[1],test_input[2],test_input[3]);
-#endif
-
-  if ((Zc&31) > 0) simd_size = 16;
-  else simd_size = 32;
-
-  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
-  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
-
-  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
-
-  // calculate number of punctured bits
-  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
-  // printf("%d\n",no_punctured_columns);
-  // printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
-
-  if(tinput != NULL) start_meas(tinput);
-  for (i=0; i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-    }
-
-  if(tinput != NULL) stop_meas(tinput);
-
-  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
-    // extend matrix
-    if(tprep != NULL) start_meas(tprep);
-    for (i1=0; i1 < ncols; i1++)
-      {
-	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-      }
-    for (i1=1;i1 8 bytes, pattern repeats.
-  __m256i zero256   = _mm256_setzero_si256();
-  __m256i masks[8];
-  register __m256i c256;
-  masks[0] = _mm256_set1_epi8(0x1);
-  masks[1] = _mm256_set1_epi8(0x2);
-  masks[2] = _mm256_set1_epi8(0x4);
-  masks[3] = _mm256_set1_epi8(0x8);
-  masks[4] = _mm256_set1_epi8(0x10);
-  masks[5] = _mm256_set1_epi8(0x20);
-  masks[6] = _mm256_set1_epi8(0x40);
-  masks[7] = _mm256_set1_epi8(0x80);
-#endif
-
-  AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
-
-  //determine number of bits in codeword
-  //if (block_length>3840)
-  if (BG==1)
-    {
-      nrows=46; //parity check bits
-      ncols=22; //info bits
-      rate=3;
-    }
-    //else if (block_length<=3840)
-   else if	(BG==2)
-    {
-      //BG=2;
-      nrows=42; //parity check bits
-      ncols=10; // info bits
-      rate=5;
-
-      }
-
-#ifdef DEBUG_LDPC
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
-#endif
-
-  AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
-
-  if ((Zc&31) > 0) simd_size = 16;
-  else          simd_size = 32;
-
-  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
-  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
-
-  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
-
-  // calculate number of punctured bits
-  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
-  // printf("%d\n",no_punctured_columns);
-  // printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
-
-  if(tinput != NULL) start_meas(tinput);
-#if 0
-  for (i=0; i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << j);
-    }
-  }
-#else
-#ifdef __AVX2__
-  for (i=0; i>5; i++) {
-    c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]);
-    for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << j);
-    }
-  }
-#else
-  AssertFatal(1==0,"Need AVX2 for this\n");
-#endif
-#endif
-
-  if(tinput != NULL) stop_meas(tinput);
-
-  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
-    // extend matrix
-    if(tprep != NULL) start_meas(tprep);
-    for (i1=0; i1 < ncols; i1++)
-      {
-	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-      }
-    for (i1=1;i1>5;
-    uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
-    __m256i *c256p = (__m256i *)&c[2*Zc];
-    __m256i *d256p = (__m256i *)&d[0];
-    //  if (((block_length-(2*Zc))&31)>0) l1++;
-    
-    for (i=0;i0) l2++;
-    
-    for (i1=0;i1>j)&1;
-    for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
-      for (j=0; j>j)&1;
-    }
-
-#else
-    AssertFatal(1==0,"Need AVX2 for now\n");
-#endif
-
-  if(toutput != NULL) stop_meas(toutput);
-  return 0;
-}
-
-int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
-{
-
-  short nrows=0,ncols=0;
-  int i,i1,j,rate=3;
-  int no_punctured_columns,removed_bit;
-  //Table of possible lifting sizes
-  char temp;
-  int simd_size;
-  unsigned int macro_segment, macro_segment_end;
-
-  
-  macro_segment = 8*macro_num;
-  // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
-  macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments);
-  ///printf("macro_segment: %d\n", macro_segment);
-  ///printf("macro_segment_end: %d\n", macro_segment_end );
-
-#ifdef __AVX2__
-  __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
-  __m256i andmask  = _mm256_set1_epi64x(0x0102040810204080);  // every 8 bits -> 8 bytes, pattern repeats.
-  __m256i zero256   = _mm256_setzero_si256();
-  __m256i masks[8];
-  register __m256i c256;
-  masks[0] = _mm256_set1_epi8(0x1);
-  masks[1] = _mm256_set1_epi8(0x2);
-  masks[2] = _mm256_set1_epi8(0x4);
-  masks[3] = _mm256_set1_epi8(0x8);
-  masks[4] = _mm256_set1_epi8(0x10);
-  masks[5] = _mm256_set1_epi8(0x20);
-  masks[6] = _mm256_set1_epi8(0x40);
-  masks[7] = _mm256_set1_epi8(0x80);
-#endif
-
-
-
-  //determine number of bits in codeword
-  if (BG==1)
-    {
-      nrows=46; //parity check bits
-      ncols=22; //info bits
-      rate=3;
-    }
-    else if (BG==2)
-    {
-      nrows=42; //parity check bits
-      ncols=10; // info bits
-      rate=5;
-    }
-
-#ifdef DEBUG_LDPC
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
-#endif
-
-  AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
-
-  if ((Zc&31) > 0) simd_size = 16;
-  else          simd_size = 32;
-
-  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
-  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
-
-  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
-
-  // calculate number of punctured bits
-  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
-  //printf("%d\n",no_punctured_columns);
-  //printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
-
-  if(tinput != NULL) start_meas(tinput);
-#if 0
-  for (i=0; i>(i&7);
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << (j-macro_segment));
-    }
-  }
-#else
-#ifdef __AVX2__
-  for (i=0; i>5; i++) {
-    c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
-    //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << (j-macro_segment));
-    }
-  }
-#else
-  AssertFatal(1==0,"Need AVX2 for this\n");
-#endif
-#endif
-
-  if(tinput != NULL) stop_meas(tinput);
-
-  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
-    // extend matrix
-    if(tprep != NULL) start_meas(tprep);
-    for (i1=0; i1 < ncols; i1++)
-      {
-	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-      }
-    for (i1=1;i1>5;
-    uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
-    __m256i *c256p = (__m256i *)&c[2*Zc];
-    __m256i *d256p = (__m256i *)&d[0];
-    //  if (((block_length-(2*Zc))&31)>0) l1++;
-
-    for (i=0;i0) l2++;
-
-    for (i1=0;i1>(j-macro_segment))&1;
-    for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
-      //for (j=0; j>(j-macro_segment))&1;
-    }
-
-#else
-    AssertFatal(1==0,"Need AVX2 for now\n");
-#endif
-
-  if(toutput != NULL) stop_meas(toutput);
-  return 0;
-}
-
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
new file mode 100644
index 0000000000..7da265494a
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
@@ -0,0 +1,146 @@
+/*
+ * 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 ldpc_encoder2.c
+ * \brief Defines the optimized LDPC encoder
+ * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
+ * \email openair_tech@eurecom.fr
+ * \date 27-03-2018
+ * \version 1.0
+ * \note
+ * \warning
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#include "PHY/TOOLS/time_meas.h"
+#include "openair1/PHY/CODING/nrLDPC_defs.h"
+#include "ldpc_encode_parity_check.c"
+#include "ldpc_generate_coefficient.c"
+//#define DEBUG_LDPC
+
+
+
+
+
+int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp)
+{
+
+  short nrows=0,ncols=0;
+  int i,i1,rate=3;
+  int no_punctured_columns,removed_bit;
+
+  int simd_size;
+
+  //determine number of bits in codeword
+   //if (block_length>3840)
+   if (BG==1)
+     {
+       //BG=1;
+       nrows=46; //parity check bits
+       ncols=22; //info bits
+       rate=3;
+     }
+     //else if (block_length<=3840)
+    else if	(BG==2)
+     {
+       //BG=2;
+       nrows=42; //parity check bits
+       ncols=10; // info bits
+       rate=5;
+
+       }
+
+
+#ifdef DEBUG_LDPC
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length);
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
+#endif
+
+  if ((Zc&31) > 0) simd_size = 16;
+  else simd_size = 32;
+
+  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
+
+  // calculate number of punctured bits
+  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+  // printf("%d\n",no_punctured_columns);
+  // printf("%d\n",removed_bit);
+  // unpack input
+  memset(c,0,sizeof(unsigned char) * ncols * Zc);
+  memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+  if(impp->tinput != NULL) start_meas(impp->tinput);
+  for (i=0; i>(i&7)))>>(7-(i&7));
+      //printf("c(%d,%d)=%d\n",j,i,temp);
+    }
+
+  if(impp->tinput != NULL) stop_meas(impp->tinput);
+
+  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
+    // extend matrix
+    if(impp->tprep != NULL) start_meas(impp->tprep);
+    for (i1=0; i1 < ncols; i1++)
+      {
+	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+      }
+    for (i1=1;i1tprep != NULL) stop_meas(impp->tprep);
+    //parity check part
+    if(impp->tparity != NULL) start_meas(impp->tparity);
+    encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
+    if(impp->tparity != NULL) stop_meas(impp->tparity);
+  }
+  else {
+    if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
+      printf("Problem with encoder\n");
+      return(-1);
+    }
+  }
+  if(impp->toutput != NULL) start_meas(impp->toutput);
+  // information part and puncture columns
+  memcpy(&channel_input[0][0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
+  memcpy(&channel_input[0][block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
+
+  if(impp->toutput != NULL) stop_meas(impp->toutput);
+  return 0;
+}
+
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
index 5988c9067d..3d26a19063 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
@@ -35,9 +35,8 @@
 #include 
 #include "Gen_shift_value.h"
 #include "assertions.h"
-#include "defs.h"
 
-short *choose_generator_matrix(short BG,short Zc)
+static inline short *choose_generator_matrix(short BG,short Zc)
 {
   short *Gen_shift_values = NULL;
 
@@ -361,237 +360,70 @@ short *choose_generator_matrix(short BG,short Zc)
   return Gen_shift_values;
 }
 
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code)
+static inline int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length)
 {
-  unsigned char c[22*384]; //padded input, unpacked, max size
-  unsigned char d[68*384]; //coded output, unpacked, max size
+  short *Gen_shift_values=choose_generator_matrix(BG,Zc);
+  short *no_shift_values, *pointer_shift_values;
+  int no_punctured_columns;
+  short nrows,ncols,rate=3;
+  int i1,i2,i3,i4,i5,temp_prime;
   unsigned char channel_temp,temp;
-  short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
 
-  short nrows = 46;//parity check bits
-  short ncols = 22;//info bits
-
-
-  int i,i1,i2,i3,i4,i5,temp_prime,var;
-  int no_punctured_columns,removed_bit,rate=3;
-  int nind=0;
-  int indlist[1000];
-  int indlist2[1000];
-
-  //determine number of bits in codeword
-  //if (block_length>3840)
-     if (BG==1)
-       {
-         nrows=46; //parity check bits
-         ncols=22; //info bits
-         rate=3;
-       }
-       //else if (block_length<=3840)
-      else if	(BG==2)
-       {
-         //BG=2;
-         nrows=42; //parity check bits
-         ncols=10; // info bits
-         rate=5;
-         }
-
-  Gen_shift_values=choose_generator_matrix(BG,Zc);
-  if (Gen_shift_values==NULL) {
-    printf("ldpc_encoder_orig: could not find generator matrix\n");
-    return(-1);
-  }
-
-  //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb);
-
-  // load base graph of generator matrix
   if (BG==1)
   {
     no_shift_values=(short *) no_shift_values_BG1;
     pointer_shift_values=(short *) pointer_shift_values_BG1;
+      nrows=46; //parity check bits
+      ncols=22; //info bits
+      rate=3;
   }
   else if (BG==2)
   {
     no_shift_values=(short *) no_shift_values_BG2;
     pointer_shift_values=(short *) pointer_shift_values_BG2;
+      nrows=42; //parity check bits
+      ncols=10; //info bits
+      rate=5;
   }
   else {
-    AssertFatal(0,"BG %d is not supported yet\n",BG);
+    printf("problem with BG\n");
+    return(-1);
   }
-  
+
+
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate);
-  //printf("%d\n",no_punctured_columns);
-  //printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
 
-  for (i=0; i>7&1;
-    c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7));
-  }
+    //t=Kb*Zc+i2;
 
-  // parity check part
-
-  if (gen_code==1)
-  {
-    char fname[100];
-    sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc);
-    FILE *fd=fopen(fname,"w");
-    AssertFatal(fd!=NULL,"cannot open %s\n",fname);
-    sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc);
-    FILE *fd2=fopen(fname,"w");
-    AssertFatal(fd2!=NULL,"cannot open %s\n",fname);
-
-    int shift;
-    char data_type[100];
-    char xor_command[100];
-    int mask;
-
-
-
-
-    fprintf(fd,"#include \"PHY/sse_intrin.h\"\n");
-    fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n");
-
-    if ((Zc&31)==0) {
-      shift=5; // AVX2 - 256-bit SIMD
-      mask=31;
-      strcpy(data_type,"__m256i");
-      strcpy(xor_command,"_mm256_xor_si256");
-    }
-    else if ((Zc&15)==0) {
-      shift=4; // SSE4 - 128-bit SIMD
-      mask=15;
-      strcpy(data_type,"__m128i");
-      strcpy(xor_command,"_mm_xor_si128");
-
-    }
-    else if ((Zc&7)==0) {
-      shift=3; // MMX  - 64-bit SIMD
-      mask=7;
-      strcpy(data_type,"__m64");
-      strcpy(xor_command,"_mm_xor_si64"); 
-    }
-    else {
-      shift=0;                 // no SIMD
-      mask=0;
-      strcpy(data_type,"uint8_t");
-      strcpy(xor_command,"scalar_xor");
-      fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n");
-      fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n");
-    }
-    fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc);
-    fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc);
-    fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc);
-    fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc);
-    fprintf(fd,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
-    fprintf(fd2,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
-    fprintf(fd,"  %s *c2,*d2;\n\n",data_type);
-    fprintf(fd2,"  %s *c2,*d2;\n\n",data_type);
-    fprintf(fd,"  int i2;\n");
-    fprintf(fd2,"  int i2;\n");
-    fprintf(fd,"  for (i2=0; i2<%d; i2++) {\n",Zc>>shift);
-    if (shift > 0)
-      fprintf(fd2,"  for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1));
-    for (i2=0; i2 < 1; i2++)
+    //rotate matrix here
+    for (i5=0; i5 < Kb; i5++)
     {
-      //t=Kb*Zc+i2;
-    
-      // calculate each row in base graph
-     
-
-      fprintf(fd,"     c2=&csimd[i2];\n");
-      fprintf(fd,"     d2=&dsimd[i2];\n");
-      fprintf(fd2,"     c2=&csimd[i2];\n");
-      fprintf(fd2,"     d2=&dsimd[i2];\n");
-
-      for (i1=0; i1 < nrows; i1++)
-
-      {
-        channel_temp=0;
-        fprintf(fd,"\n//row: %d\n",i1);
-        fprintf(fd2,"\n//row: %d\n",i1);
-	fprintf(fd,"     d2[%d]=",(Zc*i1)>>shift);
-	fprintf(fd2,"     d2[%d]=",(Zc*i1)>>(shift-1));
-
-        nind=0;
-
-        for (i3=0; i3 < ncols; i3++)
-        {
-          temp_prime=i1 * ncols + i3;
-
-
-	  for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
-	    {
-	          
-	      var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc);
-	      int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc;
-	      
-	      indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift);
-	      indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1));
-	      
-	    }
-	  
-
-        }
-	for (i4=0;i4
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#ifndef __NR_LDPC_DECODER__H__
-#define __NR_LDPC_DECODER__H__
-
-#include "nrLDPC_types.h"
-#include "nrLDPC_init_mem.h"
-
-/**
-   \brief LDPC decoder
-   \param p_decParams LDPC decoder parameters
-   \param p_llr Input LLRs
-   \param p_llrOut Output vector
-   \param p_profiler LDPC profiler statistics
-*/
-int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_llrOut, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler);
-
-#endif
+#ifdef LDPC_LOADER
+nrLDPC_decoderfunc_t nrLDPC_decoder;
+nrLDPC_encoderfunc_t nrLDPC_encoder;
+#else
+/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
+extern int load_nrLDPClib(void) ;
+extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest
+/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
+extern nrLDPC_decoderfunc_t nrLDPC_decoder;
+extern nrLDPC_encoderfunc_t nrLDPC_encoder;
+// inline functions:
+#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
+#endif
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c
new file mode 100644
index 0000000000..a74bdf7bd1
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_load.c
@@ -0,0 +1,76 @@
+/*
+ * 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 openair1/PHY/CODING/coding_nr_load.c
+ * \brief: load library implementing coding/decoding algorithms
+ * \author Francois TABURET
+ * \date 2020
+ * \version 0.1
+ * \company NOKIA BellLabs France
+ * \email: francois.taburet@nokia-bell-labs.com
+ * \note
+ * \warning
+ */
+#define _GNU_SOURCE 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#define LDPC_LOADER
+#include "PHY/CODING/nrLDPC_extern.h"
+#include "common/config/config_userapi.h" 
+#include "common/utils/load_module_shlib.h" 
+
+
+/* function description array, to be used when loading the encoding/decoding shared lib */
+static loader_shlibfunc_t shlib_fdesc[2];
+
+char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"};
+
+int load_nrLDPClib(void) {
+	 char *ptr = (char*)config_get_if();
+     if ( ptr==NULL )  {// phy simulators, config module possibly not loaded
+     	 load_configmodule(3,(char **)arg,CONFIG_ENABLECMDLINEONLY) ;
+     	 logInit();
+     }	 
+     shlib_fdesc[0].fname = "nrLDPC_decod";
+     shlib_fdesc[1].fname = "nrLDPC_encod";
+     int ret=load_module_shlib("ldpc",shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
+     AssertFatal( (ret >= 0),"Error loading ldpc decoder");
+     nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr;
+     nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr;
+return 0;
+}
+
+int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) {
+	loader_shlibfunc_t shlib_encoder_fdesc;
+
+     shlib_encoder_fdesc.fname = "nrLDPC_encod";
+     char libpath[64];
+     sprintf(libpath,"ldpc%s",libversion);
+     int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL);
+     AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath);
+     *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr;
+return 0;
+}
+
+
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index f0ad3cbaae..4798f9a9e4 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -31,6 +31,7 @@
 #include "TDD-Config.h"
 #include "MBSFN-SubframeConfigList.h"*/
 #include "openair1/PHY/defs_RU.h"
+#include "openair1/PHY/CODING/nrLDPC_extern.h"
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "assertions.h"
 #include 
@@ -115,6 +116,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
   crcTableInit();
   init_dfts();
+  load_nrLDPClib();
   // PBCH DMRS gold sequences generation
   nr_init_pbch_dmrs(gNB);
   //PDCCH DMRS init
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index dae5586224..17de9c02af 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -35,12 +35,11 @@
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/NR_TRANSPORT/nr_transport.h"
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 #include "PHY/NR_TRANSPORT/nr_dlsch.h"
 #include "SCHED_NR/sched_nr.h"
-#include "defs.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "common/utils/LOG/log.h"
 #include 
@@ -404,9 +403,11 @@ int nr_dlsch_encoding(unsigned char *a,
       //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0);
       //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
     }
-
+    encoder_implemparams_t impp;
+    impp.n_segments=dlsch->harq_processes[harq_pid]->C;
     for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
-      ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
+      impp.macro_num=j;
+      nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp);
     }
 
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 3945439a45..c58941b077 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -37,8 +37,7 @@
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 #include "PHY/NR_TRANSPORT/nr_ulsch.h"
 #include "PHY/NR_TRANSPORT/nr_dlsch.h"
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index b3a95e313e..b81c01114d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -41,8 +41,7 @@
 #include "SCHED_NR_UE/defs.h"
 #include "SIMULATION/TOOLS/sim.h"
 #include "executables/nr-uesoftmodem.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 //#define DEBUG_DLSCH_DECODING
 //#define ENABLE_PHY_PAYLOAD_DEBUG 1
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 2eb6dcd7fe..8b80b1b219 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -36,7 +36,7 @@
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
@@ -353,8 +353,11 @@ opp_enabled=0;
       printf("%d \n",  harq_process->d[0][cnt]);
       }
       printf("\n");*/
+    encoder_implemparams_t impp;
+    impp.n_segments=harq_process->C;
+    impp.macro_num=0;
 
-    ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
+    nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp);
 
     //stop_meas(te_stats);
     //printf("end ldpc encoder -- output\n");
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 3c0f0db8da..fc81f4d74b 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -40,7 +40,7 @@
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 #include "PHY/impl_defs_top.h"
 #include "PHY/defs_common.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
 
 #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 757ad6f75d..3066f0906f 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -37,6 +37,7 @@
 #include 
 
 #include "common_lib.h"
+#include "assertions.h"
 #include "common/utils/load_module_shlib.h"
 #include "common/utils/LOG/log.h"
 #include "targets/RT/USER/lte-softmodem.h"
@@ -91,38 +92,44 @@ int load_lib(openair0_device *device,
 {
   loader_shlibfunc_t shlib_fdesc[1];
   int ret=0;
-  char *libname;
+  char *deflibname=OAI_RF_LIBNAME;
   
   openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state));
 
   if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) {
-  	  libname=OAI_IQPLAYER_LIBNAME;
+  	  deflibname=OAI_IQPLAYER_LIBNAME;
   	  shlib_fdesc[0].fname="device_init";
   	  set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT);  // softmodem has to know we use the iqplayer to workaround randomized algorithms
   } else  if ( IS_SOFTMODEM_BASICSIM ) {
-	  libname=OAI_BASICSIM_LIBNAME;
+	  deflibname=OAI_BASICSIM_LIBNAME;
 	  shlib_fdesc[0].fname="device_init";
   } else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
-	  libname=OAI_RFSIM_LIBNAME;
+	  deflibname=OAI_RFSIM_LIBNAME;
 	  shlib_fdesc[0].fname="device_init";
   } else if (flag == RAU_LOCAL_RADIO_HEAD) {
 	  if (IS_SOFTMODEM_RFSIM)
-		  libname="rfsimulator";
+		  deflibname="rfsimulator";
 	  else
-          libname=OAI_RF_LIBNAME;
+          deflibname=OAI_RF_LIBNAME;
       shlib_fdesc[0].fname="device_init";
   } else {
-	  libname=OAI_TP_LIBNAME;
+	  deflibname=OAI_TP_LIBNAME;
 	  shlib_fdesc[0].fname="transport_init";
   }
-  ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
+  
+  char *devname=NULL;
+  paramdef_t device_params[]=DEVICE_PARAMS_DESC ;
+  int numparams = sizeof(device_params)/sizeof(paramdef_t);
+  int devname_pidx = config_paramidx_fromname(device_params,numparams, CONFIG_DEVICEOPT_NAME);
+  device_params[devname_pidx].defstrval=deflibname;
+  
+  config_get(device_params,numparams,DEVICE_SECTION);
+  
+  ret=load_module_shlib(devname,shlib_fdesc,1,NULL);
+  AssertFatal( (ret >= 0),
+  	           "Library %s couldn't be loaded\n",devname);
 
-  if (ret < 0) {
-    LOG_E(HW,"Library %s couldn't be loaded\n",libname);
-  } else {
-    ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
-  }
-  return ret;
+  return ((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
 }
 
 
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 7e51bdc81a..ecadb68c0c 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -448,6 +448,24 @@ typedef struct {
 extern "C"
 {
 #endif
+
+
+#define  DEVICE_SECTION   "device"
+#define  CONFIG_HLP_DEVICE  "Identifies the oai device (the interface to RF) to use, the shared lib \"lib_.so\" will be loaded"
+
+#define  CONFIG_DEVICEOPT_NAME "name"
+
+/* inclusion for device configuration */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            config parameters for oai device                                                                                               */
+/*   optname                     helpstr                paramflags                      XXXptr                  defXXXval                            type           numelt   */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define DEVICE_PARAMS_DESC {\
+    { CONFIG_DEVICEOPT_NAME,      CONFIG_HLP_DEVICE,          0,                strptr:&devname,                 defstrval:NULL,         TYPE_STRING,     0}\
+}
+
+
+
 /*! \brief get device name from device type */
 char *get_devname(int devtype);
 /*! \brief Initialize openair RF target. It returns 0 if OK */
diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h
index 903dda006b..500acdd709 100644
--- a/targets/ARCH/COMMON/record_player.h
+++ b/targets/ARCH/COMMON/record_player.h
@@ -37,19 +37,6 @@
 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 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
@@ -114,7 +101,7 @@ typedef struct {
     {CONFIG_OPT_SF_LOOPS,     CONFIG_HLP_SF_LOOPS,  0,                uptr:&((*recplay_conf)->u_sf_loops),                defintval:DEF_SF_NB_LOOP,        TYPE_UINT,   0}, \
     {CONFIG_OPT_SF_RDELAY,    CONFIG_HLP_SF_RDELAY, 0,                uptr:&((*recplay_conf)->u_sf_read_delay),           defintval:DEF_SF_DELAY_READ,     TYPE_UINT,   0}, \
     {CONFIG_OPT_SF_WDELAY,    CONFIG_HLP_SF_WDELAY, 0,                uptr:&((*recplay_conf)->u_sf_write_delay),          defintval:DEF_SF_DELAY_WRITE,    TYPE_UINT,   0}, \
-  }/*! \brief USRP Configuration and state */
+  }/*! \brief Record Player Configuration and state */
 typedef struct {
   char            u_sf_filename[1024];              // subframes file path
   unsigned int    u_sf_max ;                  // max number of recorded subframes
diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c
index beb05de3fd..c4133d1b11 100644
--- a/targets/ARCH/iqplayer/iqplayer_lib.c
+++ b/targets/ARCH/iqplayer/iqplayer_lib.c
@@ -25,6 +25,7 @@
  */
 #define _LARGEFILE_SOURCE
 #define _FILE_OFFSET_BITS 64
+#define NB_ANTENNAS_RX  2
 #include 
 #include 
 #include 
@@ -45,7 +46,9 @@
 
 
 static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) {
-  AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),"iqfile doesn't seem to be compatible with oai (invalid id in header)\n");
+  AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),
+  	           "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n",
+  	           iq_fh->oaiid);
   device->type = iq_fh->devtype;
   device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance;
   device->openair0_cfg[0].tx_bw =  device->openair0_cfg[0].rx_bw = iq_fh->bw;
@@ -138,6 +141,13 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
   return 0;
 }
 
+/*! \brief start the oai iq player
+ * \param device, the hardware used
+ */
+static int trx_iqplayer_start(openair0_device *device){
+	return 0;
+}
+
 /*! \brief Terminate operation of the oai iq player
  * \param device, the hardware used
  */
@@ -287,7 +297,7 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes
 
 int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   device->openair0_cfg = openair0_cfg;
-  device->trx_start_func = NULL;
+  device->trx_start_func = trx_iqplayer_start;
   device->trx_get_stats_func = NULL;
   device->trx_reset_stats_func = NULL;
   device->trx_end_func   = trx_iqplayer_end;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index f88d98536d..6d1a3b8cb2 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2194,7 +2194,9 @@ int start_rf(RU_t *ru) {
 }
 
 int stop_rf(RU_t *ru) {
-  ru->rfdevice.trx_end_func(&ru->rfdevice);
+    if(ru->rfdevice.trx_end_func != NULL) {
+      ru->rfdevice.trx_end_func(&ru->rfdevice);
+    }
   return 0;
 }
 

From 3b3d2322141959cdaf5e97296b590cef7ff6ab9e Mon Sep 17 00:00:00 2001
From: frtabu 
Date: Wed, 11 Mar 2020 17:32:13 +0100
Subject: [PATCH 318/343] move ldpc coder/decoder into a shared lib dymically
 loaded. Also fix a record player bug

---
 cmake_targets/CMakeLists.txt                  |  39 +-
 common/config/config_userapi.c                |   3 +-
 common/utils/telnetsrv/telnetsrv.c            |  20 +-
 openair1/PHY/CODING/TESTBENCH/ldpctest.c      |  22 +-
 .../CODING/nrLDPC_decoder/nrLDPC_decoder.c    |   4 +-
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_init.h   |   2 +-
 .../CODING/nrLDPC_decoder/nrLDPC_init_mem.h   |   1 -
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h  |   2 +-
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_types.h  |   5 +-
 .../{nrLDPC_defs.h => nrLDPCdecoder_defs.h}   |   2 +-
 openair1/PHY/CODING/nrLDPC_defs.h             |  59 ++
 openair1/PHY/CODING/nrLDPC_encoder/defs.h     |  54 --
 .../nrLDPC_encoder/ldpc_encode_parity_check.c | 201 ++++++
 .../PHY/CODING/nrLDPC_encoder/ldpc_encoder.c  | 252 +++++--
 .../PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c | 667 ------------------
 .../nrLDPC_encoder/ldpc_encoder_optim.c       | 146 ++++
 .../nrLDPC_encoder/ldpc_encoder_optim8seg.c   | 225 ++++++
 .../ldpc_encoder_optim8segmulti.c             | 238 +++++++
 .../ldpc_generate_coefficient.c               | 244 +------
 .../nrLDPC_decoder.h => nrLDPC_extern.h}      |  39 +-
 openair1/PHY/CODING/nrLDPC_load.c             |  76 ++
 openair1/PHY/INIT/nr_init.c                   |   2 +
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c   |   9 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |   3 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |   3 +-
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |   7 +-
 openair1/PHY/defs_gNB.h                       |   2 +-
 targets/ARCH/COMMON/common_lib.c              |  35 +-
 targets/ARCH/COMMON/common_lib.h              |  18 +
 targets/ARCH/COMMON/record_player.h           |  15 +-
 targets/ARCH/iqplayer/iqplayer_lib.c          |  14 +-
 targets/RT/USER/lte-ru.c                      |   4 +-
 32 files changed, 1351 insertions(+), 1062 deletions(-)
 rename openair1/PHY/CODING/nrLDPC_decoder/{nrLDPC_defs.h => nrLDPCdecoder_defs.h} (99%)
 create mode 100644 openair1/PHY/CODING/nrLDPC_defs.h
 delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/defs.h
 create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c
 delete mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
 create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
 create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c
 create mode 100644 openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
 rename openair1/PHY/CODING/{nrLDPC_decoder/nrLDPC_decoder.h => nrLDPC_extern.h} (60%)
 create mode 100644 openair1/PHY/CODING/nrLDPC_load.c

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index c4d3d7e62e..496417936a 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1298,14 +1298,35 @@ set(PHY_SMALLBLOCKSRC
 set(PHY_TURBOIF
   ${OPENAIR1_DIR}/PHY/CODING/coding_load.c
 )
-set(PHY_LDPCSRC
+
+set(PHY_LDPC_ORIG_SRC
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
-  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
-  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
 )
 
+set(PHY_LDPC_OPTIM_SRC
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
+)
+set(PHY_LDPC_OPTIM8SEG_SRC
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c
+)
+set(PHY_LDPC_OPTIM8SEGMULTI_SRC
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
+)
+set(PHY_NR_CODINGIF
+  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c;
+)
+
+add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} )
+add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} )
+add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} )
+add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
+
 add_library(coding MODULE ${PHY_TURBOSRC} )
+
 set(PHY_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
@@ -1484,10 +1505,9 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/TOOLS/lut.c
   ${PHY_POLARSRC}
   ${PHY_SMALLBLOCKSRC}
-  ${PHY_LDPCSRC}
+  ${PHY_NR_CODINGIF}
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c 
   )
-
   set(PHY_NR_UE_SRC
   ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
   ${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c
@@ -1535,7 +1555,7 @@ set(PHY_SRC_UE
   #  ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
   ${PHY_POLARSRC}
   ${PHY_SMALLBLOCKSRC}
-  ${PHY_LDPCSRC}
+  ${PHY_NR_CODINGIF}
   )
 
 
@@ -2588,7 +2608,7 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LI
 target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES})
 target_link_libraries (nr-softmodem ${T_LIB})
 
-
+add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
 # nr-uesoftmodem is  UE implementation
 #######################################
 
@@ -2629,7 +2649,7 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_
 target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES})
 target_link_libraries (nr-uesoftmodem ${T_LIB})
 
-
+add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
 
 # USIM process
 #################
@@ -2696,10 +2716,13 @@ target_link_libraries(smallblocktest
   )
 
 add_executable(ldpctest  
+  ${PHY_NR_CODINGIF}
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
   )
+add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) 
+
 target_link_libraries(ldpctest
   -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} dl
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index 67fdc2c920..c951905101 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -45,7 +45,8 @@
 
 configmodule_interface_t *config_get_if(void) {
   if (cfgptr == NULL) {
-    CONFIG_PRINTF_ERROR("[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__);
+  	if (isLogInitDone())
+       LOG_W(ENB_APP,"[CONFIG] %s %d config module not initialized\n",__FILE__,__LINE__);
   }
 
   return cfgptr;
diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c
index 10163b22b5..06a5d350c7 100644
--- a/common/utils/telnetsrv/telnetsrv.c
+++ b/common/utils/telnetsrv/telnetsrv.c
@@ -377,6 +377,14 @@ int setgetvar(int moduleindex,char getorset,char *params) {
             client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
             break;
 
+          case TELNET_VARTYPE_INT8:
+            client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));
+            break;
+            
+          case TELNET_VARTYPE_UINT:
+            client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+            break;
+            
           case TELNET_VARTYPE_DOUBLE:
             client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
             break;
@@ -405,7 +413,17 @@ int setgetvar(int moduleindex,char getorset,char *params) {
             *(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0);
             client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
             break;
-
+            
+          case TELNET_VARTYPE_INT8:
+            *(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0);
+            client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+            break;
+            
+          case TELNET_VARTYPE_UINT:
+            *(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0);
+            client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+            break;
+ 
           case TELNET_VARTYPE_DOUBLE:
             *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
             client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index 95ee3fed17..552af99c41 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -25,8 +25,7 @@
 #include 
 #include "assertions.h"
 #include "SIMULATION/TOOLS/sim.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
 
 #define MAX_NUM_DLSCH_SEGMENTS 16
@@ -85,6 +84,7 @@ typedef struct {
 RAN_CONTEXT_t RC;
 PHY_VARS_UE ***PHY_vars_UE_g;
 uint16_t NB_UE_INST = 1;
+nrLDPC_encoderfunc_t encoder_orig;
 
 short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
 
@@ -286,16 +286,19 @@ int test_ldpc(short No_iteration,
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
   //  printf("puncture:%d\n",no_punctured_columns);
   removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
+  encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS;
+ 
+  impp.gen_code=1;
   if (ntrials==0)
-    ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1);
-
+    encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp);
+  impp.gen_code=0;
   for (trial=0; trial < ntrials; trial++)
   {
 	segment_bler = 0;
     //// encoder
     start_meas(&time);
     for(j=0;j
 #include 
-#include "nrLDPC_defs.h"
+#include "nrLDPCdecoder_defs.h"
 #include "nrLDPC_types.h"
 #include "nrLDPC_init.h"
 #include "nrLDPC_mPass.h"
@@ -47,7 +47,7 @@
 
 static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler);
 
-int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
+int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler)
 {
     uint32_t numLLR;
     uint32_t numIter = 0;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h
index 82462c6d95..ea031dc2da 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init.h
@@ -32,7 +32,7 @@
 #define __NR_LDPC_INIT__H__
 
 #include "nrLDPC_lut.h"
-#include "nrLDPC_defs.h"
+#include "nrLDPCdecoder_defs.h"
 
 /**
    \brief Initializes the decoder and sets correct LUTs
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
index bdaa118e1f..3292c0debe 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
@@ -32,7 +32,6 @@
 #define __NR_LDPC_INIT_MEM__H__
 
 #include 
-#include "nrLDPC_defs.h"
 #include "nrLDPC_types.h"
 
 #ifndef malloc32_clear
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
index 66715618d0..7d0f5f077a 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
@@ -32,7 +32,7 @@
 #define __NR_LDPC_MPASS__H__
 
 #include 
-#include "nrLDPC_defs.h"
+#include "nrLDPCdecoder_defs.h"
 
 /**
    \brief Circular memcpy
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
index 34322a7780..e5b99246d5 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
@@ -32,8 +32,7 @@
 #define __NR_LDPC_TYPES__H__
 
 #include "PHY/TOOLS/time_meas.h"
-#include "nrLDPC_defs.h"
-
+#include "nrLDPCdecoder_defs.h"
 // ==============================================================================
 // TYPES
 
@@ -103,4 +102,6 @@ typedef struct nrLDPC_procBuf {
     int8_t* llrProcBuf; /**< LLR processing buffer */
 } t_nrLDPC_procBuf;
 
+
+
 #endif
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
similarity index 99%
rename from openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h
rename to openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
index 940d842550..69fc88752f 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_defs.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
@@ -19,7 +19,7 @@
  *      contact@openairinterface.org
  */
 
-/*!\file nrLDPC_defs.h
+/*!\file nrLDPCdecoder_defs.h
  * \brief Defines all constants and buffers for the LDPC decoder
  * \author Sebastian Wagner (TCL Communications) Email: 
  * \date 27-03-2018
diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h
new file mode 100644
index 0000000000..b96067f4b6
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_defs.h
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+//============================================================================================================================
+// encoder interface
+#ifndef __NRLDPC_DEFS__H__
+#define __NRLDPC_DEFS__H__
+#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+/**
+   \brief LDPC encoder
+   \param 1 input
+   \param 2 channel_input
+   \param 3 int Zc
+   \param 4 int Kb
+   \param 5 short block_length
+   \param 6 short BG
+   \param 7 int n_segment
+   \param 8 unsigned int macro_num
+   \param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput
+*/
+typedef struct {
+	int n_segments;          // optim8seg
+	unsigned int macro_num; // optim8segmulti
+	unsigned char gen_code; //orig
+	time_stats_t *tinput;
+	time_stats_t *tprep;
+	time_stats_t *tparity;
+	time_stats_t *toutput;
+}encoder_implemparams_t;
+#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL}
+typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*);
+//============================================================================================================================
+// decoder interface
+/**
+   \brief LDPC decoder API type definition
+   \param p_decParams LDPC decoder parameters
+   \param p_llr Input LLRs
+   \param p_llrOut Output vector
+   \param p_profiler LDPC profiler statistics
+*/
+typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
+#endif
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/defs.h b/openair1/PHY/CODING/nrLDPC_encoder/defs.h
deleted file mode 100644
index 85cb852fe5..0000000000
--- a/openair1/PHY/CODING/nrLDPC_encoder/defs.h
+++ /dev/null
@@ -1,54 +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 defs.h
- * \brief LDPC encoder forward declarations
- * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
- * \email openair_tech@eurecom.fr
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#include "PHY/TOOLS/time_meas.h"
-
-/*ldpc_encoder.c*/
-int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length);
-
-/*ldpc_encoder2.c*/
-void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb);
-int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-
-/*ldpc_generate_coefficient.c*/
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,unsigned char gen_code);
-
-/*
-int encode_parity_check_part(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb);
-int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length);
-int ldpc_encoder(unsigned char *test_input,unsigned char *channel_input,short block_length, double rate);
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,unsigned char gen_code);
-int ldpc_encoder_multi_segment(unsigned char **test_input,unsigned char **channel_input,short block_length,double rate,uint8_t n_segments);
-int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,int nom_rate,int denom_rate,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
-*/
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c
new file mode 100644
index 0000000000..738fd49b7d
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encode_parity_check.c
@@ -0,0 +1,201 @@
+/*
+ * 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 ldpc_encode_parity_check.c
+ * \brief Parity check function used by ldpc encoders
+ * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
+ * \email openair_tech@eurecom.fr
+ * \date 27-03-2018
+ * \version 1.0
+ * \note
+ * \warning
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+
+
+//#define DEBUG_LDPC
+
+#include "ldpc384_byte.c"
+#include "ldpc352_byte.c"
+#include "ldpc320_byte.c"
+#include "ldpc288_byte.c"
+#include "ldpc256_byte.c"
+#include "ldpc240_byte.c"
+#include "ldpc224_byte.c"
+#include "ldpc208_byte.c"
+#include "ldpc192_byte.c"
+#include "ldpc176_byte.c"
+#include "ldpc_BG2_Zc384_byte.c"
+#include "ldpc_BG2_Zc352_byte.c"
+#include "ldpc_BG2_Zc320_byte.c"
+#include "ldpc_BG2_Zc288_byte.c"
+#include "ldpc_BG2_Zc256_byte.c"
+#include "ldpc_BG2_Zc240_byte.c"
+#include "ldpc_BG2_Zc224_byte.c"
+#include "ldpc_BG2_Zc208_byte.c"
+#include "ldpc_BG2_Zc192_byte.c"
+#include "ldpc_BG2_Zc176_byte.c"
+#include "ldpc_BG2_Zc160_byte.c"
+#include "ldpc_BG2_Zc144_byte.c"
+#include "ldpc_BG2_Zc128_byte.c"
+#include "ldpc_BG2_Zc120_byte.c"
+#include "ldpc_BG2_Zc112_byte.c"
+#include "ldpc_BG2_Zc104_byte.c"
+#include "ldpc_BG2_Zc96_byte.c"
+#include "ldpc_BG2_Zc88_byte.c"
+#include "ldpc_BG2_Zc80_byte.c"
+#include "ldpc_BG2_Zc72_byte.c"
+
+
+
+static inline void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb)
+{
+
+  if (BG==1)
+  {
+    switch (Zc)
+    {
+    case 2: break;
+    case 3: break;
+    case 4: break;
+    case 5: break;
+    case 6: break;
+    case 7: break;
+    case 8: break;
+    case 9: break;
+    case 10: break;
+    case 11: break;
+    case 12: break;
+    case 13: break;
+    case 14: break;
+    case 15: break;
+    case 16: break;
+    case 18: break;
+    case 20: break;
+    case 22: break;
+    case 24: break;      
+    case 26: break;
+    case 28: break;
+    case 30: break;
+    case 32: break;
+    case 36: break;
+    case 40: break;
+    case 44: break;
+    case 48: break;
+    case 52: break;
+    case 56: break;
+    case 60: break;
+    case 64: break;
+    case 72: break;
+    case 80: break;   
+    case 88: break;   
+    case 96: break;
+    case 104: break;
+    case 112: break;
+    case 120: break;
+    case 128: break;
+    case 144: break;
+    case 160: break;
+    case 176: ldpc176_byte(c,d); break;
+    case 192: ldpc192_byte(c,d); break;
+    case 208: ldpc208_byte(c,d); break;
+    case 224: ldpc224_byte(c,d); break;
+    case 240: ldpc240_byte(c,d); break;
+    case 256: ldpc256_byte(c,d); break;
+    case 288: ldpc288_byte(c,d); break;
+    case 320: ldpc320_byte(c,d); break;
+    case 352: ldpc352_byte(c,d); break;
+    case 384: ldpc384_byte(c,d); break;
+    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
+    }
+  }
+  else if (BG==2) {
+    switch (Zc)
+    {
+    case 2: break;
+    case 3: break;
+    case 4: break;
+    case 5: break;
+    case 6: break;
+    case 7: break;
+    case 8: break;
+    case 9: break;
+    case 10: break;
+    case 11: break;
+    case 12: break;
+    case 13: break;
+    case 14: break;
+    case 15: break;
+    case 16: break;
+    case 18: break;
+    case 20: break;
+    case 22: break;
+    case 24: break;      
+    case 26: break;
+    case 28: break;
+    case 30: break;
+    case 32: break;
+    case 36: break;
+    case 40: break;
+    case 44: break;
+    case 48: break;
+    case 52: break;
+    case 56: break;
+    case 60: break;
+    case 64: break;
+    case 72: ldpc_BG2_Zc72_byte(c,d); break;
+    case 80: ldpc_BG2_Zc80_byte(c,d); break;   
+    case 88: ldpc_BG2_Zc88_byte(c,d); break;   
+    case 96: ldpc_BG2_Zc96_byte(c,d); break;
+    case 104: ldpc_BG2_Zc104_byte(c,d); break;
+    case 112: ldpc_BG2_Zc112_byte(c,d); break;
+    case 120: ldpc_BG2_Zc120_byte(c,d); break;
+    case 128: ldpc_BG2_Zc128_byte(c,d); break;
+    case 144: ldpc_BG2_Zc144_byte(c,d); break;
+    case 160: ldpc_BG2_Zc160_byte(c,d); break;
+    case 176: ldpc_BG2_Zc176_byte(c,d); break;
+    case 192: ldpc_BG2_Zc192_byte(c,d); break;
+    case 208: ldpc_BG2_Zc208_byte(c,d); break;
+    case 224: ldpc_BG2_Zc224_byte(c,d); break;
+    case 240: ldpc_BG2_Zc240_byte(c,d); break;
+    case 256: ldpc_BG2_Zc256_byte(c,d); break;
+    case 288: ldpc_BG2_Zc288_byte(c,d); break;
+    case 320: ldpc_BG2_Zc320_byte(c,d); break;
+    case 352: ldpc_BG2_Zc352_byte(c,d); break;
+    case 384: ldpc_BG2_Zc384_byte(c,d); break;
+    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
+    }
+  }
+  else {
+    AssertFatal(0,"BG %d is not supported yet\n",BG);
+  } 
+
+}
+
+
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
index 6ded22d8ca..76f92574ba 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
@@ -37,77 +37,247 @@
 #include 
 #include 
 #include "defs.h"
+#include "assertions.h"
+#include "openair1/PHY/CODING/nrLDPC_defs.h"
+#include "ldpc_generate_coefficient.c"
 
-short *choose_generator_matrix(short BG,short Zc);
-extern short no_shift_values_BG1[1012],pointer_shift_values_BG1[1012],no_shift_values_BG2[2109],pointer_shift_values_BG2[2019];
 
-int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length)
+int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code)
 {
-  short *Gen_shift_values=choose_generator_matrix(BG,Zc);
-  short *no_shift_values, *pointer_shift_values;
-  int no_punctured_columns;
-  short nrows,ncols,rate=3;
-  int i1,i2,i3,i4,i5,temp_prime;
+  unsigned char c[22*384]; //padded input, unpacked, max size
+  unsigned char d[68*384]; //coded output, unpacked, max size
   unsigned char channel_temp,temp;
+  short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
 
+  short nrows = 46;//parity check bits
+  short ncols = 22;//info bits
+
+
+  int i,i1,i2,i3,i4,i5,temp_prime,var;
+  int no_punctured_columns,removed_bit,rate=3;
+  int nind=0;
+  int indlist[1000];
+  int indlist2[1000];
+
+  //determine number of bits in codeword
+  //if (block_length>3840)
+     if (BG==1)
+       {
+         nrows=46; //parity check bits
+         ncols=22; //info bits
+         rate=3;
+       }
+       //else if (block_length<=3840)
+      else if	(BG==2)
+       {
+         //BG=2;
+         nrows=42; //parity check bits
+         ncols=10; // info bits
+         rate=5;
+         }
+
+  Gen_shift_values=choose_generator_matrix(BG,Zc);
+  if (Gen_shift_values==NULL) {
+    printf("ldpc_encoder_orig: could not find generator matrix\n");
+    return(-1);
+  }
+
+  //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb);
+
+  // load base graph of generator matrix
   if (BG==1)
   {
     no_shift_values=(short *) no_shift_values_BG1;
     pointer_shift_values=(short *) pointer_shift_values_BG1;
-      nrows=46; //parity check bits
-      ncols=22; //info bits
-      rate=3;
   }
   else if (BG==2)
   {
     no_shift_values=(short *) no_shift_values_BG2;
     pointer_shift_values=(short *) pointer_shift_values_BG2;
-      nrows=42; //parity check bits
-      ncols=10; //info bits
-      rate=5;
   }
   else {
-    printf("problem with BG\n");
-    return(-1);
+    AssertFatal(0,"BG %d is not supported yet\n",BG);
   }
-
-
+  
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate);
+  //printf("%d\n",no_punctured_columns);
+  //printf("%d\n",removed_bit);
+  // unpack input
+  memset(c,0,sizeof(unsigned char) * ncols * Zc);
+  memset(d,0,sizeof(unsigned char) * nrows * Zc);
 
-  //printf("no_punctured_columns = %d\n",no_punctured_columns);
-
-  for (i2=0; i2 < Zc; i2++)
+  for (i=0; i>7&1;
+    c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7));
+  }
 
-    //rotate matrix here
-    for (i5=0; i5 < Kb; i5++)
-    {
-      temp = c[i5*Zc];
-      memmove(&c[i5*Zc], &c[i5*Zc+1], (Zc-1)*sizeof(unsigned char));
-      c[i5*Zc+Zc-1] = temp;
+  // parity check part
+
+  if (gen_code==1)
+  {
+    char fname[100];
+    sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc);
+    FILE *fd=fopen(fname,"w");
+    AssertFatal(fd!=NULL,"cannot open %s\n",fname);
+    sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc);
+    FILE *fd2=fopen(fname,"w");
+    AssertFatal(fd2!=NULL,"cannot open %s\n",fname);
+
+    int shift;
+    char data_type[100];
+    char xor_command[100];
+    int mask;
+
+
+
+
+    fprintf(fd,"#include \"PHY/sse_intrin.h\"\n");
+    fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n");
+
+    if ((Zc&31)==0) {
+      shift=5; // AVX2 - 256-bit SIMD
+      mask=31;
+      strcpy(data_type,"__m256i");
+      strcpy(xor_command,"_mm256_xor_si256");
     }
+    else if ((Zc&15)==0) {
+      shift=4; // SSE4 - 128-bit SIMD
+      mask=15;
+      strcpy(data_type,"__m128i");
+      strcpy(xor_command,"_mm_xor_si128");
 
-    // calculate each row in base graph
-    for (i1=0; i1 < nrows-no_punctured_columns; i1++)
+    }
+    else if ((Zc&7)==0) {
+      shift=3; // MMX  - 64-bit SIMD
+      mask=7;
+      strcpy(data_type,"__m64");
+      strcpy(xor_command,"_mm_xor_si64"); 
+    }
+    else {
+      shift=0;                 // no SIMD
+      mask=0;
+      strcpy(data_type,"uint8_t");
+      strcpy(xor_command,"scalar_xor");
+      fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n");
+      fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n");
+    }
+    fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc);
+    fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc);
+    fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc);
+    fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc);
+    fprintf(fd,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
+    fprintf(fd2,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
+    fprintf(fd,"  %s *c2,*d2;\n\n",data_type);
+    fprintf(fd2,"  %s *c2,*d2;\n\n",data_type);
+    fprintf(fd,"  int i2;\n");
+    fprintf(fd2,"  int i2;\n");
+    fprintf(fd,"  for (i2=0; i2<%d; i2++) {\n",Zc>>shift);
+    if (shift > 0)
+      fprintf(fd2,"  for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1));
+    for (i2=0; i2 < 1; i2++)
     {
-      channel_temp=0;
-      for (i3=0; i3 < Kb; i3++)
-      {
-        temp_prime=i1 * ncols + i3;
+      //t=Kb*Zc+i2;
+    
+      // calculate each row in base graph
+     
 
-        for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
+      fprintf(fd,"     c2=&csimd[i2];\n");
+      fprintf(fd,"     d2=&dsimd[i2];\n");
+      fprintf(fd2,"     c2=&csimd[i2];\n");
+      fprintf(fd2,"     d2=&dsimd[i2];\n");
+
+      for (i1=0; i1 < nrows; i1++)
+
+      {
+        channel_temp=0;
+        fprintf(fd,"\n//row: %d\n",i1);
+        fprintf(fd2,"\n//row: %d\n",i1);
+	fprintf(fd,"     d2[%d]=",(Zc*i1)>>shift);
+	fprintf(fd2,"     d2[%d]=",(Zc*i1)>>(shift-1));
+
+        nind=0;
+
+        for (i3=0; i3 < ncols; i3++)
         {
-          channel_temp = channel_temp ^ c[ i3*Zc + Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ] ];
+          temp_prime=i1 * ncols + i3;
+
+
+	  for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
+	    {
+	          
+	      var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc);
+	      int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc;
+	      
+	      indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift);
+	      indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1));
+	      
+	    }
+	  
+
         }
+	for (i4=0;i4gen_code);
+}
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
deleted file mode 100644
index ef207b6cdc..0000000000
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c
+++ /dev/null
@@ -1,667 +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 ldpc_encoder2.c
- * \brief Defines the optimized LDPC encoder
- * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
- * \email openair_tech@eurecom.fr
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "assertions.h"
-#include "common/utils/LOG/log.h"
-#include "PHY/TOOLS/time_meas.h"
-#include "defs.h"
-
-//#define DEBUG_LDPC
-
-#include "ldpc384_byte.c"
-#include "ldpc352_byte.c"
-#include "ldpc320_byte.c"
-#include "ldpc288_byte.c"
-#include "ldpc256_byte.c"
-#include "ldpc240_byte.c"
-#include "ldpc224_byte.c"
-#include "ldpc208_byte.c"
-#include "ldpc192_byte.c"
-#include "ldpc176_byte.c"
-#include "ldpc_BG2_Zc384_byte.c"
-#include "ldpc_BG2_Zc352_byte.c"
-#include "ldpc_BG2_Zc320_byte.c"
-#include "ldpc_BG2_Zc288_byte.c"
-#include "ldpc_BG2_Zc256_byte.c"
-#include "ldpc_BG2_Zc240_byte.c"
-#include "ldpc_BG2_Zc224_byte.c"
-#include "ldpc_BG2_Zc208_byte.c"
-#include "ldpc_BG2_Zc192_byte.c"
-#include "ldpc_BG2_Zc176_byte.c"
-#include "ldpc_BG2_Zc160_byte.c"
-#include "ldpc_BG2_Zc144_byte.c"
-#include "ldpc_BG2_Zc128_byte.c"
-#include "ldpc_BG2_Zc120_byte.c"
-#include "ldpc_BG2_Zc112_byte.c"
-#include "ldpc_BG2_Zc104_byte.c"
-#include "ldpc_BG2_Zc96_byte.c"
-#include "ldpc_BG2_Zc88_byte.c"
-#include "ldpc_BG2_Zc80_byte.c"
-#include "ldpc_BG2_Zc72_byte.c"
-
-
-
-void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb)
-{
-
-  if (BG==1)
-  {
-    switch (Zc)
-    {
-    case 2: break;
-    case 3: break;
-    case 4: break;
-    case 5: break;
-    case 6: break;
-    case 7: break;
-    case 8: break;
-    case 9: break;
-    case 10: break;
-    case 11: break;
-    case 12: break;
-    case 13: break;
-    case 14: break;
-    case 15: break;
-    case 16: break;
-    case 18: break;
-    case 20: break;
-    case 22: break;
-    case 24: break;      
-    case 26: break;
-    case 28: break;
-    case 30: break;
-    case 32: break;
-    case 36: break;
-    case 40: break;
-    case 44: break;
-    case 48: break;
-    case 52: break;
-    case 56: break;
-    case 60: break;
-    case 64: break;
-    case 72: break;
-    case 80: break;   
-    case 88: break;   
-    case 96: break;
-    case 104: break;
-    case 112: break;
-    case 120: break;
-    case 128: break;
-    case 144: break;
-    case 160: break;
-    case 176: ldpc176_byte(c,d); break;
-    case 192: ldpc192_byte(c,d); break;
-    case 208: ldpc208_byte(c,d); break;
-    case 224: ldpc224_byte(c,d); break;
-    case 240: ldpc240_byte(c,d); break;
-    case 256: ldpc256_byte(c,d); break;
-    case 288: ldpc288_byte(c,d); break;
-    case 320: ldpc320_byte(c,d); break;
-    case 352: ldpc352_byte(c,d); break;
-    case 384: ldpc384_byte(c,d); break;
-    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
-    }
-  }
-  else if (BG==2) {
-    switch (Zc)
-    {
-    case 2: break;
-    case 3: break;
-    case 4: break;
-    case 5: break;
-    case 6: break;
-    case 7: break;
-    case 8: break;
-    case 9: break;
-    case 10: break;
-    case 11: break;
-    case 12: break;
-    case 13: break;
-    case 14: break;
-    case 15: break;
-    case 16: break;
-    case 18: break;
-    case 20: break;
-    case 22: break;
-    case 24: break;      
-    case 26: break;
-    case 28: break;
-    case 30: break;
-    case 32: break;
-    case 36: break;
-    case 40: break;
-    case 44: break;
-    case 48: break;
-    case 52: break;
-    case 56: break;
-    case 60: break;
-    case 64: break;
-    case 72: ldpc_BG2_Zc72_byte(c,d); break;
-    case 80: ldpc_BG2_Zc80_byte(c,d); break;   
-    case 88: ldpc_BG2_Zc88_byte(c,d); break;   
-    case 96: ldpc_BG2_Zc96_byte(c,d); break;
-    case 104: ldpc_BG2_Zc104_byte(c,d); break;
-    case 112: ldpc_BG2_Zc112_byte(c,d); break;
-    case 120: ldpc_BG2_Zc120_byte(c,d); break;
-    case 128: ldpc_BG2_Zc128_byte(c,d); break;
-    case 144: ldpc_BG2_Zc144_byte(c,d); break;
-    case 160: ldpc_BG2_Zc160_byte(c,d); break;
-    case 176: ldpc_BG2_Zc176_byte(c,d); break;
-    case 192: ldpc_BG2_Zc192_byte(c,d); break;
-    case 208: ldpc_BG2_Zc208_byte(c,d); break;
-    case 224: ldpc_BG2_Zc224_byte(c,d); break;
-    case 240: ldpc_BG2_Zc240_byte(c,d); break;
-    case 256: ldpc_BG2_Zc256_byte(c,d); break;
-    case 288: ldpc_BG2_Zc288_byte(c,d); break;
-    case 320: ldpc_BG2_Zc320_byte(c,d); break;
-    case 352: ldpc_BG2_Zc352_byte(c,d); break;
-    case 384: ldpc_BG2_Zc384_byte(c,d); break;
-    default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
-    }
-  }
-  else {
-    AssertFatal(0,"BG %d is not supported yet\n",BG);
-  } 
-
-}
-
-
-int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
-{
-
-  short nrows=0,ncols=0;
-  int i,i1,rate=3;
-  int no_punctured_columns,removed_bit;
-
-  int simd_size;
-
-  //determine number of bits in codeword
-   //if (block_length>3840)
-   if (BG==1)
-     {
-       //BG=1;
-       nrows=46; //parity check bits
-       ncols=22; //info bits
-       rate=3;
-     }
-     //else if (block_length<=3840)
-    else if	(BG==2)
-     {
-       //BG=2;
-       nrows=42; //parity check bits
-       ncols=10; // info bits
-       rate=5;
-
-       }
-
-
-#ifdef DEBUG_LDPC
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length);
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0],test_input[1],test_input[2],test_input[3]);
-#endif
-
-  if ((Zc&31) > 0) simd_size = 16;
-  else simd_size = 32;
-
-  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
-  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
-
-  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
-
-  // calculate number of punctured bits
-  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
-  // printf("%d\n",no_punctured_columns);
-  // printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
-
-  if(tinput != NULL) start_meas(tinput);
-  for (i=0; i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-    }
-
-  if(tinput != NULL) stop_meas(tinput);
-
-  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
-    // extend matrix
-    if(tprep != NULL) start_meas(tprep);
-    for (i1=0; i1 < ncols; i1++)
-      {
-	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-      }
-    for (i1=1;i1 8 bytes, pattern repeats.
-  __m256i zero256   = _mm256_setzero_si256();
-  __m256i masks[8];
-  register __m256i c256;
-  masks[0] = _mm256_set1_epi8(0x1);
-  masks[1] = _mm256_set1_epi8(0x2);
-  masks[2] = _mm256_set1_epi8(0x4);
-  masks[3] = _mm256_set1_epi8(0x8);
-  masks[4] = _mm256_set1_epi8(0x10);
-  masks[5] = _mm256_set1_epi8(0x20);
-  masks[6] = _mm256_set1_epi8(0x40);
-  masks[7] = _mm256_set1_epi8(0x80);
-#endif
-
-  AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
-
-  //determine number of bits in codeword
-  //if (block_length>3840)
-  if (BG==1)
-    {
-      nrows=46; //parity check bits
-      ncols=22; //info bits
-      rate=3;
-    }
-    //else if (block_length<=3840)
-   else if	(BG==2)
-    {
-      //BG=2;
-      nrows=42; //parity check bits
-      ncols=10; // info bits
-      rate=5;
-
-      }
-
-#ifdef DEBUG_LDPC
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
-#endif
-
-  AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
-
-  if ((Zc&31) > 0) simd_size = 16;
-  else          simd_size = 32;
-
-  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
-  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
-
-  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
-
-  // calculate number of punctured bits
-  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
-  // printf("%d\n",no_punctured_columns);
-  // printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
-
-  if(tinput != NULL) start_meas(tinput);
-#if 0
-  for (i=0; i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << j);
-    }
-  }
-#else
-#ifdef __AVX2__
-  for (i=0; i>5; i++) {
-    c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]);
-    for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << j);
-    }
-  }
-#else
-  AssertFatal(1==0,"Need AVX2 for this\n");
-#endif
-#endif
-
-  if(tinput != NULL) stop_meas(tinput);
-
-  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
-    // extend matrix
-    if(tprep != NULL) start_meas(tprep);
-    for (i1=0; i1 < ncols; i1++)
-      {
-	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-      }
-    for (i1=1;i1>5;
-    uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
-    __m256i *c256p = (__m256i *)&c[2*Zc];
-    __m256i *d256p = (__m256i *)&d[0];
-    //  if (((block_length-(2*Zc))&31)>0) l1++;
-    
-    for (i=0;i0) l2++;
-    
-    for (i1=0;i1>j)&1;
-    for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
-      for (j=0; j>j)&1;
-    }
-
-#else
-    AssertFatal(1==0,"Need AVX2 for now\n");
-#endif
-
-  if(toutput != NULL) stop_meas(toutput);
-  return 0;
-}
-
-int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
-{
-
-  short nrows=0,ncols=0;
-  int i,i1,j,rate=3;
-  int no_punctured_columns,removed_bit;
-  //Table of possible lifting sizes
-  char temp;
-  int simd_size;
-  unsigned int macro_segment, macro_segment_end;
-
-  
-  macro_segment = 8*macro_num;
-  // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
-  macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments);
-  ///printf("macro_segment: %d\n", macro_segment);
-  ///printf("macro_segment_end: %d\n", macro_segment_end );
-
-#ifdef __AVX2__
-  __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
-  __m256i andmask  = _mm256_set1_epi64x(0x0102040810204080);  // every 8 bits -> 8 bytes, pattern repeats.
-  __m256i zero256   = _mm256_setzero_si256();
-  __m256i masks[8];
-  register __m256i c256;
-  masks[0] = _mm256_set1_epi8(0x1);
-  masks[1] = _mm256_set1_epi8(0x2);
-  masks[2] = _mm256_set1_epi8(0x4);
-  masks[3] = _mm256_set1_epi8(0x8);
-  masks[4] = _mm256_set1_epi8(0x10);
-  masks[5] = _mm256_set1_epi8(0x20);
-  masks[6] = _mm256_set1_epi8(0x40);
-  masks[7] = _mm256_set1_epi8(0x80);
-#endif
-
-
-
-  //determine number of bits in codeword
-  if (BG==1)
-    {
-      nrows=46; //parity check bits
-      ncols=22; //info bits
-      rate=3;
-    }
-    else if (BG==2)
-    {
-      nrows=42; //parity check bits
-      ncols=10; // info bits
-      rate=5;
-    }
-
-#ifdef DEBUG_LDPC
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
-  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
-#endif
-
-  AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
-
-  if ((Zc&31) > 0) simd_size = 16;
-  else          simd_size = 32;
-
-  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
-  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
-
-  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
-
-  // calculate number of punctured bits
-  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
-  //printf("%d\n",no_punctured_columns);
-  //printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
-
-  if(tinput != NULL) start_meas(tinput);
-#if 0
-  for (i=0; i>(i&7);
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << (j-macro_segment));
-    }
-  }
-#else
-#ifdef __AVX2__
-  for (i=0; i>5; i++) {
-    c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
-    //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
-      //printf("c(%d,%d)=%d\n",j,i,temp);
-      c[i] |= (temp << (j-macro_segment));
-    }
-  }
-#else
-  AssertFatal(1==0,"Need AVX2 for this\n");
-#endif
-#endif
-
-  if(tinput != NULL) stop_meas(tinput);
-
-  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
-    // extend matrix
-    if(tprep != NULL) start_meas(tprep);
-    for (i1=0; i1 < ncols; i1++)
-      {
-	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
-      }
-    for (i1=1;i1>5;
-    uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
-    __m256i *c256p = (__m256i *)&c[2*Zc];
-    __m256i *d256p = (__m256i *)&d[0];
-    //  if (((block_length-(2*Zc))&31)>0) l1++;
-
-    for (i=0;i0) l2++;
-
-    for (i1=0;i1>(j-macro_segment))&1;
-    for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
-      //for (j=0; j>(j-macro_segment))&1;
-    }
-
-#else
-    AssertFatal(1==0,"Need AVX2 for now\n");
-#endif
-
-  if(toutput != NULL) stop_meas(toutput);
-  return 0;
-}
-
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
new file mode 100644
index 0000000000..7da265494a
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c
@@ -0,0 +1,146 @@
+/*
+ * 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 ldpc_encoder2.c
+ * \brief Defines the optimized LDPC encoder
+ * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
+ * \email openair_tech@eurecom.fr
+ * \date 27-03-2018
+ * \version 1.0
+ * \note
+ * \warning
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#include "PHY/TOOLS/time_meas.h"
+#include "openair1/PHY/CODING/nrLDPC_defs.h"
+#include "ldpc_encode_parity_check.c"
+#include "ldpc_generate_coefficient.c"
+//#define DEBUG_LDPC
+
+
+
+
+
+int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp)
+{
+
+  short nrows=0,ncols=0;
+  int i,i1,rate=3;
+  int no_punctured_columns,removed_bit;
+
+  int simd_size;
+
+  //determine number of bits in codeword
+   //if (block_length>3840)
+   if (BG==1)
+     {
+       //BG=1;
+       nrows=46; //parity check bits
+       ncols=22; //info bits
+       rate=3;
+     }
+     //else if (block_length<=3840)
+    else if	(BG==2)
+     {
+       //BG=2;
+       nrows=42; //parity check bits
+       ncols=10; // info bits
+       rate=5;
+
+       }
+
+
+#ifdef DEBUG_LDPC
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length);
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
+#endif
+
+  if ((Zc&31) > 0) simd_size = 16;
+  else simd_size = 32;
+
+  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
+
+  // calculate number of punctured bits
+  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+  // printf("%d\n",no_punctured_columns);
+  // printf("%d\n",removed_bit);
+  // unpack input
+  memset(c,0,sizeof(unsigned char) * ncols * Zc);
+  memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+  if(impp->tinput != NULL) start_meas(impp->tinput);
+  for (i=0; i>(i&7)))>>(7-(i&7));
+      //printf("c(%d,%d)=%d\n",j,i,temp);
+    }
+
+  if(impp->tinput != NULL) stop_meas(impp->tinput);
+
+  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
+    // extend matrix
+    if(impp->tprep != NULL) start_meas(impp->tprep);
+    for (i1=0; i1 < ncols; i1++)
+      {
+	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+      }
+    for (i1=1;i1tprep != NULL) stop_meas(impp->tprep);
+    //parity check part
+    if(impp->tparity != NULL) start_meas(impp->tparity);
+    encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
+    if(impp->tparity != NULL) stop_meas(impp->tparity);
+  }
+  else {
+    if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
+      printf("Problem with encoder\n");
+      return(-1);
+    }
+  }
+  if(impp->toutput != NULL) start_meas(impp->toutput);
+  // information part and puncture columns
+  memcpy(&channel_input[0][0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
+  memcpy(&channel_input[0][block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
+
+  if(impp->toutput != NULL) stop_meas(impp->toutput);
+  return 0;
+}
+
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c
new file mode 100644
index 0000000000..a974e86e27
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8seg.c
@@ -0,0 +1,225 @@
+/*
+ * 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 ldpc_encoder2.c
+ * \brief Defines the optimized LDPC encoder
+ * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
+ * \email openair_tech@eurecom.fr
+ * \date 27-03-2018
+ * \version 1.0
+ * \note
+ * \warning
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#include "PHY/TOOLS/time_meas.h"
+#include "openair1/PHY/CODING/nrLDPC_defs.h"
+//#define DEBUG_LDPC
+#include "ldpc_encode_parity_check.c" 
+#include "ldpc_generate_coefficient.c"
+
+
+
+int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp)
+{
+
+  short nrows=0,ncols=0;
+  int i,i1,j,rate=3;
+  int no_punctured_columns,removed_bit;
+  char temp;
+  int simd_size;
+
+#ifdef __AVX2__
+  __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
+  __m256i andmask  = _mm256_set1_epi64x(0x0102040810204080);  // every 8 bits -> 8 bytes, pattern repeats.
+  __m256i zero256   = _mm256_setzero_si256();
+  __m256i masks[8];
+  register __m256i c256;
+  masks[0] = _mm256_set1_epi8(0x1);
+  masks[1] = _mm256_set1_epi8(0x2);
+  masks[2] = _mm256_set1_epi8(0x4);
+  masks[3] = _mm256_set1_epi8(0x8);
+  masks[4] = _mm256_set1_epi8(0x10);
+  masks[5] = _mm256_set1_epi8(0x20);
+  masks[6] = _mm256_set1_epi8(0x40);
+  masks[7] = _mm256_set1_epi8(0x80);
+#endif
+
+  AssertFatal((impp->n_segments>0&&impp->n_segments<=8),"0 < n_segments %d <= 8\n",impp->n_segments);
+
+  //determine number of bits in codeword
+  //if (block_length>3840)
+  if (BG==1)
+    {
+      nrows=46; //parity check bits
+      ncols=22; //info bits
+      rate=3;
+    }
+    //else if (block_length<=3840)
+   else if	(BG==2)
+    {
+      //BG=2;
+      nrows=42; //parity check bits
+      ncols=10; // info bits
+      rate=5;
+
+      }
+
+#ifdef DEBUG_LDPC
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
+#endif
+
+  AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
+
+  if ((Zc&31) > 0) simd_size = 16;
+  else          simd_size = 32;
+
+  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
+
+  // calculate number of punctured bits
+  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+  // printf("%d\n",no_punctured_columns);
+  // printf("%d\n",removed_bit);
+  // unpack input
+  memset(c,0,sizeof(unsigned char) * ncols * Zc);
+  memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+  if(impp->tinput != NULL) start_meas(impp->tinput);
+#if 0
+  for (i=0; i>(i&7)))>>(7-(i&7));
+      //printf("c(%d,%d)=%d\n",j,i,temp);
+      c[i] |= (temp << j);
+    }
+  }
+#else
+#ifdef __AVX2__
+  for (i=0; i>5; i++) {
+    c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]);
+    for (j=1; jn_segments; j++) {
+      c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[j])[i]), shufmask),andmask),zero256),masks[j]),c256);
+    }
+    ((__m256i *)c)[i] = c256;
+  }
+
+  for (i=(block_length>>5)<<5;in_segments; j++) {
+
+      temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
+      //printf("c(%d,%d)=%d\n",j,i,temp);
+      c[i] |= (temp << j);
+    }
+  }
+#else
+  AssertFatal(1==0,"Need AVX2 for this\n");
+#endif
+#endif
+
+  if(impp->tinput != NULL) stop_meas(impp->tinput);
+
+  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { 
+    // extend matrix
+    if(impp->tprep != NULL) start_meas(impp->tprep);
+    for (i1=0; i1 < ncols; i1++)
+      {
+	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+      }
+    for (i1=1;i1tprep != NULL) stop_meas(impp->tprep);
+    //parity check part
+    if(impp->tparity != NULL) start_meas(impp->tparity);
+    encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
+    if(impp->tparity != NULL) stop_meas(impp->tparity);
+  }
+  else {
+    if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
+      printf("Problem with encoder\n");
+      return(-1);
+    }
+  }
+  if(impp->toutput != NULL) start_meas(impp->toutput);
+  // information part and puncture columns
+  /*
+  memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
+  memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
+  */
+#ifdef __AVX2__
+  if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
+    //AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
+    //AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
+    uint32_t l1 = (block_length-(2*Zc))>>5;
+    uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
+    __m256i *c256p = (__m256i *)&c[2*Zc];
+    __m256i *d256p = (__m256i *)&d[0];
+    //  if (((block_length-(2*Zc))&31)>0) l1++;
+    
+    for (i=0;in_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
+    
+    //  if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
+    
+    for (i1=0;i1n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
+  }
+  else {
+#ifdef DEBUG_LDPC
+  LOG_W(PHY,"using non-optimized version\n");
+#endif
+    // do non-SIMD version
+    for (i=0;i<(block_length-2*Zc);i++) 
+      for (j=0; jn_segments; j++)
+	channel_input[j][i] = (c[2*Zc+i]>>j)&1;
+    for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
+      for (j=0; jn_segments; j++)
+	channel_input[j][block_length-2*Zc+i] = (d[i]>>j)&1;
+    }
+
+#else
+    AssertFatal(1==0,"Need AVX2 for now\n");
+#endif
+
+  if(impp->toutput != NULL) stop_meas(impp->toutput);
+  return 0;
+}
+
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
new file mode 100644
index 0000000000..28ab5b5029
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
@@ -0,0 +1,238 @@
+/*
+ * 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 ldpc_encoder2.c
+ * \brief Defines the optimized LDPC encoder
+ * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom)
+ * \email openair_tech@eurecom.fr
+ * \date 27-03-2018
+ * \version 1.0
+ * \note
+ * \warning
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#include "PHY/TOOLS/time_meas.h"
+#include "openair1/PHY/CODING/nrLDPC_defs.h"
+
+//#define DEBUG_LDPC
+
+#include "ldpc_encode_parity_check.c"
+#include "ldpc_generate_coefficient.c"
+
+
+int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp)
+{
+
+  short nrows=0,ncols=0;
+  int i,i1,j,rate=3;
+  int no_punctured_columns,removed_bit;
+  //Table of possible lifting sizes
+  char temp;
+  int simd_size;
+  unsigned int macro_segment, macro_segment_end;
+
+  
+  macro_segment = 8*impp->macro_num;
+  // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
+  macro_segment_end = macro_segment + (impp->n_segments > 8 ? 8 : impp->n_segments);
+  ///printf("macro_segment: %d\n", macro_segment);
+  ///printf("macro_segment_end: %d\n", macro_segment_end );
+
+#ifdef __AVX2__
+  __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
+  __m256i andmask  = _mm256_set1_epi64x(0x0102040810204080);  // every 8 bits -> 8 bytes, pattern repeats.
+  __m256i zero256   = _mm256_setzero_si256();
+  __m256i masks[8];
+  register __m256i c256;
+  masks[0] = _mm256_set1_epi8(0x1);
+  masks[1] = _mm256_set1_epi8(0x2);
+  masks[2] = _mm256_set1_epi8(0x4);
+  masks[3] = _mm256_set1_epi8(0x8);
+  masks[4] = _mm256_set1_epi8(0x10);
+  masks[5] = _mm256_set1_epi8(0x20);
+  masks[6] = _mm256_set1_epi8(0x40);
+  masks[7] = _mm256_set1_epi8(0x80);
+#endif
+
+
+
+  //determine number of bits in codeword
+  if (BG==1)
+    {
+      nrows=46; //parity check bits
+      ncols=22; //info bits
+      rate=3;
+    }
+    else if (BG==2)
+    {
+      nrows=42; //parity check bits
+      ncols=10; // info bits
+      rate=5;
+    }
+
+#ifdef DEBUG_LDPC
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
+  LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
+#endif
+
+  AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
+
+  if ((Zc&31) > 0) simd_size = 16;
+  else          simd_size = 32;
+
+  unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+  unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+  unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32)));      //double size matrix of c
+
+  // calculate number of punctured bits
+  no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+  //printf("%d\n",no_punctured_columns);
+  //printf("%d\n",removed_bit);
+  // unpack input
+  memset(c,0,sizeof(unsigned char) * ncols * Zc);
+  memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+  if(impp->tinput != NULL) start_meas(impp->tinput);
+#if 0
+  for (i=0; i>(i&7);
+      //printf("c(%d,%d)=%d\n",j,i,temp);
+      c[i] |= (temp << (j-macro_segment));
+    }
+  }
+#else
+#ifdef __AVX2__
+  for (i=0; i>5; i++) {
+    c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
+    //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
+      //printf("c(%d,%d)=%d\n",j,i,temp);
+      c[i] |= (temp << (j-macro_segment));
+    }
+  }
+#else
+  AssertFatal(1==0,"Need AVX2 for this\n");
+#endif
+#endif
+
+  if(impp->tinput != NULL) stop_meas(impp->tinput);
+
+  if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
+    // extend matrix
+    if(impp->tprep != NULL) start_meas(impp->tprep);
+    for (i1=0; i1 < ncols; i1++)
+      {
+	memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+	memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+      }
+    for (i1=1;i1tprep != NULL) stop_meas(impp->tprep);
+    //parity check part
+    if(impp->tparity != NULL) start_meas(impp->tparity);
+    encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
+    if(impp->tparity != NULL) stop_meas(impp->tparity);
+  }
+  else {
+    if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
+      printf("Problem with encoder\n");
+      return(-1);
+    }
+  }
+  if(impp->toutput != NULL) start_meas(impp->toutput);
+  // information part and puncture columns
+  /*
+  memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
+  memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
+  */
+#ifdef __AVX2__
+  if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
+    //AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
+    //AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
+    uint32_t l1 = (block_length-(2*Zc))>>5;
+    uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
+    __m256i *c256p = (__m256i *)&c[2*Zc];
+    __m256i *d256p = (__m256i *)&d[0];
+    //  if (((block_length-(2*Zc))&31)>0) l1++;
+
+    for (i=0;i0) l2++;
+
+    for (i1=0;i1>(j-macro_segment))&1;
+    for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
+      //for (j=0; j>(j-macro_segment))&1;
+    }
+
+#else
+    AssertFatal(1==0,"Need AVX2 for now\n");
+#endif
+
+  if(impp->toutput != NULL) stop_meas(impp->toutput);
+  return 0;
+}
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
index 5988c9067d..3d26a19063 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
@@ -35,9 +35,8 @@
 #include 
 #include "Gen_shift_value.h"
 #include "assertions.h"
-#include "defs.h"
 
-short *choose_generator_matrix(short BG,short Zc)
+static inline short *choose_generator_matrix(short BG,short Zc)
 {
   short *Gen_shift_values = NULL;
 
@@ -361,237 +360,70 @@ short *choose_generator_matrix(short BG,short Zc)
   return Gen_shift_values;
 }
 
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code)
+static inline int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb,short block_length)
 {
-  unsigned char c[22*384]; //padded input, unpacked, max size
-  unsigned char d[68*384]; //coded output, unpacked, max size
+  short *Gen_shift_values=choose_generator_matrix(BG,Zc);
+  short *no_shift_values, *pointer_shift_values;
+  int no_punctured_columns;
+  short nrows,ncols,rate=3;
+  int i1,i2,i3,i4,i5,temp_prime;
   unsigned char channel_temp,temp;
-  short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
 
-  short nrows = 46;//parity check bits
-  short ncols = 22;//info bits
-
-
-  int i,i1,i2,i3,i4,i5,temp_prime,var;
-  int no_punctured_columns,removed_bit,rate=3;
-  int nind=0;
-  int indlist[1000];
-  int indlist2[1000];
-
-  //determine number of bits in codeword
-  //if (block_length>3840)
-     if (BG==1)
-       {
-         nrows=46; //parity check bits
-         ncols=22; //info bits
-         rate=3;
-       }
-       //else if (block_length<=3840)
-      else if	(BG==2)
-       {
-         //BG=2;
-         nrows=42; //parity check bits
-         ncols=10; // info bits
-         rate=5;
-         }
-
-  Gen_shift_values=choose_generator_matrix(BG,Zc);
-  if (Gen_shift_values==NULL) {
-    printf("ldpc_encoder_orig: could not find generator matrix\n");
-    return(-1);
-  }
-
-  //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb);
-
-  // load base graph of generator matrix
   if (BG==1)
   {
     no_shift_values=(short *) no_shift_values_BG1;
     pointer_shift_values=(short *) pointer_shift_values_BG1;
+      nrows=46; //parity check bits
+      ncols=22; //info bits
+      rate=3;
   }
   else if (BG==2)
   {
     no_shift_values=(short *) no_shift_values_BG2;
     pointer_shift_values=(short *) pointer_shift_values_BG2;
+      nrows=42; //parity check bits
+      ncols=10; //info bits
+      rate=5;
   }
   else {
-    AssertFatal(0,"BG %d is not supported yet\n",BG);
+    printf("problem with BG\n");
+    return(-1);
   }
-  
+
+
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
-  removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate);
-  //printf("%d\n",no_punctured_columns);
-  //printf("%d\n",removed_bit);
-  // unpack input
-  memset(c,0,sizeof(unsigned char) * ncols * Zc);
-  memset(d,0,sizeof(unsigned char) * nrows * Zc);
 
-  for (i=0; i>7&1;
-    c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7));
-  }
+    //t=Kb*Zc+i2;
 
-  // parity check part
-
-  if (gen_code==1)
-  {
-    char fname[100];
-    sprintf(fname,"ldpc_BG%d_Zc%d_byte.c",BG,Zc);
-    FILE *fd=fopen(fname,"w");
-    AssertFatal(fd!=NULL,"cannot open %s\n",fname);
-    sprintf(fname,"ldpc_BG%d_Zc%d_16bit.c",BG,Zc);
-    FILE *fd2=fopen(fname,"w");
-    AssertFatal(fd2!=NULL,"cannot open %s\n",fname);
-
-    int shift;
-    char data_type[100];
-    char xor_command[100];
-    int mask;
-
-
-
-
-    fprintf(fd,"#include \"PHY/sse_intrin.h\"\n");
-    fprintf(fd2,"#include \"PHY/sse_intrin.h\"\n");
-
-    if ((Zc&31)==0) {
-      shift=5; // AVX2 - 256-bit SIMD
-      mask=31;
-      strcpy(data_type,"__m256i");
-      strcpy(xor_command,"_mm256_xor_si256");
-    }
-    else if ((Zc&15)==0) {
-      shift=4; // SSE4 - 128-bit SIMD
-      mask=15;
-      strcpy(data_type,"__m128i");
-      strcpy(xor_command,"_mm_xor_si128");
-
-    }
-    else if ((Zc&7)==0) {
-      shift=3; // MMX  - 64-bit SIMD
-      mask=7;
-      strcpy(data_type,"__m64");
-      strcpy(xor_command,"_mm_xor_si64"); 
-    }
-    else {
-      shift=0;                 // no SIMD
-      mask=0;
-      strcpy(data_type,"uint8_t");
-      strcpy(xor_command,"scalar_xor");
-      fprintf(fd,"#define scalar_xor(a,b) ((a)^(b))\n");
-      fprintf(fd2,"#define scalar_xor(a,b) ((a)^(b))\n");
-    }
-    fprintf(fd,"// generated code for Zc=%d, byte encoding\n",Zc);
-    fprintf(fd2,"// generated code for Zc=%d, 16bit encoding\n",Zc);
-    fprintf(fd,"static inline void ldpc_BG%d_Zc%d_byte(uint8_t *c,uint8_t *d) {\n",BG,Zc);
-    fprintf(fd2,"static inline void ldpc_BG%d_Zc%d_16bit(uint16_t *c,uint16_t *d) {\n",BG,Zc);
-    fprintf(fd,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
-    fprintf(fd2,"  %s *csimd=(%s *)c,*dsimd=(%s *)d;\n\n",data_type,data_type,data_type);
-    fprintf(fd,"  %s *c2,*d2;\n\n",data_type);
-    fprintf(fd2,"  %s *c2,*d2;\n\n",data_type);
-    fprintf(fd,"  int i2;\n");
-    fprintf(fd2,"  int i2;\n");
-    fprintf(fd,"  for (i2=0; i2<%d; i2++) {\n",Zc>>shift);
-    if (shift > 0)
-      fprintf(fd2,"  for (i2=0; i2<%d; i2++) {\n",Zc>>(shift-1));
-    for (i2=0; i2 < 1; i2++)
+    //rotate matrix here
+    for (i5=0; i5 < Kb; i5++)
     {
-      //t=Kb*Zc+i2;
-    
-      // calculate each row in base graph
-     
-
-      fprintf(fd,"     c2=&csimd[i2];\n");
-      fprintf(fd,"     d2=&dsimd[i2];\n");
-      fprintf(fd2,"     c2=&csimd[i2];\n");
-      fprintf(fd2,"     d2=&dsimd[i2];\n");
-
-      for (i1=0; i1 < nrows; i1++)
-
-      {
-        channel_temp=0;
-        fprintf(fd,"\n//row: %d\n",i1);
-        fprintf(fd2,"\n//row: %d\n",i1);
-	fprintf(fd,"     d2[%d]=",(Zc*i1)>>shift);
-	fprintf(fd2,"     d2[%d]=",(Zc*i1)>>(shift-1));
-
-        nind=0;
-
-        for (i3=0; i3 < ncols; i3++)
-        {
-          temp_prime=i1 * ncols + i3;
-
-
-	  for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
-	    {
-	          
-	      var=(int)((i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc)/Zc);
-	      int index =var*2*Zc + (i3*Zc + (Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ]+1)%Zc) % Zc;
-	      
-	      indlist[nind] = ((index&mask)*((2*Zc)>>shift)*Kb)+(index>>shift);
-	      indlist2[nind++] = ((index&(mask>>1))*((2*Zc)>>(shift-1))*Kb)+(index>>(shift-1));
-	      
-	    }
-	  
-
-        }
-	for (i4=0;i4
- * \date 27-03-2018
- * \version 1.0
- * \note
- * \warning
- */
-
-#ifndef __NR_LDPC_DECODER__H__
-#define __NR_LDPC_DECODER__H__
-
-#include "nrLDPC_types.h"
-#include "nrLDPC_init_mem.h"
-
-/**
-   \brief LDPC decoder
-   \param p_decParams LDPC decoder parameters
-   \param p_llr Input LLRs
-   \param p_llrOut Output vector
-   \param p_profiler LDPC profiler statistics
-*/
-int32_t nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_llrOut, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler);
-
-#endif
+#ifdef LDPC_LOADER
+nrLDPC_decoderfunc_t nrLDPC_decoder;
+nrLDPC_encoderfunc_t nrLDPC_encoder;
+#else
+/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
+extern int load_nrLDPClib(void) ;
+extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest
+/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
+extern nrLDPC_decoderfunc_t nrLDPC_decoder;
+extern nrLDPC_encoderfunc_t nrLDPC_encoder;
+// inline functions:
+#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h"
+#endif
\ No newline at end of file
diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c
new file mode 100644
index 0000000000..a74bdf7bd1
--- /dev/null
+++ b/openair1/PHY/CODING/nrLDPC_load.c
@@ -0,0 +1,76 @@
+/*
+ * 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 openair1/PHY/CODING/coding_nr_load.c
+ * \brief: load library implementing coding/decoding algorithms
+ * \author Francois TABURET
+ * \date 2020
+ * \version 0.1
+ * \company NOKIA BellLabs France
+ * \email: francois.taburet@nokia-bell-labs.com
+ * \note
+ * \warning
+ */
+#define _GNU_SOURCE 
+#include 
+#include 
+#include 
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#define LDPC_LOADER
+#include "PHY/CODING/nrLDPC_extern.h"
+#include "common/config/config_userapi.h" 
+#include "common/utils/load_module_shlib.h" 
+
+
+/* function description array, to be used when loading the encoding/decoding shared lib */
+static loader_shlibfunc_t shlib_fdesc[2];
+
+char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"};
+
+int load_nrLDPClib(void) {
+	 char *ptr = (char*)config_get_if();
+     if ( ptr==NULL )  {// phy simulators, config module possibly not loaded
+     	 load_configmodule(3,(char **)arg,CONFIG_ENABLECMDLINEONLY) ;
+     	 logInit();
+     }	 
+     shlib_fdesc[0].fname = "nrLDPC_decod";
+     shlib_fdesc[1].fname = "nrLDPC_encod";
+     int ret=load_module_shlib("ldpc",shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
+     AssertFatal( (ret >= 0),"Error loading ldpc decoder");
+     nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr;
+     nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr;
+return 0;
+}
+
+int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) {
+	loader_shlibfunc_t shlib_encoder_fdesc;
+
+     shlib_encoder_fdesc.fname = "nrLDPC_encod";
+     char libpath[64];
+     sprintf(libpath,"ldpc%s",libversion);
+     int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL);
+     AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath);
+     *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr;
+return 0;
+}
+
+
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index f0ad3cbaae..4798f9a9e4 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -31,6 +31,7 @@
 #include "TDD-Config.h"
 #include "MBSFN-SubframeConfigList.h"*/
 #include "openair1/PHY/defs_RU.h"
+#include "openair1/PHY/CODING/nrLDPC_extern.h"
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "assertions.h"
 #include 
@@ -115,6 +116,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
   crcTableInit();
   init_dfts();
+  load_nrLDPClib();
   // PBCH DMRS gold sequences generation
   nr_init_pbch_dmrs(gNB);
   //PDCCH DMRS init
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index dae5586224..17de9c02af 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -35,12 +35,11 @@
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/NR_TRANSPORT/nr_transport.h"
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 #include "PHY/NR_TRANSPORT/nr_dlsch.h"
 #include "SCHED_NR/sched_nr.h"
-#include "defs.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "common/utils/LOG/log.h"
 #include 
@@ -404,9 +403,11 @@ int nr_dlsch_encoding(unsigned char *a,
       //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0);
       //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
     }
-
+    encoder_implemparams_t impp;
+    impp.n_segments=dlsch->harq_processes[harq_pid]->C;
     for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
-      ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
+      impp.macro_num=j;
+      nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp);
     }
 
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 3945439a45..c58941b077 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -37,8 +37,7 @@
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 #include "PHY/NR_TRANSPORT/nr_ulsch.h"
 #include "PHY/NR_TRANSPORT/nr_dlsch.h"
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index b3a95e313e..b81c01114d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -41,8 +41,7 @@
 #include "SCHED_NR_UE/defs.h"
 #include "SIMULATION/TOOLS/sim.h"
 #include "executables/nr-uesoftmodem.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 //#define DEBUG_DLSCH_DECODING
 //#define ENABLE_PHY_PAYLOAD_DEBUG 1
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 2eb6dcd7fe..8b80b1b219 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -36,7 +36,7 @@
 #include "PHY/CODING/coding_defs.h"
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
@@ -353,8 +353,11 @@ opp_enabled=0;
       printf("%d \n",  harq_process->d[0][cnt]);
       }
       printf("\n");*/
+    encoder_implemparams_t impp;
+    impp.n_segments=harq_process->C;
+    impp.macro_num=0;
 
-    ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
+    nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp);
 
     //stop_meas(te_stats);
     //printf("end ldpc encoder -- output\n");
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 3c0f0db8da..fc81f4d74b 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -40,7 +40,7 @@
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 #include "PHY/impl_defs_top.h"
 #include "PHY/defs_common.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
 
 #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 757ad6f75d..3066f0906f 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -37,6 +37,7 @@
 #include 
 
 #include "common_lib.h"
+#include "assertions.h"
 #include "common/utils/load_module_shlib.h"
 #include "common/utils/LOG/log.h"
 #include "targets/RT/USER/lte-softmodem.h"
@@ -91,38 +92,44 @@ int load_lib(openair0_device *device,
 {
   loader_shlibfunc_t shlib_fdesc[1];
   int ret=0;
-  char *libname;
+  char *deflibname=OAI_RF_LIBNAME;
   
   openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state));
 
   if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) {
-  	  libname=OAI_IQPLAYER_LIBNAME;
+  	  deflibname=OAI_IQPLAYER_LIBNAME;
   	  shlib_fdesc[0].fname="device_init";
   	  set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT);  // softmodem has to know we use the iqplayer to workaround randomized algorithms
   } else  if ( IS_SOFTMODEM_BASICSIM ) {
-	  libname=OAI_BASICSIM_LIBNAME;
+	  deflibname=OAI_BASICSIM_LIBNAME;
 	  shlib_fdesc[0].fname="device_init";
   } else if (IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
-	  libname=OAI_RFSIM_LIBNAME;
+	  deflibname=OAI_RFSIM_LIBNAME;
 	  shlib_fdesc[0].fname="device_init";
   } else if (flag == RAU_LOCAL_RADIO_HEAD) {
 	  if (IS_SOFTMODEM_RFSIM)
-		  libname="rfsimulator";
+		  deflibname="rfsimulator";
 	  else
-          libname=OAI_RF_LIBNAME;
+          deflibname=OAI_RF_LIBNAME;
       shlib_fdesc[0].fname="device_init";
   } else {
-	  libname=OAI_TP_LIBNAME;
+	  deflibname=OAI_TP_LIBNAME;
 	  shlib_fdesc[0].fname="transport_init";
   }
-  ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
+  
+  char *devname=NULL;
+  paramdef_t device_params[]=DEVICE_PARAMS_DESC ;
+  int numparams = sizeof(device_params)/sizeof(paramdef_t);
+  int devname_pidx = config_paramidx_fromname(device_params,numparams, CONFIG_DEVICEOPT_NAME);
+  device_params[devname_pidx].defstrval=deflibname;
+  
+  config_get(device_params,numparams,DEVICE_SECTION);
+  
+  ret=load_module_shlib(devname,shlib_fdesc,1,NULL);
+  AssertFatal( (ret >= 0),
+  	           "Library %s couldn't be loaded\n",devname);
 
-  if (ret < 0) {
-    LOG_E(HW,"Library %s couldn't be loaded\n",libname);
-  } else {
-    ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
-  }
-  return ret;
+  return ((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
 }
 
 
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 7e51bdc81a..ecadb68c0c 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -448,6 +448,24 @@ typedef struct {
 extern "C"
 {
 #endif
+
+
+#define  DEVICE_SECTION   "device"
+#define  CONFIG_HLP_DEVICE  "Identifies the oai device (the interface to RF) to use, the shared lib \"lib_.so\" will be loaded"
+
+#define  CONFIG_DEVICEOPT_NAME "name"
+
+/* inclusion for device configuration */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            config parameters for oai device                                                                                               */
+/*   optname                     helpstr                paramflags                      XXXptr                  defXXXval                            type           numelt   */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define DEVICE_PARAMS_DESC {\
+    { CONFIG_DEVICEOPT_NAME,      CONFIG_HLP_DEVICE,          0,                strptr:&devname,                 defstrval:NULL,         TYPE_STRING,     0}\
+}
+
+
+
 /*! \brief get device name from device type */
 char *get_devname(int devtype);
 /*! \brief Initialize openair RF target. It returns 0 if OK */
diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h
index 903dda006b..500acdd709 100644
--- a/targets/ARCH/COMMON/record_player.h
+++ b/targets/ARCH/COMMON/record_player.h
@@ -37,19 +37,6 @@
 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 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
@@ -114,7 +101,7 @@ typedef struct {
     {CONFIG_OPT_SF_LOOPS,     CONFIG_HLP_SF_LOOPS,  0,                uptr:&((*recplay_conf)->u_sf_loops),                defintval:DEF_SF_NB_LOOP,        TYPE_UINT,   0}, \
     {CONFIG_OPT_SF_RDELAY,    CONFIG_HLP_SF_RDELAY, 0,                uptr:&((*recplay_conf)->u_sf_read_delay),           defintval:DEF_SF_DELAY_READ,     TYPE_UINT,   0}, \
     {CONFIG_OPT_SF_WDELAY,    CONFIG_HLP_SF_WDELAY, 0,                uptr:&((*recplay_conf)->u_sf_write_delay),          defintval:DEF_SF_DELAY_WRITE,    TYPE_UINT,   0}, \
-  }/*! \brief USRP Configuration and state */
+  }/*! \brief Record Player Configuration and state */
 typedef struct {
   char            u_sf_filename[1024];              // subframes file path
   unsigned int    u_sf_max ;                  // max number of recorded subframes
diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c
index beb05de3fd..c4133d1b11 100644
--- a/targets/ARCH/iqplayer/iqplayer_lib.c
+++ b/targets/ARCH/iqplayer/iqplayer_lib.c
@@ -25,6 +25,7 @@
  */
 #define _LARGEFILE_SOURCE
 #define _FILE_OFFSET_BITS 64
+#define NB_ANTENNAS_RX  2
 #include 
 #include 
 #include 
@@ -45,7 +46,9 @@
 
 
 static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) {
-  AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),"iqfile doesn't seem to be compatible with oai (invalid id in header)\n");
+  AssertFatal((memcmp(iq_fh->oaiid,OAIIQFILE_ID,sizeof(OAIIQFILE_ID)) == 0),
+  	           "iqfile doesn't seem to be compatible with oai (invalid id %.4s in header)\n",
+  	           iq_fh->oaiid);
   device->type = iq_fh->devtype;
   device->openair0_cfg[0].tx_sample_advance=iq_fh->tx_sample_advance;
   device->openair0_cfg[0].tx_bw =  device->openair0_cfg[0].rx_bw = iq_fh->bw;
@@ -138,6 +141,13 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
   return 0;
 }
 
+/*! \brief start the oai iq player
+ * \param device, the hardware used
+ */
+static int trx_iqplayer_start(openair0_device *device){
+	return 0;
+}
+
 /*! \brief Terminate operation of the oai iq player
  * \param device, the hardware used
  */
@@ -287,7 +297,7 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes
 
 int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   device->openair0_cfg = openair0_cfg;
-  device->trx_start_func = NULL;
+  device->trx_start_func = trx_iqplayer_start;
   device->trx_get_stats_func = NULL;
   device->trx_reset_stats_func = NULL;
   device->trx_end_func   = trx_iqplayer_end;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index f88d98536d..6d1a3b8cb2 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2194,7 +2194,9 @@ int start_rf(RU_t *ru) {
 }
 
 int stop_rf(RU_t *ru) {
-  ru->rfdevice.trx_end_func(&ru->rfdevice);
+    if(ru->rfdevice.trx_end_func != NULL) {
+      ru->rfdevice.trx_end_func(&ru->rfdevice);
+    }
   return 0;
 }
 

From d4a81bcc0f611b70fe77c6bdf6c00845de1578df Mon Sep 17 00:00:00 2001
From: Hongzhi Wang 
Date: Mon, 9 Mar 2020 16:12:23 +0100
Subject: [PATCH 319/343] update dlsch multi thread

---
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   | 27 +++++++++++--------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 7a23ce7167..b8b5ed7654 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -581,13 +581,13 @@ 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)) {
-        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
+        LOG_I(PHY,"Segment %u CRC OK\n\033[0m",r);
         //Temporary hack
         no_iteration_ldpc = dlsch->max_ldpc_iterations;
         ret = no_iteration_ldpc;
       }
       else {
-        LOG_D(PHY,"CRC NOK\n\033[0m");
+        LOG_I(PHY,"CRC NOK\n\033[0m");
         ret = 1 + dlsch->max_ldpc_iterations;
       }
 
@@ -799,13 +799,12 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   uint32_t Tbslbrm = 950984;
   uint16_t nb_rb = 30;
   double Coderate = 0.0;
-  nfapi_nr_dl_config_dlsch_pdu_rel15_t *dl_config_pdu = &harq_processes[harq_pid]->dl_config_pdu
-  uint8_t dmrs_type = dl_config_pdu->dmrsConfigType;
+  uint8_t dmrs_type = harq_process->dmrsConfigType;
   //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==1)?6:4;
-  uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); 
+  uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos); 
 
   uint32_t i,j;
 //  int nbDlProcessing =0;
@@ -861,7 +860,8 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 
   A = harq_process->TBS;
 
-  ret = dlsch->max_ldpc_iterations;
+  ret = dlsch->max_ldpc_iterations + 1;
+  dlsch->last_iteration_cnt = ret;
 
   harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
 
@@ -929,9 +929,10 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
                       &harq_process->F,
                       p_decParams->BG);
 
-      p_decParams->Z = harq_process->Z;
 
     }
+    
+    p_decParams->Z = harq_process->Z;
 
   //printf("coderate %f kc %d \n", Coderate, kc);
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
@@ -1149,11 +1150,13 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
         pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
       }
 
-      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
+      j+=(harq_process->F>>3);
+      //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
+      for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
       {
         pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
       }
-
+      
       for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)
       {
         pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
@@ -1683,9 +1686,11 @@ void nr_dlsch_decoding_process(void *arg)
           pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
         }
 
-        for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
+        j+=(harq_process->F>>3);
+        //      for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++)
+        for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++)
         {
-          pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
+         pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
         }
 
         for (i=0, j=0; j < ((kc*p_decParams->Z)>>4);  i+=2, j++)

From 7b9be8744da4354054c0c4e4479998b839691d64 Mon Sep 17 00:00:00 2001
From: magounak 
Date: Fri, 13 Mar 2020 10:46:40 +0100
Subject: [PATCH 320/343] bug fix ue dlsch thread

---
 openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index b8b5ed7654..d3003da094 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -1483,7 +1483,7 @@ void nr_dlsch_decoding_process(void *arg)
   }    
 
   harq_process->round  =0;
-  if (harq_process->round == 0) {
+ // if (harq_process->round == 0) {
     // This is a new packet, so compute quantities regarding segmentation
 	if (A > 3824)
 	  harq_process->B = A+24;
@@ -1501,7 +1501,7 @@ 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);
 

From 9cf9ea7c99edcf1c20f3b450c5c56709c00b3ac1 Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Sat, 14 Mar 2020 13:50:07 +0100
Subject: [PATCH 321/343] remainder of merge

---
 executables/nr-softmodem.c                    | 15 -----
 executables/nr-ue.c                           | 13 +---
 executables/softmodem-common.c                | 64 -------------------
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |  3 -
 openair1/PHY/TOOLS/Makefile                   |  4 --
 5 files changed, 1 insertion(+), 98 deletions(-)

diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 4534761d87..04c515e556 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -859,10 +859,6 @@ if(!IS_SOFTMODEM_NOS1)
   if(IS_SOFTMODEM_NOS1)
 	  init_pdcp();
 
-<<<<<<< HEAD
-
-=======
->>>>>>> origin/develop
   if (RC.nb_nr_inst > 0)  {
     // don't create if node doesn't connect to RRC/S1/GTP
     AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
@@ -871,11 +867,6 @@ if(!IS_SOFTMODEM_NOS1)
     RCconfig_L1();
   }
 
-<<<<<<< HEAD
-
-  
-=======
->>>>>>> origin/develop
   /* Start the agent. If it is turned off in the configuration, it won't start */
   /*
   RCconfig_nr_flexran();
@@ -995,11 +986,6 @@ if(!IS_SOFTMODEM_NOS1)
   oai_exit=1;
   printf("oai_exit=%d\n",oai_exit);
 
-<<<<<<< HEAD
-  printf("Terminating application - oai_exit=%d\n",oai_exit);
-#endif
-  // stop threads  
-=======
   // stop threads
 /*#ifdef XFORMS
 
@@ -1022,7 +1008,6 @@ if(!IS_SOFTMODEM_NOS1)
     }
 
 #endif*/
->>>>>>> origin/develop
   printf("stopping MODEM threads\n");
   // cleanup
   stop_gNB(NB_gNB_INST);
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index d4ace2ce68..40d33b701e 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -460,7 +460,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
     LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
     //printf(">>> nr_ue_pdcch_procedures ended\n");
 #endif
-<<<<<<< HEAD
+
     if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1
       //Hardcoded rnti value
       protocol_ctxt_t ctxt;
@@ -468,18 +468,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
 				     0x1234, proc->frame_rx,
 				     proc->nr_tti_rx, 0);
       pdcp_run(&ctxt);
-      pdcp_fifo_flush_sdus(&ctxt);
     }
-=======
-  if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1
-	  //Hardcoded rnti value
-	  protocol_ctxt_t ctxt;
-	  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
-                                   0x1234, proc->frame_rx,
-                                   proc->nr_tti_rx, 0);
-	  pdcp_run(&ctxt);
-  }
->>>>>>> origin/develop
   }
 
   
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index b901fe0c64..0a4e94571f 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -61,69 +61,6 @@ softmodem_params_t *get_softmodem_params(void) {
   return &softmodem_params;
 }
 
-<<<<<<< HEAD
-void softmodem_printresources(int sig, telnet_printfunc_t pf) {
-   struct rusage usage;
-   struct timespec stop;
-
-   clock_gettime(CLOCK_BOOTTIME, &stop);
-
-   uint64_t elapse = (stop.tv_sec - start.tv_sec) ;   // in seconds
-
-
-   int st = getrusage(RUSAGE_SELF,&usage);
-   if (!st) {
-   	 pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600)));
-     pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec);
-     pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec);
-     pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss);
-     pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt);
-     pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt);
-     pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock);
-     pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock);
-     pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw);
-     pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw);
-   } 
-}
-
-void signal_handler(int sig) {
-  void *array[10];
-  size_t size;
-
-  if (sig==SIGSEGV) {
-    // get void*'s for all entries on the stack
-    size = backtrace(array, 10);
-    // print out all the frames to stderr
-    fprintf(stderr, "Error: signal %d:\n", sig);
-    backtrace_symbols_fd(array, size, 2);
-    exit(-1);
-  } else {
-  	if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL)
-  		softmodem_printresources(sig,(telnet_printfunc_t)printf);
-  	if (sig != SOFTMODEM_RTSIGNAL) {
-      printf("Linux signal %s...\n",strsignal(sig));
-      exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n");
-    }
-  }
-}
-
-
-
-void set_softmodem_sighandler(void) {
-  struct sigaction	act,oldact;
-  clock_gettime(CLOCK_BOOTTIME, &start);
-  memset(&act,0,sizeof(act));
-  act.sa_handler=signal_handler;
-  sigaction(SOFTMODEM_RTSIGNAL,&act,&oldact);
-  printf("Send signal %d to display resource usage...\n",SIGRTMIN+1);
-  signal(SIGSEGV, signal_handler);
-  signal(SIGINT,  signal_handler);
-  signal(SIGTERM, signal_handler);
-  signal(SIGABRT, signal_handler);	
-}
-#ifndef PHYSICAL_SIMULATOR
-void get_common_options(void) {
-=======
 int32_t check_execmask(uint64_t execmask) {
   char *softmodemfunc=map_int_to_str(softmodem_funcs, execmask);
   if (softmodemfunc != NULL) {
@@ -144,7 +81,6 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
 }
 
 void get_common_options(uint32_t execmask) {
->>>>>>> origin/develop
   uint32_t online_log_messages;
   uint32_t glog_level ;
   uint32_t start_telnetsrv = 0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 3030a4b974..f56dd1757d 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -727,8 +727,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
       
     }
   }
-<<<<<<< HEAD
-=======
 
 #ifdef DEBUG_ULSCH_DECODING
   LOG_I(PHY, "Decoder output (payload): \n");
@@ -739,7 +737,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   }
 #endif
 
->>>>>>> origin/develop
   ulsch->last_iteration_cnt = ret;
 
   return(ret);
diff --git a/openair1/PHY/TOOLS/Makefile b/openair1/PHY/TOOLS/Makefile
index db20bc834e..c71717dc87 100644
--- a/openair1/PHY/TOOLS/Makefile
+++ b/openair1/PHY/TOOLS/Makefile
@@ -1,9 +1,5 @@
 lte_dfts_sse4: lte_dfts.c
-<<<<<<< HEAD
-	gcc -O2 -std=gnu99 -msse4.1 -g -ggdb -o lte_dfts_sse4 lte_dfts.c time_meas.c  ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
-=======
 	gcc-7 -O3 -std=gnu99 -msse4.1 -o lte_dfts_sse4 lte_dfts.c time_meas.c  ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS
->>>>>>> origin/develop-nr
 
 lte_dfts_avx2: lte_dfts.c
 	gcc -O2 -std=gnu99 -mavx2 -g -ggdb -o lte_dfts_avx2 lte_dfts.c time_meas.c ../../SIMULATION/TOOLS/taus.c $$OPENAIR_HOME/common/utils/backtrace.c -I$$OPENAIR_HOME -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR -I$$OPENAIR2_DIR/COMMON -I$$OPENAIR_HOME/common/utils -I$$OPENAIR_HOME/common/utils/T -DMR_MAIN -DNB_ANTENNAS_RX=1 -lm -lpthread # -DD256STATS #-DD64STATS

From 6dff67430229834ec00098f17b50c57b528ebd0a Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Sun, 15 Mar 2020 18:03:42 +0100
Subject: [PATCH 322/343] testing after merge with develo

---
 cmake_targets/autotests/test_case_list.xml    | 20 +++---
 executables/softmodem-common.c                | 61 ++++++++++++++++++-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |  4 +-
 openair1/SCHED_NR_UE/fapi_nr_ue_l1.c          |  1 -
 openair1/SIMULATION/NR_PHY/dlsim.c            | 52 ++++------------
 openair1/SIMULATION/NR_PHY/prachsim.c         |  7 +++
 openair1/SIMULATION/NR_PHY/ulsim.c            | 53 +++++-----------
 openair2/LAYER2/NR_MAC_UE/mac_defs.h          |  2 -
 8 files changed, 104 insertions(+), 96 deletions(-)

diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 3a02cfe30c..6e96bb3b99 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1082,15 +1082,13 @@
       nr_dlsim Test cases. (Test1: 106 PRB),
                                  (Test2: 217 PRB),
                                  (Test3: 273 PRB),
-                                 (Test4: 106 PRB 12 CSET-Offset),
-                                 (Test5: 217 PRB 48 CSET-Offset),
-                                 (Test6: 106 PRB 25 PDSCH-Offset),
-                                 (Test7: 106 PRB 51 PDSCH-Offset),
-                                 (Test8: 217 PRB 100 PDSCH-PRBs),
-                                 (Test9: 217 PRB 80 PDSCH-Offset),
-                                 (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
-                                 (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 27)
-                                 (Test12: 106 PRBs 50 PDSCH-PRBs MCS Index 16)
+                                 (Test4: 106 PRB 25 PDSCH-Offset),
+                                 (Test5: 106 PRB 51 PDSCH-Offset),
+                                 (Test6: 217 PRB 100 PDSCH-PRBs),
+                                 (Test7: 217 PRB 80 PDSCH-Offset),
+                                 (Test8: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
+                                 (Test9: 106 PRBs 50 PDSCH-PRBs MCS Index 27)
+                                 (Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16)
       
       $OPENAIR_DIR/cmake_targets/build_oai
        --phy_simulators  -c 
@@ -1100,14 +1098,12 @@
       -n100 -R106 -b106 -s5
 		  -n100 -R217 -b217 -s5
 		  -n100 -R273 -b273 -s5
-                  -n100 -R106 -o12 -s5
-                  -n100 -R217 -o48 -s5
                   -n100 -R106 -a25 -s5
                   -n100 -R106 -a51 -s5
                   -n100 -R217 -b100 -s5
                   -n100 -R217 -a80 -s5
                   -n100 -R217 -a110 -s5 -b100
-                  -n100 -e27 -s20 
+                  -n100 -e27 -s30 
                   -n100 -e16 -s10 
       
       nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index 0a4e94571f..f714fa2bd4 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -144,4 +144,63 @@ void get_common_options(uint32_t execmask) {
 
   if(worker_config != NULL)   set_worker_conf(worker_config);
 }
-#endif
+void softmodem_printresources(int sig, telnet_printfunc_t pf) {
+   struct rusage usage;
+   struct timespec stop;
+
+   clock_gettime(CLOCK_BOOTTIME, &stop);
+
+   uint64_t elapse = (stop.tv_sec - start.tv_sec) ;   // in seconds
+
+
+   int st = getrusage(RUSAGE_SELF,&usage);
+   if (!st) {
+   	 pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600)));
+     pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec);
+     pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec);
+     pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss);
+     pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt);
+     pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt);
+     pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock);
+     pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock);
+     pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw);
+     pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw);
+   } 
+}
+
+void signal_handler(int sig) {
+  void *array[10];
+  size_t size;
+
+  if (sig==SIGSEGV) {
+    // get void*'s for all entries on the stack
+    size = backtrace(array, 10);
+    // print out all the frames to stderr
+    fprintf(stderr, "Error: signal %d:\n", sig);
+    backtrace_symbols_fd(array, size, 2);
+    exit(-1);
+  } else {
+  	if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL)
+  		softmodem_printresources(sig,(telnet_printfunc_t)printf);
+  	if (sig != SOFTMODEM_RTSIGNAL) {
+      printf("Linux signal %s...\n",strsignal(sig));
+      exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n");
+    }
+  }
+}
+
+
+
+void set_softmodem_sighandler(void) {
+  struct sigaction	act,oldact;
+  clock_gettime(CLOCK_BOOTTIME, &start);
+  memset(&act,0,sizeof(act));
+  act.sa_handler=signal_handler;
+  sigaction(SOFTMODEM_RTSIGNAL,&act,&oldact);
+  printf("Send signal %d to display resource usage...\n",SIGRTMIN+1);
+  signal(SIGSEGV, signal_handler);
+  signal(SIGINT,  signal_handler);
+  signal(SIGTERM, signal_handler);
+  signal(SIGABRT, signal_handler);	
+}
+
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index d3003da094..cfdae15b65 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -581,13 +581,13 @@ 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)) {
-        LOG_I(PHY,"Segment %u CRC OK\n\033[0m",r);
+        LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
         //Temporary hack
         no_iteration_ldpc = dlsch->max_ldpc_iterations;
         ret = no_iteration_ldpc;
       }
       else {
-        LOG_I(PHY,"CRC NOK\n\033[0m");
+        LOG_D(PHY,"CRC NOK\n\033[0m");
         ret = 1 + dlsch->max_ldpc_iterations;
       }
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index c6a830a8da..69876159d6 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -51,7 +51,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
     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_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index c0976d254f..ebcedbaeb0 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -80,6 +80,7 @@ int sf_ahead=4 ;
 int sl_ahead=0;
 uint8_t nfapi_mode = 0;
 uint16_t NB_UE_INST = 1;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
 
 // dummy functions
 int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info)              { return(0);  }
@@ -97,13 +98,17 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t     module_id,
 }
 
 
-//Dummy Functions
-
-//lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms, unsigned char subframe) {return(SF_DL);}
-int rlc_module_init (int eNB_id) {return(0);}
-
-
 void pdcp_layer_init(void) {}
+boolean_t
+pdcp_data_ind(
+  const protocol_ctxt_t *const ctxt_pP,
+  const srb_flag_t   srb_flagP,
+  const MBMS_flag_t  MBMS_flagP,
+  const rb_id_t      rb_idP,
+  const sdu_size_t   sdu_buffer_sizeP,
+  mem_block_t *const sdu_buffer_pP
+) { return(false);}
+
 int rrc_init_nr_global_param(void){return(0);}
 
 void config_common(int Mod_idP,
@@ -111,28 +116,6 @@ void config_common(int Mod_idP,
 		   NR_ServingCellConfigCommon_t *scc
 		   );
 
-mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t       module_idP,
-                                         const rnti_t            rntiP,
-                                         const eNB_index_t       eNB_index,
-                                         const frame_t           frameP,
-                                         const sub_frame_t       subframeP,
-                                         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,
-                                         const uint32_t          sourceL2Id,
-                                         const uint32_t          destinationL2Id) {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,
-                            const frame_t           frameP,
-                            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,
-                            char                    *buffer_pP,
-                            const uint32_t          sourceL2Id,
-                            const uint32_t          destinationL2Id) {return 0;}
 int generate_dlsch_header(unsigned char *mac_header,
                           unsigned char num_sdus,
                           unsigned short *sdu_lengths,
@@ -144,19 +127,6 @@ int generate_dlsch_header(unsigned char *mac_header,
                           unsigned short post_padding){return 0;}
 void nr_ip_over_LTE_DRB_preconfiguration(void){}
 
-void mac_rlc_data_ind     (
-  const module_id_t         module_idP,
-  const rnti_t              rntiP,
-  const eNB_index_t         eNB_index,
-  const frame_t             frameP,
-  const eNB_flag_t          enb_flagP,
-  const MBMS_flag_t         MBMS_flagP,
-  const logical_chan_id_t   channel_idP,
-  char                     *buffer_pP,
-  const tb_size_t           tb_sizeP,
-  num_tb_t                  num_tbP,
-  crc_t                    *crcs_pP)
-{}
 // needed for some functions
 openair0_config_t openair0_cfg[MAX_CARDS];
 
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 1ec18858dc..5c00352515 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -73,6 +73,10 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e
   return 0;
 }
 
+uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
+           sub_frame_t subframe, uint8_t eNB_index,
+           uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) {return(0);}
+
 int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
 
 openair0_config_t openair0_cfg[MAX_CARDS];
@@ -80,6 +84,9 @@ uint8_t nfapi_mode=0;
 NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
 int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
 
+uint64_t get_softmodem_optmask(void) {
+  return 0;
+}
 
 int main(int argc, char **argv)
 {
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index f43709cac5..f98b9be7c6 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -67,44 +67,11 @@ int sl_ahead=0;
 double cpuf;
 uint8_t nfapi_mode = 0;
 uint16_t NB_UE_INST = 1;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
+
 
 int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
                               const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
-void mac_rlc_data_ind ( const module_id_t         module_idP,
-			const rnti_t              rntiP,
-			const eNB_index_t         eNB_index,
-			const frame_t             frameP,
-			const eNB_flag_t          enb_flagP,
-			const MBMS_flag_t         MBMS_flagP,
-			const logical_chan_id_t   channel_idP,
-			char                     *buffer_pP,
-			const tb_size_t           tb_sizeP,
-			num_tb_t                  num_tbP,
-			crc_t                    *crcs_pP){}
-mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t       module_idP,
-					  const rnti_t            rntiP,
-					  const eNB_index_t       eNB_index,
-					  const frame_t           frameP,
-					  const sub_frame_t 	  subframeP,
-					  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,
-					  const uint32_t sourceL2Id,
-					  const uint32_t destinationL2Id)
-{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,
-			      const frame_t           frameP,
-			      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,
-			      char             *buffer_pP,
-			      const uint32_t sourceL2Id,
-			      const uint32_t destinationL2Id )
-{return 0;}
 int generate_dlsch_header(unsigned char *mac_header,
                           unsigned char num_sdus,
                           unsigned short *sdu_lengths,
@@ -114,8 +81,16 @@ int generate_dlsch_header(unsigned char *mac_header,
                           unsigned char *ue_cont_res_id,
                           unsigned char short_padding,
                           unsigned short post_padding){return 0;}
-int rlc_module_init (int enb) {return(0);}
 void pdcp_layer_init (void) {}
+boolean_t pdcp_data_ind(
+  const protocol_ctxt_t *const ctxt_pP,
+  const srb_flag_t   srb_flagP,
+  const MBMS_flag_t  MBMS_flagP,
+  const rb_id_t      rb_idP,
+  const sdu_size_t   sdu_buffer_sizeP,
+  mem_block_t *const sdu_buffer_pP
+) { return(false);}
+
 void pdcp_run (const protocol_ctxt_t *const  ctxt_pP) { return;}
 void nr_ip_over_LTE_DRB_preconfiguration(void){}
 int rrc_init_nr_global_param(void){return(0);}
@@ -395,8 +370,9 @@ int main(int argc, char **argv)
 
   //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
   gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t));
+  gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t));
   gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0;
-
+  gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0;
   frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
   frame_parms->nb_antennas_tx = n_tx;
   frame_parms->nb_antennas_rx = n_rx;
@@ -675,6 +651,9 @@ int main(int argc, char **argv)
         //----------------------------------------------------------
         //------------------- gNB phy procedures -------------------
         //----------------------------------------------------------
+        gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0;
+        gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0;
+
         phy_procedures_gNB_common_RX(gNB, frame, slot);
 
 	if (n_trials==1)
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 4cf39bcfdb..405ea95eb1 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -167,8 +167,6 @@ typedef struct {
   RA_state_t ra_state;
   ///     RA-rnti
   uint16_t ra_rnti;
-  uint16_t crnti;
-
   ///     Temporary CRNTI
   uint16_t t_crnti;
   ///     CRNTI

From 93b4211d022f740efeee2c7966a3ccbd0b8484f4 Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Sun, 15 Mar 2020 19:16:30 +0100
Subject: [PATCH 323/343] merge conflict removal

---
 openair1/PHY/INIT/nr_init.c    | 95 +++-------------------------------
 openair1/PHY/INIT/nr_init_ue.c |  3 --
 2 files changed, 8 insertions(+), 90 deletions(-)

diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 216a83025f..d30c0dc874 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -154,19 +154,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     }
   }
 
-<<<<<<< HEAD
   //------------- 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_pos0;
   gNB->dmrs_UplinkConfig.pusch_maxLength = pusch_len1;
   //--------------------------------------------------------------------------------
-=======
-  //------------- config PUSCH DMRS parameters(to be updated from RRC)--------------//
-  dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
-  dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
-  dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
-  //--------------------------------------------------------------------------------//
->>>>>>> origin/develop
 
   nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
 
@@ -234,7 +226,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
 */
   // PRACH
   prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
-<<<<<<< HEAD
   prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*));
   /* 
   for (i=0;irxdataF_ext2          = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
     pusch_vars[ULSCH_id]->ul_ch_estimates       = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
     pusch_vars[ULSCH_id]->ul_ch_estimates_ext   = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates     = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+    pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
     pusch_vars[ULSCH_id]->ul_ch_estimates_time  = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
     pusch_vars[ULSCH_id]->rxdataF_comp          = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
     pusch_vars[ULSCH_id]->ul_ch_mag0             = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
@@ -268,55 +261,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
       pusch_vars[ULSCH_id]->ul_ch_estimates[i]       = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]   = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]  = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
+      pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]       = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
+      pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]   = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->rxdataF_comp[i]          = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
       pusch_vars[ULSCH_id]->ul_ch_mag0[i]             = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
       pusch_vars[ULSCH_id]->ul_ch_magb0[i]            = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
       pusch_vars[ULSCH_id]->ul_ch_mag[i]             = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
       pusch_vars[ULSCH_id]->ul_ch_magb[i]            = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
       pusch_vars[ULSCH_id]->rho[i]                   = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
-=======
-  // assume maximum of 64 RX antennas for PRACH receiver
-  prach_vars->prach_ifft[0]    = (int32_t **)malloc16_clear(64*sizeof(int32_t *));
-
-  for (i=0; i<64; i++) prach_vars->prach_ifft[0][i]    = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
-
-  prach_vars->rxsigF[0]        = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
-*/
-
-  for (int UE_id=0; UE_idrxdataF_ext              = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->rxdataF_ext2             = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_estimates          = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_estimates_ext      = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_ptrs_estimates     = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_estimates_time     = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->rxdataF_comp             = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_mag0               = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_magb0              = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_mag                = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->ul_ch_magb               = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-    pusch_vars[UE_id]->rho                      = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-
-    for (i=0; inb_antennas_rx; i++) {
-      // RK 2 times because of output format of FFT!
-      // FIXME We should get rid of this
-      pusch_vars[UE_id]->rxdataF_ext[i]                = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->rxdataF_ext2[i]               = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_estimates[i]            = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_estimates_ext[i]        = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_ptrs_estimates[i]       = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
-      pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i]   = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_estimates_time[i]       = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
-      pusch_vars[UE_id]->rxdataF_comp[i]               = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
-      pusch_vars[UE_id]->ul_ch_mag0[i]                 = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->ul_ch_magb0[i]                = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->ul_ch_mag[i]                  = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->ul_ch_magb[i]                 = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
-      pusch_vars[UE_id]->rho[i]                        = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
->>>>>>> origin/develop
     }
     printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
     pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
@@ -374,12 +326,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
 */
   for (int ULSCH_id=0; ULSCH_idrxdataF_ext[i]);
       free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]);
+      free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]);
       free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]);
       free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]);
@@ -392,6 +345,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
     free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2);
     free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates);
     free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext);
+    free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates);
+    free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext);
     free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
     free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
     free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0);
@@ -403,40 +358,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
     free_and_zero(pusch_vars[ULSCH_id]->llr);
     free_and_zero(pusch_vars[ULSCH_id]);
   } //ULSCH_id
-=======
-      free_and_zero(pusch_vars[UE_id]->rxdataF_ext[i]);
-      free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_estimates[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time[i]);
-      free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_mag0[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_magb0[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]);
-      free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]);
-      free_and_zero(pusch_vars[UE_id]->rho[i]);
-    }
-
-    free_and_zero(pusch_vars[UE_id]->rxdataF_ext);
-    free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_estimates);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time);
-    free_and_zero(pusch_vars[UE_id]->rxdataF_comp);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_mag0);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_magb0);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_mag);
-    free_and_zero(pusch_vars[UE_id]->ul_ch_magb);
-    free_and_zero(pusch_vars[UE_id]->rho);
-
-    free_and_zero(pusch_vars[UE_id]->llr);
-    free_and_zero(pusch_vars[UE_id]);
-  } //UE_id
->>>>>>> origin/develop
 /*
   for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL;
 */
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 60c8e1943d..4ed5be2119 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -655,13 +655,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
   int n_scid;
   abstraction_flag = 0;
-<<<<<<< HEAD
-=======
   fp->nb_antennas_tx = 1;
   fp->nb_antennas_rx=1;
   dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
   ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
->>>>>>> origin/develop
   printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
   //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
   phy_init_nr_top(ue);

From e9fad1854059a1738661228726e8359eb17c78bf Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Mon, 16 Mar 2020 01:26:12 +0100
Subject: [PATCH 324/343] temporary changes for nr_ulsim. To be removed when
 new branch with SCF NR FAPI for PUSCH is merged in.

---
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 5 +++++
 openair1/SIMULATION/NR_PHY/ulsim.c          | 4 ++++
 2 files changed, 9 insertions(+)

diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 0238cb655f..05705a9fe9 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -442,6 +442,11 @@ int nr_dlsch_encoding(unsigned char *a,
     }
     encoder_implemparams_t impp;
     impp.n_segments=dlsch->harq_processes[harq_pid]->C;
+    impp.tprep = tprep;
+    impp.tinput = tinput;
+    impp.tparity = tparity;
+    impp.toutput = toutput;
+
     for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
       impp.macro_num=j;
       nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp);
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index bd005d2331..477efac413 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -562,6 +562,10 @@ int main(int argc, char **argv)
       pusch_pdu->nrOfLayers = 1;
       pusch_pdu->ul_dmrs_symb_pos = 1;
       pusch_pdu->dmrs_config_type = 0;
+      // inserted to make simulation work 
+      // remove the next 2 lines when P7 is integrated from new branch
+      gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type=pusch_dmrs_type1;
+      gNB->pusch_config.dmrs_UplinkConfig.pusch_maxLength   = length_dmrs;
       pusch_pdu->ul_dmrs_scrambling_id =  0;
       pusch_pdu->scid = 0;
       pusch_pdu->resource_alloc = 1; 

From 1ddd729044d334bff0c97159c469e3a738a6c6f3 Mon Sep 17 00:00:00 2001
From: Raymond Knopp 
Date: Mon, 16 Mar 2020 09:32:50 +0100
Subject: [PATCH 325/343] bring back recent changes in ldpc encoder after merge
 with dynamic library implementation

---
 cmake_targets/autotests/test_case_list.xml                     | 2 +-
 .../PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c    | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 6e96bb3b99..b3954db1fd 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1106,7 +1106,7 @@
                   -n100 -e27 -s30 
                   -n100 -e16 -s10 
       
-      nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12
+      nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 
       PDSCH test OK
       segmentation fault|assertion|exiting|fatal
       3
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
index 28ab5b5029..b21f875b32 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
@@ -58,8 +58,7 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
 
   
   macro_segment = 8*impp->macro_num;
-  // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
-  macro_segment_end = macro_segment + (impp->n_segments > 8 ? 8 : impp->n_segments);
+  macro_segment_end = (impp->n_segments > 8*(impp->macro_num+1)) ? 8*(impp->macro_num+1) : impp->n_segments;
   ///printf("macro_segment: %d\n", macro_segment);
   ///printf("macro_segment_end: %d\n", macro_segment_end );
 

From 07a48f87e41b14fce9e65375ecab31b7918db25d Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Tue, 17 Mar 2020 19:06:22 +0100
Subject: [PATCH 326/343] loading LDPC libs for UE

---
 executables/nr-uesoftmodem.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 64e0e03a05..53e407923f 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -688,6 +688,7 @@ int main( int argc, char **argv ) {
   itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
 
   init_opt() ;
+  load_nrLDPClib();
 
   if (ouput_vcd) {
     vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");

From 57c993ce2613dd908580c25d5935fb05da0ce8b2 Mon Sep 17 00:00:00 2001
From: Francesco Mani 
Date: Wed, 18 Mar 2020 10:03:41 +0100
Subject: [PATCH 327/343] fix for some warnings

---
 openair1/PHY/MODULATION/modulation_UE.h            | 6 ++++++
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c        | 2 +-
 openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h      | 2 +-
 openair1/PHY/NR_UE_TRANSPORT/dci_nr.c              | 2 +-
 openair1/SIMULATION/NR_PHY/nr_unitary_defs.h       | 2 +-
 openair1/SIMULATION/NR_PHY/pbchsim.c               | 4 +++-
 openair1/SIMULATION/NR_PHY/ulsim.c                 | 1 +
 openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c       | 2 +-
 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c         | 3 +--
 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +-
 openair2/RRC/NR/rrc_gNB_reconfig.c                 | 2 +-
 11 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h
index 1199a91baa..228299095f 100644
--- a/openair1/PHY/MODULATION/modulation_UE.h
+++ b/openair1/PHY/MODULATION/modulation_UE.h
@@ -54,6 +54,12 @@ int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
              int sample_offset,
              int no_prefix);
 
+int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
+                          unsigned char symbol,
+                          unsigned char Ns,
+                          int sample_offset,
+                          int no_prefix);
+
 int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
                    unsigned char l,
                    int subframe,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 05705a9fe9..856a7863f4 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -272,7 +272,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
   LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of  %ld\n",
 	exit_flag, sizeof(NR_gNB_DLSCH_t));
 
-  free_gNB_dlsch(dlsch,N_RB);
+  free_gNB_dlsch(&dlsch,N_RB);
 
   return(NULL);
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 68b9e44d63..af06f9a98f 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -90,6 +90,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
                         uint32_t rx_power_fil_dB,
                         uint8_t eNB_id);
 
-int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index);
 
 #endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 9921862c52..ef22b61260 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -702,7 +702,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
       for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
         avgs = cmax(avgs, avgP[aarx]);
 
-        log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
+      log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
 #ifdef UE_DEBUG_TRACE
       LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
 #endif
diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
index 48fd49943b..c7a30f826e 100644
--- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
+++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
@@ -143,7 +143,7 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL
   *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB=19;
   scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present=NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139;
   scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139=0;
-  scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig=NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64;
+  scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig=NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet;
   *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2=2;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
   scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength=55;
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index f78210a0f8..99ca466fee 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -410,7 +410,9 @@ int main(int argc, char **argv)
   uint8_t n_hf = 0;
   int cyclic_prefix_type = NFAPI_CP_NORMAL;
 
-  double fs,bw,scs,eps;
+  double fs, eps;
+  double scs = 30000;
+  double bw = 100e6;
   
   switch (mu) {
     case 1:
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 477efac413..1ca4a5a389 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -52,6 +52,7 @@
 #include "openair1/SIMULATION/TOOLS/sim.h"
 #include "openair1/SIMULATION/RF/rf.h"
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
+#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
 #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
 #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
 
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index d62a763a22..58b312038a 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -2732,7 +2732,7 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
     NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) :
     NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
 
-  int pos;
+  int pos=0;
   int fsize=0;
   switch(dci_format) {
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 93de38060d..90c56c2ef5 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -308,10 +308,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   //printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP);
 			       
   protocol_ctxt_t   ctxt;
-  int CC_id, i = -1, UE_id = 0;
+  int CC_id, UE_id = 0;
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_UE_list_t *UE_list = &gNB->UE_list;
-  rnti_t rnti;
   UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
   NR_COMMON_channels_t *cc = gNB->common_channels;
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 37808dec8d..85d0a04b54 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -37,7 +37,7 @@
 #include "executables/nr-softmodem.h"
 #include "LAYER2/NR_MAC_COMMON/nr_mac.h"
 #include "executables/softmodem-common.h"
-
+#include "common/utils/nr/nr_common.h"
 #include "NR_SCS-SpecificCarrier.h"
 #include "NR_TDD-UL-DL-ConfigCommon.h"
 #include "NR_FrequencyInfoUL.h"
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index faabbb1400..1df17a19aa 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -41,7 +41,7 @@
 #include "BOOLEAN.h"
 #include "assertions.h"
 #include "common/utils/nr/nr_common.h"
-
+#include "SIMULATION/TOOLS/sim.h"
 #include "executables/softmodem-common.h"
 
 #define false 0

From 6d058d306aa6adef383ca81d836ffc7eafb17530 Mon Sep 17 00:00:00 2001
From: Francesco Mani 
Date: Thu, 19 Mar 2020 18:07:12 +0100
Subject: [PATCH 328/343] SCF FAPI structures for PUSCH at gNB

---
 executables/nr-ue.c                           |   2 +-
 .../nfapi/public_inc/nfapi_nr_interface_scf.h |   4 +-
 openair1/PHY/CODING/nr_segmentation.c         |  14 +-
 openair1/PHY/INIT/nr_init.c                   |  39 +-
 .../NR_ESTIMATION/nr_ul_channel_estimation.c  |  34 +-
 openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h |  14 +-
 openair1/PHY/NR_REFSIG/dmrs_nr.c              |  15 +-
 openair1/PHY/NR_REFSIG/dmrs_nr.h              |   3 +-
 openair1/PHY/NR_REFSIG/nr_gold.c              |  57 +--
 openair1/PHY/NR_REFSIG/nr_refsig.h            |   2 +-
 openair1/PHY/NR_REFSIG/ptrs_nr.c              |  92 +++--
 openair1/PHY/NR_REFSIG/ptrs_nr.h              |   9 +-
 openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c    |  16 +-
 .../PHY/NR_TRANSPORT/nr_transport_proto.h     |  11 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch.h          |   5 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |  93 +++--
 .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c  | 342 ++++++++----------
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |  36 +-
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    |  19 +-
 openair1/PHY/defs_gNB.h                       |  17 +-
 openair1/PHY/impl_defs_nr.h                   |   4 +-
 openair1/SCHED_NR/phy_procedures_nr_gNB.c     |  49 ++-
 openair1/SIMULATION/NR_PHY/ulschsim.c         |  31 +-
 openair1/SIMULATION/NR_PHY/ulsim.c            |   9 +-
 .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c |   4 +-
 .../NR_MAC_gNB/gNB_scheduler_primitives.c     |  22 --
 26 files changed, 411 insertions(+), 532 deletions(-)

diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 40d33b701e..653a97dc61 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -762,7 +762,7 @@ void *UE_thread(void *arg) {
     int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
     for (int i=0; iframe_parms.nb_antennas_rx; i++)
       rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
-               get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
+               UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
 
     for (int i=0; iframe_parms.nb_antennas_tx; i++)
       txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index ee1550a5bb..f69c928ed2 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -1122,10 +1122,10 @@ typedef struct
   uint16_t data_scrambling_id;
   uint8_t  nrOfLayers;
   //DMRS
-  uint8_t  ul_dmrs_symb_pos;
+  uint16_t  ul_dmrs_symb_pos;
   uint8_t  dmrs_config_type;
   uint16_t ul_dmrs_scrambling_id;
-  uint8_t  scid;//
+  uint8_t  scid;
   uint8_t  num_dmrs_cdm_grps_no_data;
   uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
   //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c
index 462cdee1fc..1d80a83131 100644
--- a/openair1/PHY/CODING/nr_segmentation.c
+++ b/openair1/PHY/CODING/nr_segmentation.c
@@ -30,13 +30,13 @@
 //#define DEBUG_SEGMENTATION
 
 int32_t nr_segmentation(unsigned char *input_buffer,
-                     unsigned char **output_buffers,
-                     unsigned int B,
-                     unsigned int *C,
-                     unsigned int *K,
-                     unsigned int *Zout, // [hna] Zout is Zc
-                     unsigned int *F,
-                     uint8_t BG)
+                        unsigned char **output_buffers,
+                        unsigned int B,
+                        unsigned int *C,
+                        unsigned int *K,
+                        unsigned int *Zout, // [hna] Zout is Zc
+                        unsigned int *F,
+                        uint8_t BG)
 {
 
   unsigned int L,Bprime,Z,r,Kcb,Kb,k,s,crc,Kprime;
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index d30c0dc874..1c0d5a6aca 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -83,8 +83,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   NR_gNB_COMMON *const common_vars  = &gNB->common_vars;
   NR_gNB_PRACH *const prach_vars   = &gNB->prach_vars;
   NR_gNB_PUSCH **const pusch_vars   = gNB->pusch_vars;
-  dmrs_UplinkConfig_t *dmrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig;
-  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   /*LTE_eNB_SRS *const srs_vars       = gNB->srs_vars;
   LTE_eNB_PRACH *const prach_vars   = &gNB->prach_vars;*/
 
@@ -154,31 +152,30 @@ 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_pos0;
-  gNB->dmrs_UplinkConfig.pusch_maxLength = pusch_len1;
-  //--------------------------------------------------------------------------------
 
   nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
 
-  // default values until overwritten by RRCConnectionReconfiguration
+  //PUSCH DMRS init
+  gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***));
+  uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
 
-  for (i=0;ipusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t));
-    gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
+  for(int nscid=0; nscid<2; nscid++) {
+    pusch_dmrs[nscid] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
+    AssertFatal(pusch_dmrs[nscid]!=NULL, "NR init: pusch_dmrs for nscid %d - malloc failed\n", nscid);
+
+    for (int slot=0; slotslots_per_frame; slot++) {
+      pusch_dmrs[nscid][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
+      AssertFatal(pusch_dmrs[nscid][slot]!=NULL, "NR init: pusch_dmrs for slot %d - malloc failed\n", slot);
+
+      for (int symb=0; symbsymbols_per_slot; symb++) {
+        pusch_dmrs[nscid][slot][symb] = (uint32_t *)malloc16(NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
+        AssertFatal(pusch_dmrs[nscid][slot][symb]!=NULL, "NR init: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
+      }
+    }
   }
 
-  gNB->ptrs_configured = 0;
-
-  //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------//
-  ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
-  ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0;
-  ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0;
-  ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0;     // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
-  ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0;
-  ptrs_Uplink_Config->resourceElementOffset = 0;
-  //--------------------------------------------------------------------------------//
+  uint32_t Nid_pusch[2] = {cfg->cell_config.phy_cell_id.value,cfg->cell_config.phy_cell_id.value};
+  nr_gold_pusch(gNB, &Nid_pusch[0]);
 
   /// Transport init necessary for NR synchro
   init_nr_transport(gNB);
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 83c6f054cd..0d7732599f 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -31,22 +31,19 @@
 
 
 int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
-                                uint8_t gNB_offset,
                                 unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
                                 unsigned short bwp_start_subcarrier,
-                                unsigned short nb_rb_pusch,
-                                dmrs_UplinkConfig_t *dmrs_UplinkConfig)
-{
+                                nfapi_nr_pusch_pdu_t *pusch_pdu) {
+
   int pilot[3280] __attribute__((aligned(16)));
   unsigned char aarx;
   unsigned short k;
   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
+  int ch_offset,symbol_offset, UE_id = 0;
   int32_t **ul_ch_estimates_time =  gNB->pusch_vars[UE_id]->ul_ch_estimates_time;
   __m128i *ul_ch_128;
 
@@ -71,9 +68,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
   k = bwp_start_subcarrier;
   int re_offset = k;
 
+  uint16_t nb_rb_pusch = pusch_pdu->rb_size;
+
 /*
 #ifdef DEBUG_CH
-  printf("PUSCH Channel Estimation : gNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", gNB_offset,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
+  printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
          gNB->frame_parms.Ncp,l,Ns,k, symbol);
 #endif
 */
@@ -117,21 +116,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
   //------------------generate DMRS------------------//
 
-  length_dmrs = dmrs_UplinkConfig->pusch_maxLength;
-
-  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, dmrs_UplinkConfig->pusch_dmrs_type);
+  nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->dmrs_config_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);
@@ -141,8 +136,7 @@ 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){
+    if (pusch_pdu->dmrs_config_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);
@@ -237,10 +231,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
       }
       
       // Treat first 2 pilots specially (right edge)
-	  ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+      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 %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 %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,
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index cc84f2292c..a7789c9224 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -39,14 +39,12 @@
 \param nb_rb_pusch, number of allocated RBs for this UE
 */
 
- int32_t nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
-                                     uint8_t gNB_offset,
-				                     unsigned char Ns,
-				                     unsigned short p,
-				                     unsigned char symbol,
-				                     unsigned short bwp_start_subcarrier,
-				                     unsigned short nb_rb_pusch,
-				                     dmrs_UplinkConfig_t *dmrs_UplinkConfig);
+int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
+                                unsigned char Ns,
+                                unsigned short p,
+                                unsigned char symbol,
+                                unsigned short bwp_start_subcarrier,
+                                nfapi_nr_pusch_pdu_t *pusch_pdu);
 
 int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
 
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 67118f35a9..ed37a79d0f 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -128,22 +128,21 @@ uint8_t is_dmrs_symbol(uint8_t l,
                        uint16_t n,
                        uint8_t delta,
                        uint8_t duration_in_symbols,
-                       dmrs_UplinkConfig_t *dmrs_UplinkConfig,
-                       uint8_t mapping_type,
+                       uint8_t dmrs_type,
                        uint16_t ofdm_symbol_size) {
 
-  uint8_t is_dmrs_freq, is_dmrs_time, dmrs_type, l0;
+  uint8_t is_dmrs_freq, is_dmrs_time, l0;
   int32_t l_prime_mask;
-  pusch_dmrs_AdditionalPosition_t additional_pos;
+  pusch_dmrs_AdditionalPosition_t additional_pos = pusch_dmrs_pos0;
+  pusch_maxLength_t pusch_maxLength = pusch_len1;
+  uint8_t mapping_type = typeB;
 
   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, dmrs_UplinkConfig->pusch_maxLength);
+  l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos, pusch_maxLength);
 
   if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%ofdm_symbol_size))
     is_dmrs_freq = 1;
@@ -157,7 +156,7 @@ uint8_t is_dmrs_symbol(uint8_t l,
   } else if ( (l==l0) || (((l_prime_mask>>l)&1) == 1 && l!=0) )
     is_dmrs_time = 1;
 
-  if (dmrs_UplinkConfig->pusch_maxLength == pusch_len2){
+  if (pusch_maxLength == pusch_len2){
 
     if (((l_prime_mask>>(l-1))&1) == 1 && l!=0 && l!=1)
       is_dmrs_time = 1;
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h
index de77a8a6ce..f1dfffff8b 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h
@@ -66,8 +66,7 @@ uint8_t is_dmrs_symbol(uint8_t l,
                        uint16_t n,
                        uint8_t delta,
                        uint8_t duration_in_symbols,
-                       dmrs_UplinkConfig_t *dmrs_UplinkConfig,
-                       uint8_t mapping_type,
+                       uint8_t dmrs_type,
                        uint16_t ofdm_symbol_size);
 
 #undef EXTERN
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index 7057adef21..472d03e649 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -104,56 +104,27 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
 }
 
 
-void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs)
-{
+void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid) {
 
-  unsigned char ns,l;
-  unsigned int n,x1,x2,x2tmp0;
-  int nscid;
+  unsigned char ns;
+  unsigned int n,x1,x2;
+  int nscid, reset;
   unsigned int nid;
-
-  /// to be updated from higher layer
-  //unsigned short lbar = 0;
+  NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
+  unsigned short l;
 
   for (nscid=0; nscid<2; nscid++) {
-    if (n_idDMRS)
-      nid = n_idDMRS[nscid];
-    else
-      nid = gNB->frame_parms.Nid_cell;
-      
-      //printf("gold pdsch nid %d lbar %d\n",nid,lbar);
-
-    for (ns=0; ns<20; ns++) {
-
-      for (l=0; l>1) ^ (x2>>2) ^ (x2>>3))<<31);
-
-        // skip first 50 double words (1600 bits)
-        for (n=1; n<50; n++) {
-          x1 = (x1>>1) ^ (x1>>4);
-          x1 = x1 ^ (x1<<31) ^ (x1<<28);
-          x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
-          x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
-            //printf("x1 : %x, x2 : %x\n",x1,x2);
-        }
+    nid = Nid[nscid];
+    for (ns=0; nsslots_per_frame; ns++) {
+      for (l=0; lsymbols_per_slot; l++) {
+        reset = 1;
+        x2 = ((1<<17) * (fp->symbols_per_slot*ns+l+1) * ((nid<<1)+1) +((nid<<1)+nscid));
+        LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",ns,l,x2);
 
         for (n=0; n>1) ^ (x1>>4);
-          x1 = x1 ^ (x1<<31) ^ (x1<<28);
-          x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
-          x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
-          gNB->nr_gold_pusch[nscid][ns][l][n] = x1^x2;
-            // if ((ns==2)&&(l==0))
-            //printf("n=%d : c %x\n",n,x1^x2);
+          gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
+          reset = 0;
         }
-
       }
     }
   }
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index 754edfef64..5af0e88099 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -39,7 +39,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
 void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
 void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
 
-void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs);
+void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid);
 
 int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
                      unsigned int Ns,
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c
index 9be37d2d95..12f76b950f 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c
@@ -123,9 +123,6 @@ uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
 * NAME :         set_ptrs_symb_idx
 *
 * PARAMETERS :   ptrs_symbols           PTRS OFDM symbol indicies bit mask
-*                ptrs_UplinkConfig      PTRS uplink configuration
-*                dmrs_UplinkConfig      DMRS uplink configuration
-*                mapping_type           PUSCH time domain mapping type
 *                duration_in_symbols    number of scheduled PUSCH ofdm symbols
 *                start_symbol           first ofdm symbol of PUSCH within slot
 *                L_ptrs                 the parameter L_ptrs
@@ -138,64 +135,61 @@ uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
 *********************************************************************/
 
 void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
-                       ptrs_UplinkConfig_t *ptrs_UplinkConfig,
-                       dmrs_UplinkConfig_t *dmrs_UplinkConfig,
-                       uint8_t mapping_type,
                        uint8_t duration_in_symbols,
                        uint8_t start_symbol,
+                       uint8_t dmrs_type,
                        uint8_t L_ptrs,
+                       uint8_t pusch_maxLength,
                        uint16_t ofdm_symbol_size) {
 
-	uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2;
-	int16_t l_ref;
+  uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2;
+  int16_t l_ref;
 
-	*ptrs_symbols = 0;
-	i = 0;
-	is_dmrs_symbol1 = 0;
-	is_dmrs_symbol2 = 0;
-	l_ref = start_symbol;
-	last_symbol = start_symbol + duration_in_symbols - 1;
+  *ptrs_symbols = 0;
+  i = 0;
+  is_dmrs_symbol1 = 0;
+  is_dmrs_symbol2 = 0;
+  l_ref = start_symbol;
+  last_symbol = start_symbol + duration_in_symbols - 1;
 
-	while ( (l_ref + i*L_ptrs) <= last_symbol) {
+  while ( (l_ref + i*L_ptrs) <= last_symbol) {
 
-		is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref),
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         duration_in_symbols,
-                                         dmrs_UplinkConfig,
-                                         mapping_type,
-                                         ofdm_symbol_size);
+    is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref),
+                                     0,
+                                     0,
+                                     0,
+                                     0,
+                                     0,
+                                     duration_in_symbols,
+                                     dmrs_type,
+                                     ofdm_symbol_size);
 
-		is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         duration_in_symbols,
-                                         dmrs_UplinkConfig,
-                                         mapping_type,
-                                         ofdm_symbol_size);
+    is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs,
+                                     0,
+                                     0,
+                                     0,
+                                     0,
+                                     0,
+                                     duration_in_symbols,
+                                     dmrs_type,
+                                     ofdm_symbol_size);
 
-		if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) {
+    if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) {
 
-			if (dmrs_UplinkConfig->pusch_maxLength == 2)
-				l_ref = l_ref + i*L_ptrs + 1;
-			else
-				l_ref = l_ref + i*L_ptrs;
+      if (pusch_maxLength == 2)
+        l_ref = l_ref + i*L_ptrs + 1;
+      else
+        l_ref = l_ref + i*L_ptrs;
 
-			i = 1;
+       i = 1;
 
-			continue;
+       continue;
 
-		}
+    }
 
-		*ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs));
-		i++;
-	}
+    *ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs));
+    i++;
+  }
 }
 
 /*******************************************************************
@@ -313,7 +307,7 @@ uint8_t is_ptrs_symbol(uint8_t l,
                        uint16_t start_sc,
                        uint16_t ofdm_symbol_size,
                        pusch_dmrs_type_t pusch_dmrs_type,
-                       ptrs_UplinkConfig_t *ptrs_UplinkConfig) {
+                       uint8_t resourceElementOffset) {
 
   uint8_t is_ptrs_freq, is_ptrs_time;
   int16_t k_RE_ref;
@@ -321,7 +315,7 @@ uint8_t is_ptrs_symbol(uint8_t l,
   is_ptrs_freq = 0;
   is_ptrs_time = 0;
 
-  k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, ptrs_UplinkConfig->resourceElementOffset);
+  k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, resourceElementOffset);
 
   is_ptrs_freq = is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref, start_sc, ofdm_symbol_size);
 
@@ -426,4 +420,4 @@ int main(int argc, char const *argv[])
 
 	return 0;
 }
-*/
\ No newline at end of file
+*/
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h
index f3b42fff30..291ff4a555 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h
@@ -52,12 +52,11 @@ int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t
 uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB);
 
 void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
-                       ptrs_UplinkConfig_t *ptrs_UplinkConfig,
-                       dmrs_UplinkConfig_t *dmrs_UplinkConfig,
-                       uint8_t mapping_type,
                        uint8_t duration_in_symbols,
                        uint8_t start_symbol,
+                       uint8_t dmrs_type,
                        uint8_t L_ptrs,
+                       uint8_t pusch_maxLength,
                        uint16_t ofdm_symbol_size);
 
 uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs);
@@ -75,8 +74,8 @@ uint8_t is_ptrs_symbol(uint8_t l,
                        uint16_t start_sc,
                        uint16_t ofdm_symbol_size,
                        pusch_dmrs_type_t pusch_dmrs_type,
-                       ptrs_UplinkConfig_t *ptrs_UplinkConfig);
+                       uint8_t resourceElementOffset);
 
 
 
-#endif /* PTRS_NR_H */
\ No newline at end of file
+#endif /* PTRS_NR_H */
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index dd9f06d0f9..2e6fc707bd 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -333,23 +333,9 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
   ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid;
 
-  nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch->harq_processes[harq_pid]->ulsch_pdu;
+  memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
 
   LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
- 
-  
-  //FK this is still a bad hack. We need to replace the L1 FAPI structures with the new scf ones as well.
-  rel15_ul->rnti                           = ulsch_pdu->rnti;
-  rel15_ul->ulsch_pdu_rel15.start_rb       = ulsch_pdu->rb_start;
-  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.length_dmrs    = gNB->pusch_config.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;
-  rel15_ul->ulsch_pdu_rel15.n_layers       = ulsch_pdu->nrOfLayers;
-  rel15_ul->ulsch_pdu_rel15.R              = ulsch_pdu->target_code_rate;
 
 }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 52f3fbb5f9..a6fcb874f4 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -68,15 +68,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
 void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
                                  NR_gNB_PUSCH *pusch_vars,
                                  unsigned char symbol,
-                                 unsigned short start_rb,
-                                 unsigned short nb_rb_pusch,
-                                 uint16_t n_rnti,
-                                 NR_DL_FRAME_PARMS *frame_parms,
-                                 uint16_t number_symbols,
-                                 uint8_t mapping_type,
-                                 uint8_t ptrs_configured,
-                                 dmrs_UplinkConfig_t *dmrs_UplinkConfig,
-                                 ptrs_UplinkConfig_t *ptrs_Uplink_Config);
+                                 nfapi_nr_pusch_pdu_t *pusch_pdu,
+                                 NR_DL_FRAME_PARMS *frame_parms);
 
 void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
                             NR_DL_FRAME_PARMS *frame_parms,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index b4ce29eedf..7ff52ae692 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -53,12 +53,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
                            uint8_t UE_id,
                            short *ulsch_llr,
                            NR_DL_FRAME_PARMS *frame_parms,
+                           nfapi_nr_pusch_pdu_t *pusch_pdu,
                            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);
+                           uint32_t G);
 
 
 /*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 0b9e919b25..e8a961360f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -121,7 +121,7 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint
   if (N_RB_UL != 273) {
     a_segments = a_segments*N_RB_UL;
     a_segments = a_segments/273;
-  }  
+  }
 
   uint16_t ulsch_bytes = a_segments*1056;  // allocated bytes per segment
 
@@ -295,15 +295,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
                            uint8_t UE_id,
                            short *ulsch_llr,
                            NR_DL_FRAME_PARMS *frame_parms,
+                           nfapi_nr_pusch_pdu_t *pusch_pdu,
                            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)
-{
+                           uint32_t G) {
+
   uint32_t A,E;
-  uint32_t G;
   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;
@@ -317,7 +315,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
   NR_gNB_ULSCH_t                       *ulsch                 = phy_vars_gNB->ulsch[UE_id][0];
   NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
-  nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
   
   t_nrLDPC_dec_params decParams;
   t_nrLDPC_dec_params* p_decParams    = &decParams;
@@ -337,13 +334,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   double   Coderate = 0.0;
   
   // ------------------------------------------------------------------
-  uint16_t nb_rb          = nfapi_ulsch_pdu_rel15->number_rbs;
-  uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols;
-  uint8_t Qm              = nfapi_ulsch_pdu_rel15->Qm;
-  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 length_dmrs     = nfapi_ulsch_pdu_rel15->length_dmrs;
+  uint16_t nb_rb          = pusch_pdu->rb_size;
+  uint8_t Qm              = pusch_pdu->qam_mod_order;
+  uint16_t R              = pusch_pdu->target_code_rate;
+  uint8_t mcs             = pusch_pdu->mcs_index;
+  uint8_t n_layers        = pusch_pdu->nrOfLayers;
   // ------------------------------------------------------------------
 
   uint32_t i,j;
@@ -363,19 +358,20 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   }
 
   // harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
-  harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs*length_dmrs, 0, n_layers);
+  harq_process->TBS = pusch_pdu->pusch_data.tb_size;
 
-  A   = harq_process->TBS;
+  A   = (harq_process->TBS)<<3;
   ret = ulsch->max_ldpc_iterations + 1;
 
-  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, 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);
+  LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
 
   if (harq_process->round == 0) {
 
     // This is a new packet, so compute quantities regarding segmentation
-    harq_process->B = A+24;
+    if (A > 3824)
+      harq_process->B = A+24;
+    else
+      harq_process->B = A+16;
 
     if (R<1024)
       Coderate = (float) R /(float) 1024;
@@ -412,20 +408,20 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
     }
   }
 
-    // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
-    nr_segmentation(NULL,
-                    NULL,
-                    harq_process->B,
-                    &harq_process->C,
-                    &harq_process->K,
-                    &harq_process->Z, // [hna] Z is Zc
-                    &harq_process->F,
-                    p_decParams->BG);
+  // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
+  nr_segmentation(NULL,
+                  NULL,
+                  harq_process->B,
+                  &harq_process->C,
+                  &harq_process->K,
+                  &harq_process->Z, // [hna] Z is Zc
+                  &harq_process->F,
+                  p_decParams->BG);
 
 #ifdef DEBUG_ULSCH_DECODING
     printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
     if (!frame%100)
-      printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl);
+      printf("K %d C %d Z %d\n", harq_process->K, harq_process->C, harq_process->Z);
 #endif
   }
   p_decParams->Z = harq_process->Z;
@@ -442,7 +438,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   if (nb_rb != 273) {
     a_segments = a_segments*nb_rb;
     a_segments = a_segments/273;
-  }  
+  }
 
   if (harq_process->C > a_segments) {
     LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
@@ -460,7 +456,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   K_bytes_F = Kr_bytes-(harq_process->F>>3);
 
   for (r=0; rC; r++) {
-    E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
+    E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
 
 #if gNB_TIMING_TRACE
     start_meas(ulsch_deinterleaving_stats);
@@ -473,7 +469,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
     //////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
 
     nr_deinterleaving_ldpc(E,
-                           nfapi_ulsch_pdu_rel15->Qm,
+                           Qm,
                            harq_process->e[r],
                            ulsch_llr+r_offset);
 
@@ -493,10 +489,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
           harq_pid,r, G,
           Kr*3,
           harq_process->TBS,
-          nfapi_ulsch_pdu_rel15->Qm,
-          nfapi_ulsch_pdu_rel15->number_rbs,
-          nfapi_ulsch_pdu_rel15->n_layers,
-          nfapi_ulsch_pdu_rel15->rv,
+          Qm,
+          nb_rb,
+          n_layers,
+          pusch_pdu->pusch_data.rv_index,
           harq_process->round);
 #endif
     //////////////////////////////////////////////////////////////////////////////////////////
@@ -508,7 +504,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
     ///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
 
-    Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C);
+    Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
 
     if (nr_rate_matching_ldpc_rx(Ilbrm,
                                  Tbslbrm,
@@ -517,7 +513,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
                                  harq_process->d[r],
                                  harq_process->e[r],
                                  harq_process->C,
-                                 nfapi_ulsch_pdu_rel15->rv,
+                                 pusch_pdu->pusch_data.rv_index,
                                  (harq_process->round==0)?1:0,
                                  E,
 				 harq_process->F,
@@ -554,7 +550,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
     //    printf("done\n");
     if (harq_process->C == 1) {
-      crc_type = CRC24_A;
+      if (A > 3824)
+        crc_type = CRC24_A;
+      else
+        crc_type = CRC16;
+
       length_dec = harq_process->B;
     }
     else {
@@ -653,7 +653,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   int32_t tti_rx_prev = nr_tti_rx - 1;
   if (tti_rx_prev < 0) {
     frame_rx_prev--;
-    tti_rx_prev += 10*frame_parms->ttis_per_subframe;
+    tti_rx_prev += frame_parms->slots_per_frame;
   }
   frame_rx_prev = frame_rx_prev%1024;
 
@@ -677,10 +677,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
       ulsch->harq_mask &= ~(1 << harq_pid);
     }
 
-    if(is_crnti) {
-      LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
-            phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
-    }
+    //  LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+       //     phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
 
     harq_process->handled  = 1;
     ret = ulsch->max_ldpc_iterations + 1;
@@ -700,10 +698,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
     // harq_process->harq_ack.harq_id = harq_pid;
     // harq_process->harq_ack.send_harq_status = 1;
 
-    if(is_crnti)
-    {
-      LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
-    }
+    //  LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
 
     // Reassembly of Transport block here
     offset = 0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 8ca920359e..e02278d664 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -222,18 +222,12 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
 
 }
 
+
 void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
                                  NR_gNB_PUSCH *pusch_vars,
                                  unsigned char symbol,
-                                 unsigned short start_rb,
-                                 unsigned short nb_rb_pusch,
-                                 uint16_t n_rnti,
-                                 NR_DL_FRAME_PARMS *frame_parms,
-                                 uint16_t number_symbols,
-                                 uint8_t mapping_type,
-                                 uint8_t ptrs_configured,
-                                 dmrs_UplinkConfig_t *dmrs_UplinkConfig,
-                                 ptrs_UplinkConfig_t *ptrs_Uplink_Config)
+                                 nfapi_nr_pusch_pdu_t *pusch_pdu,
+                                 NR_DL_FRAME_PARMS *frame_parms)
 {
   unsigned short start_re, re, nb_re_pusch;
   unsigned char aarx;
@@ -248,22 +242,23 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
   int16_t *rxF,*rxF_ext;
   int *ul_ch0,*ul_ch0_ext;
   int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
+  uint16_t n_rnti = pusch_pdu->rnti;
 
 #ifdef DEBUG_RB_EXT
 
   printf("--------------------symbol = %d-----------------------\n", symbol);
-  printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch);
+  printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size);
 
 #endif
   
-  start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
+  start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
   
-  nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
+  nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
   is_dmrs_symbol_flag = 0;
   is_ptrs_symbol_flag = 0;
   num_ptrs_symbols = 0;
 
-  K_ptrs = get_K_ptrs(ptrs_Uplink_Config, nb_rb_pusch);
+  K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
 
   for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
     
@@ -289,24 +284,23 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
                                             k_prime,
                                             n,
                                             0,
-                                            number_symbols,
-                                            dmrs_UplinkConfig,
-                                            mapping_type,
+                                            pusch_pdu->nr_of_symbols,
+                                            pusch_pdu->dmrs_config_type,
                                             frame_parms->ofdm_symbol_size);
 
-      if (ptrs_configured == 1){
+      if ( ((pusch_pdu->pdu_bit_map)>>2)& 0x01 ) {
         is_ptrs_symbol_flag = is_ptrs_symbol(symbol,
                                              (start_re + re)%frame_parms->ofdm_symbol_size,
                                              n_rnti,
-                                             nb_rb_pusch,
-                                             number_symbols,
+                                             pusch_pdu->rb_size,
+                                             pusch_pdu->nr_of_symbols,
                                              aarx,
                                              K_ptrs,
                                              pusch_vars->ptrs_symbols,
                                              start_re,
                                              frame_parms->ofdm_symbol_size,
-                                             dmrs_UplinkConfig->pusch_dmrs_type,
-                                             ptrs_Uplink_Config);
+                                             pusch_pdu->dmrs_config_type,
+                                             pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset);
 
         if (is_ptrs_symbol_flag == 1)
           num_ptrs_symbols++;
@@ -505,18 +499,17 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
 }
 
 void nr_ulsch_channel_compensation(int **rxdataF_ext,
-                                int **ul_ch_estimates_ext,
-                                int **ul_ch_mag,
-                                int **ul_ch_magb,
-                                int **rxdataF_comp,
-                                int **rho,
-                                NR_DL_FRAME_PARMS *frame_parms,
-                                unsigned char symbol,
-                                uint8_t is_dmrs_symbol,
-                                unsigned char mod_order,
-                                unsigned short nb_rb,
-                                unsigned char output_shift)
-{
+                                   int **ul_ch_estimates_ext,
+                                   int **ul_ch_mag,
+                                   int **ul_ch_magb,
+                                   int **rxdataF_comp,
+                                   int **rho,
+                                   NR_DL_FRAME_PARMS *frame_parms,
+                                   unsigned char symbol,
+                                   uint8_t is_dmrs_symbol,
+                                   unsigned char mod_order,
+                                   unsigned short nb_rb,
+                                   unsigned char output_shift) {
 
 #ifdef DEBUG_CH_COMP
   int16_t *rxF, *ul_ch;
@@ -1039,172 +1032,155 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
 
   uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
   uint32_t nb_re_pusch, bwp_start_subcarrier;
-  uint8_t mapping_type;
   uint8_t L_ptrs = 0; // PTRS parameter
   int avgs;
   int avg[4];
   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;
-  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
+  nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu;
 
   dmrs_symbol_flag = 0;
   ptrs_symbol_flag = 0;
   first_symbol_flag = 0;
-  mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
   gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0;
 
-  if (mapping_type == typeB) {
+  if(symbol == rel15_ul->start_symbol_index){
+    gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
+    gNB->pusch_vars[UE_id]->dmrs_symbol = 0;
+    gNB->pusch_vars[UE_id]->cl_done = 0;
+    gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
+    first_symbol_flag = 1;
 
-    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;
-
-      L_ptrs = get_L_ptrs(ptrs_Uplink_Config, rel15_ul->mcs);
-
-      gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
+    if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) {  // if there is ptrs pdu
+      L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
 
       set_ptrs_symb_idx(&gNB->pusch_vars[UE_id]->ptrs_symbols,
-                        ptrs_Uplink_Config,
-                        &gNB->pusch_config.dmrs_UplinkConfig,
-                        1,
-                        rel15_ul->number_symbols,
-                        rel15_ul->start_symbol,
+                        rel15_ul->nr_of_symbols,
+                        rel15_ul->start_symbol_index,
+                        rel15_ul->dmrs_config_type,
                         L_ptrs,
+                        1, // only dmrs of length 1 is currently supported
                         frame_parms->ofdm_symbol_size);
-
     }
-
-    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->pusch_config.dmrs_UplinkConfig,
-                                      mapping_type,
-                                      frame_parms->ofdm_symbol_size);
-
-    if (dmrs_symbol_flag == 1){
-      nb_re_pusch = rel15_ul->number_rbs * ((gNB->pusch_config.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;
-    }
-
-    if (gNB->ptrs_configured == 1)
-        ptrs_symbol_flag = is_ptrs_symbol(symbol,
-                                          0,
-                                          gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti,
-                                          rel15_ul->number_rbs,
-                                          rel15_ul->number_symbols,
-                                          0,
-                                          get_K_ptrs(ptrs_Uplink_Config, rel15_ul->number_rbs),
-                                          gNB->pusch_vars[UE_id]->ptrs_symbols,
-                                          0,
-                                          frame_parms->ofdm_symbol_size,
-                                          gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
-                                          ptrs_Uplink_Config);
-
-
-    if (ptrs_symbol_flag == 1){
-      gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
-    }
-
-
-    //----------------------------------------------------------
-    //--------------------- Channel estimation ---------------------
-    //----------------------------------------------------------
-
-    if (dmrs_symbol_flag == 1)
-      nr_pusch_channel_estimation(gNB,
-                                  0,
-                                  nr_tti_rx,
-                                  0, // p
-                                  symbol,
-                                  bwp_start_subcarrier,
-                                  rel15_ul->number_rbs,
-                                  &gNB->pusch_config.dmrs_UplinkConfig);
-
-    //----------------------------------------------------------
-    //--------------------- RBs extraction ---------------------
-    //----------------------------------------------------------
-
-    nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
-                                gNB->pusch_vars[UE_id],
-                                symbol,
-                                rel15_ul->start_rb,
-                                rel15_ul->number_rbs,
-                                gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti,
-                                frame_parms,
-                                rel15_ul->number_symbols,
-                                mapping_type,
-                                gNB->ptrs_configured,
-                                &gNB->pusch_config.dmrs_UplinkConfig,
-                                ptrs_Uplink_Config);
-
-    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,
-                           gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type);
-
-    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 - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
-  } else {
-    LOG_E(PHY, "PUSCH mapping type A is not supported \n");
   }
+
+  bwp_start_subcarrier = (rel15_ul->rb_start*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->nr_of_symbols,
+                                    rel15_ul->dmrs_config_type,
+                                    frame_parms->ofdm_symbol_size);
+
+  if (dmrs_symbol_flag == 1){
+    nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8);
+    gNB->pusch_vars[UE_id]->dmrs_symbol = symbol;
+  } else {
+    nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
+  }
+
+  if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) {  // if there is ptrs pdu
+    ptrs_symbol_flag = is_ptrs_symbol(symbol,
+                                      0,
+                                      rel15_ul->rnti,
+                                      rel15_ul->rb_size,
+                                      rel15_ul->nr_of_symbols,
+                                      0,
+                                      (rel15_ul->pusch_ptrs.ptrs_freq_density)?4:2,
+                                      gNB->pusch_vars[UE_id]->ptrs_symbols,
+                                      0,
+                                      frame_parms->ofdm_symbol_size,
+                                      rel15_ul->dmrs_config_type,
+                                      rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset);
+  }
+
+  if (ptrs_symbol_flag == 1){
+    gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
+  }
+
+
+  //----------------------------------------------------------
+  //--------------------- Channel estimation ---------------------
+  //----------------------------------------------------------
+
+  if (dmrs_symbol_flag == 1)
+    nr_pusch_channel_estimation(gNB,
+                                nr_tti_rx,
+                                0, // p
+                                symbol,
+                                bwp_start_subcarrier,
+                                rel15_ul);
+
+  //----------------------------------------------------------
+  //--------------------- RBs extraction ---------------------
+  //----------------------------------------------------------
+
+  nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
+                              gNB->pusch_vars[UE_id],
+                              symbol,
+                              rel15_ul,
+                              frame_parms);
+
+  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->rb_size,
+                         rel15_ul->dmrs_config_type);
+
+
+  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->rb_size);
+     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->qam_mod_order,
+                                rel15_ul->rb_size,
+                                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->rb_size * 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->rb_size * 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->qam_mod_order],
+                       rel15_ul->rb_size,
+                       nb_re_pusch,
+                       symbol,
+                       rel15_ul->qam_mod_order);
+
+  gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset +  nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
   
 }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 6bcaba4604..55bac90520 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -292,17 +292,35 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
       printf("%02x.",a[i]);
     printf("\n");
     */
-    // Add 24-bit crc (polynomial A) to payload
-    crc = crc24a(harq_process->a,A)>>8;
-    harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
-    harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[1];
-    harq_process->a[2+(A>>3)] = ((uint8_t*)&crc)[0];
-    //printf("CRC %x (A %d)\n",crc,A);
-    //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
+    if (A > 3824) {
+      // Add 24-bit crc (polynomial A) to payload
+      crc = crc24a(harq_process->a,A)>>8;
+      harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
+      harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[1];
+      harq_process->a[2+(A>>3)] = ((uint8_t*)&crc)[0];
+      //printf("CRC %x (A %d)\n",crc,A);
+      //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
 
-    harq_process->B = A+24;
+      harq_process->B = A+24;
 
-    memcpy(harq_process->b,harq_process->a,(A/8)+4);
+      AssertFatal((A/8)+4 <= MAX_NR_ULSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_NR_ULSCH_PAYLOAD_BYTES);
+
+      memcpy(harq_process->b,harq_process->a,(A/8)+4);
+    }
+    else {
+      // Add 16-bit crc (polynomial A) to payload
+      crc = crc16(harq_process->a,A)>>16;
+      harq_process->a[A>>3] = ((uint8_t*)&crc)[1];
+      harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[0];
+      //printf("CRC %x (A %d)\n",crc,A);
+      //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
+
+      harq_process->B = A+16;
+
+      AssertFatal((A/8)+3 <= MAX_NR_ULSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_NR_ULSCH_PAYLOAD_BYTES);
+
+      memcpy(harq_process->b,harq_process->a,(A/8)+3);  // using 3 bytes to mimic the case of 24 bit crc
+    }
 
 ///////////
 ///////////////////////////////////////////////////////////////////////////
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 1dd971fc90..bdd8ea8c24 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -108,7 +108,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   int8_t Wf[2], Wt[2], l_prime[2], delta;
   uint16_t n_dmrs, code_rate, number_dmrs_symbols, k;
   uint8_t dmrs_type;
-  uint8_t mapping_type;
   int ap, start_symbol, Nid_cell, i;
   int sample_offsetF, N_RE_prime, N_PRB_oh;
   uint16_t n_rnti;
@@ -129,8 +128,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   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];
@@ -146,8 +143,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                             0,
                                             0,
                                             harq_process_ul_ue->number_of_symbols,
-                                            &UE->pusch_config.dmrs_UplinkConfig,
-                                            mapping_type,
+                                            UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
                                             frame_parms->ofdm_symbol_size);
 
     ulsch_ue->length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength;
@@ -303,12 +299,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     ulsch_ue->ptrs_symbols = 0;
 
     set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols,
-                      ptrs_Uplink_Config,
-                      &UE->pusch_config.dmrs_UplinkConfig,
-                      1,
                       harq_process_ul_ue->number_of_symbols,
                       start_symbol,
+                      dmrs_type,
                       L_ptrs,
+                      ulsch_ue->length_dmrs,
                       frame_parms->ofdm_symbol_size);
   }
 
@@ -347,8 +342,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                              0,
                              0,
                              harq_process_ul_ue->number_of_symbols,
-                             &UE->pusch_config.dmrs_UplinkConfig,
-                             mapping_type,
+                             dmrs_type,
                              frame_parms->ofdm_symbol_size);
 
     if (is_dmrs == 1)
@@ -414,8 +408,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                  n,
                                  delta,
                                  harq_process_ul_ue->number_of_symbols,
-                                 &UE->pusch_config.dmrs_UplinkConfig,
-                                 mapping_type,
+                                 dmrs_type,
                                  frame_parms->ofdm_symbol_size);
 
         if (UE->ptrs_configured == 1){
@@ -430,7 +423,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                    start_sc,
                                    frame_parms->ofdm_symbol_size,
                                    UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
-                                   ptrs_Uplink_Config);
+                                   ptrs_Uplink_Config->resourceElementOffset);
         }
 
         if (is_dmrs == 1) {
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 04351d6434..b5a24ca793 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -162,7 +162,7 @@ typedef struct {
 
 typedef struct {
   /// Nfapi ULSCH PDU
-  nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
+  nfapi_nr_pusch_pdu_t ulsch_pdu;
   /// Frame where current HARQ round was sent
   uint32_t frame;
   /// Subframe where current HARQ round was sent
@@ -410,7 +410,7 @@ 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.
+  /// DMRS symbol index, to be updated every DMRS symbol within a slot.
   uint8_t dmrs_symbol;
   // PTRS symbol index, to be updated every PTRS symbol within a slot.
   uint8_t ptrs_symbol_index;
@@ -418,6 +418,8 @@ typedef struct {
   uint16_t ptrs_symbols;
   // PTRS subcarriers per OFDM symbol
   uint16_t ptrs_sc_per_ofdm_symbol;
+  /// flag to verify if channel level computation is done
+  uint8_t cl_done;
 } NR_gNB_PUSCH;
 
 
@@ -672,11 +674,8 @@ typedef struct PHY_VARS_gNB_s {
   /// PDSCH DMRS sequence
   uint32_t ****nr_gold_pdsch_dmrs;
 
-  /// flag to indicate if PTRS is configured
-  uint8_t ptrs_configured;
-  
   /// PUSCH DMRS
-  uint32_t nr_gold_pusch[2][20][2][NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD];
+  uint32_t ****nr_gold_pusch_dmrs;
 
   /// Indicator set to 0 after first SR
   uint8_t first_sr[NUMBER_OF_NR_SR_MAX];
@@ -710,12 +709,6 @@ typedef struct PHY_VARS_gNB_s {
   /// counter to average prach energh over first 100 prach opportunities
   int prach_energy_counter;
 
-  PUSCH_Config_t pusch_config;
-
-  dmrs_UplinkConfig_t dmrs_UplinkConfig;
-
-  dmrs_DownlinkConfig_t dmrs_DownlinkConfig;
-
   /*
   time_stats_t phy_proc;
   */
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index bbb3da5d52..44f2e314ea 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -500,8 +500,8 @@ typedef enum {
   pdsch_dmrs_type2 = 2
 } pdsch_dmrs_type_t;
 typedef enum {
-  pusch_dmrs_type1 = 1,
-  pusch_dmrs_type2 = 2
+  pusch_dmrs_type1 = 0,
+  pusch_dmrs_type2 = 1
 } pusch_dmrs_type_t;
 typedef enum {
   pdsch_dmrs_pos0 = 0,
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 909b91a81c..b28911b495 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -214,21 +214,16 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
 
 void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
 {
-  NR_DL_FRAME_PARMS                    *frame_parms           = &gNB->frame_parms;
-  nfapi_nr_ul_config_ulsch_pdu         *rel15_ul              = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu;
-  nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &rel15_ul->ulsch_pdu_rel15;
+  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+  nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu;
   
   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)
   uint16_t start_symbol, number_symbols, nb_re_dmrs;
 
-  mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
-
-  start_symbol = nfapi_ulsch_pdu_rel15->start_symbol;
-  number_symbols = nfapi_ulsch_pdu_rel15->number_symbols;
+  start_symbol = pusch_pdu->start_symbol_index;
+  number_symbols = pusch_pdu->nr_of_symbols;
 
   for (l = start_symbol; l < start_symbol + number_symbols; l++)
       number_dmrs_symbols += is_dmrs_symbol(l,
@@ -238,18 +233,18 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
                                             0,
                                             0,
                                             number_symbols,
-                                            &gNB->pusch_config.dmrs_UplinkConfig,
-                                            mapping_type,
+                                            pusch_pdu->dmrs_config_type,
                                             frame_parms->ofdm_symbol_size);
 
-  nb_re_dmrs = ((gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
 
-  G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs,
+  nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
+
+  G = nr_get_G(pusch_pdu->rb_size,
                number_symbols,
                nb_re_dmrs,
-               nfapi_ulsch_pdu_rel15->length_dmrs,
-               nfapi_ulsch_pdu_rel15->Qm,
-               nfapi_ulsch_pdu_rel15->n_layers);
+               1, // FIXME only single dmrs is implemented
+               pusch_pdu->qam_mod_order,
+               pusch_pdu->nrOfLayers);
 
 
   //----------------------------------------------------------
@@ -259,23 +254,23 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
   nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr,
                         G,
                         0,
-                        Nid_cell,
-                        rel15_ul->rnti);
+                        pusch_pdu->data_scrambling_id,
+                        pusch_pdu->rnti);
 
   //----------------------------------------------------------
   //--------------------- ULSCH decoding ---------------------
   //----------------------------------------------------------
 
   ret = nr_ulsch_decoding(gNB,
-                    ULSCH_id,
-                    gNB->pusch_vars[ULSCH_id]->llr,
-                    frame_parms,
-                    frame_rx,
-                    number_symbols,
-                    nb_re_dmrs,
-                    slot_rx,
-                    harq_pid,
-                    0);
+                          ULSCH_id,
+                          gNB->pusch_vars[ULSCH_id]->llr,
+                          frame_parms,
+                          pusch_pdu,
+                          frame_rx,
+                          slot_rx,
+                          harq_pid,
+                          G);
+
         
   if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations)
     LOG_I(PHY, "ULSCH %d in error\n",ULSCH_id);
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index 0b9340debd..48ea26da8f 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -371,7 +371,6 @@ int main(int argc, char **argv)
   }
 
   unsigned char harq_pid = 0;
-  uint8_t is_crnti = 0;
   unsigned int TBS = 8424;
   unsigned int available_bits;
   uint8_t nb_re_dmrs = 6;
@@ -385,7 +384,7 @@ int main(int argc, char **argv)
 
   NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0];
   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;
+  nfapi_nr_pusch_pdu_t *rel15_ul = &harq_process_gNB->ulsch_pdu;
 
   NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
 
@@ -397,14 +396,15 @@ int main(int argc, char **argv)
   printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
 
   /////////// setting rel15_ul parameters ///////////
-  rel15_ul->number_rbs     = nb_rb;
-  rel15_ul->number_symbols = nb_symb_sch;
-  rel15_ul->Qm             = mod_order;
-  rel15_ul->mcs            = Imcs;
-  rel15_ul->rv             = rvidx;
-  rel15_ul->n_layers       = Nl;
-  rel15_ul->length_dmrs    = length_dmrs;
-  rel15_ul->R              = code_rate;
+  rel15_ul->rb_size             = nb_rb;
+  rel15_ul->nr_of_symbols       = nb_symb_sch;
+  rel15_ul->qam_mod_order       = mod_order;
+  rel15_ul->mcs_index           = Imcs;
+  rel15_ul->pusch_data.rv_index = rvidx;
+  rel15_ul->nrOfLayers          = Nl;
+  //rel15_ul->length_dmrs       = length_dmrs;
+  rel15_ul->target_code_rate    = code_rate;
+  rel15_ul->pusch_data.tb_size  = TBS>>3;
   ///////////////////////////////////////////////////
 
   double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
@@ -527,8 +527,15 @@ int main(int argc, char **argv)
       exit(-1);
 #endif
 
-      ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms,
-                              frame, nb_symb_sch, nb_re_dmrs, subframe, harq_pid, is_crnti);
+     uint32_t G = nr_get_G(rel15_ul->rb_size,
+                           rel15_ul->nr_of_symbols,
+                           nb_re_dmrs,
+                           1, // FIXME only single dmrs is implemented 
+                           rel15_ul->qam_mod_order,
+                           rel15_ul->nrOfLayers);
+
+      ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
+                              frame, subframe, harq_pid, G);
 
       if (ret > ulsch_gNB->max_ldpc_iterations)
         n_errors++;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 1ca4a5a389..2adc67501a 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -511,8 +511,7 @@ int main(int argc, char **argv)
                                             0,
                                             0,
                                             nb_symb_sch,
-                                            &UE->pusch_config.dmrs_UplinkConfig,
-                                            UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType,
+                                            UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
                                             frame_parms->ofdm_symbol_size);
 
   mod_order      = nr_get_Qm_ul(Imcs, 0);
@@ -563,10 +562,6 @@ int main(int argc, char **argv)
       pusch_pdu->nrOfLayers = 1;
       pusch_pdu->ul_dmrs_symb_pos = 1;
       pusch_pdu->dmrs_config_type = 0;
-      // inserted to make simulation work 
-      // remove the next 2 lines when P7 is integrated from new branch
-      gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type=pusch_dmrs_type1;
-      gNB->pusch_config.dmrs_UplinkConfig.pusch_maxLength   = length_dmrs;
       pusch_pdu->ul_dmrs_scrambling_id =  0;
       pusch_pdu->scid = 0;
       pusch_pdu->resource_alloc = 1; 
@@ -580,7 +575,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 = TBS;
+      pusch_pdu->pusch_data.tb_size = TBS>>3;
       pusch_pdu->pusch_data.num_cb = 0;
 
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 85d0a04b54..f1e2e8e071 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -781,13 +781,13 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
   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->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
 						 pusch_pdu->target_code_rate,
 						 pusch_pdu->rb_size,
 						 pusch_pdu->nr_of_symbols,
 						 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI
 						 0, //nb_rb_oh
-						 pusch_pdu->nrOfLayers = 1);
+						 pusch_pdu->nrOfLayers)>>3;
   pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
   //pusch_pdu->pusch_data.cb_present_and_position;
   //pusch_pdu->pusch_uci;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index c357f0071b..9376855882 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -921,28 +921,6 @@ int extract_length(int startSymbolAndLength) {
   if (tmp > 0 && tmp < (14-tmp2)) return(tmp);
   else                            return(15-tmp2);
 }
- 
-void fill_initialBWPDLtimeDomainAllocaion(nfapi_nr_config_request_t *cfg,int time_domain_assignment,int *k0,int *mappingType,int *start_symbol,int *length) {
-  AssertFatal(time_domain_assignment < cfg->pdsch_config.num_PDSCHTimeDomainResourceAllocations.value,"DL time_domain_assignment %d >= %d\n",
-	      time_domain_assignment,cfg->pdsch_config.num_PDSCHTimeDomainResourceAllocations.value);
-  *k0           = cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_k0[time_domain_assignment].value;
-  *mappingType = cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_mappingType[time_domain_assignment].value;
-  *start_symbol = extract_startSymbol(cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_startSymbolAndLength[time_domain_assignment].value);
-  *length       = extract_length(cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_startSymbolAndLength[time_domain_assignment].value);
-
-}
-
-
-
-void fill_initialBWPULtimeDomainAllocaion(nfapi_nr_config_request_t *cfg,int time_domain_assignment,int *k2, int *mappingType, int *start_symbol,int *length) {
-  AssertFatal(time_domain_assignment < cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value,"UL time_domain_assignment %d >= %d\n",
-	      time_domain_assignment,cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value);
-
-  *k2           = cfg->pusch_config.PUSCHTimeDomainResourceAllocation_k2[time_domain_assignment].value;
-  *mappingType = cfg->pusch_config.PUSCHTimeDomainResourceAllocation_mappingType[time_domain_assignment].value;
-  *start_symbol = extract_startSymbol(cfg->pusch_config.PUSCHTimeDomainResourceAllocation_startSymbolAndLength[time_domain_assignment].value);
-  *length       = extract_length(cfg->pusch_config.PUSCHTimeDomainResourceAllocation_startSymbolAndLength[time_domain_assignment].value);
-}
 
 /*
  * Dump the UL or DL UE_list into LOG_T(MAC)

From ad1a102f08faa5c50c068b7ffd60a8d128943028 Mon Sep 17 00:00:00 2001
From: Cedric Roux 
Date: Fri, 20 Mar 2020 11:13:51 +0100
Subject: [PATCH 329/343] fix for CU/DU split

---
 openair2/RRC/LTE/rrc_eNB.c      |   5 +-
 openair2/RRC/LTE/rrc_eNB_endc.c | 160 --------------------------------
 2 files changed, 1 insertion(+), 164 deletions(-)

diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 7de5a2c64c..1d25bf180a 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -8510,7 +8510,7 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP,
     unsigned char buffer[8192];
     int size;
 
-    ue_context = (rrc_eNB_ue_context_t *) get_first_ue_context(RC.rrc[enb_mod_idP]);
+    ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti);
 
     PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
                                     0,
@@ -8893,9 +8893,6 @@ rrc_enb_task(
 {
   rrc_enb_init();
 
-void rrc_endc_hack_init(void);
-rrc_endc_hack_init();
-
   itti_mark_task_ready(TASK_RRC_ENB);
   LOG_I(RRC,"Entering main loop of RRC message task\n");
 
diff --git a/openair2/RRC/LTE/rrc_eNB_endc.c b/openair2/RRC/LTE/rrc_eNB_endc.c
index d6fb910507..3d3d9787b5 100644
--- a/openair2/RRC/LTE/rrc_eNB_endc.c
+++ b/openair2/RRC/LTE/rrc_eNB_endc.c
@@ -241,163 +241,3 @@ printf("\n");
 
   return (enc_rval.encoded + 7) / 8;
 }
-
-volatile int go_nr;
-
-struct rrc_eNB_ue_context_s *
-get_first_ue_context(eNB_RRC_INST *rrc_instance_pP)
-{
-  struct rrc_eNB_ue_context_s   *ue_context_p = NULL;
-  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
-    return ue_context_p;
-  }
-  return NULL;
-}
-
-void rrc_go_nr(void)
-{
-  protocol_ctxt_t ctxt;
-  rrc_eNB_ue_context_t *ue_context;
-  unsigned char buffer[8192];
-  int size;
-
-  go_nr = 0;
-
-  ue_context = get_first_ue_context(RC.rrc[0]);
-
-  PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
-                                0,
-                                ENB_FLAG_YES,
-                                ue_context->ue_context.rnti,
-                                0, 0);
-
-  size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, NULL, NULL);
-
-  rrc_data_req(&ctxt,
-               DCCH,
-               rrc_eNB_mui++,
-               SDU_CONFIRM_NO,
-               size,
-               buffer,
-               PDCP_TRANSMISSION_MODE_CONTROL);
-}
-
-static void new_thread(void *(*f)(void *), void *data) {
-  pthread_t t;
-  pthread_attr_t att;
-
-  if (pthread_attr_init(&att)) {
-    fprintf(stderr, "pthread_attr_init err\n");
-    exit(1);
-  }
-
-  if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
-    fprintf(stderr, "pthread_attr_setdetachstate err\n");
-    exit(1);
-  }
-
-  if (pthread_attr_setstacksize(&att, 10000000)) {
-    fprintf(stderr, "pthread_attr_setstacksize err\n");
-    exit(1);
-  }
-
-  if (pthread_create(&t, &att, f, data)) {
-    fprintf(stderr, "pthread_create err\n");
-    exit(1);
-  }
-
-  if (pthread_attr_destroy(&att)) {
-    fprintf(stderr, "pthread_attr_destroy err\n");
-    exit(1);
-  }
-}
-
-static int create_listen_socket(char *addr, int port) {
-  struct sockaddr_in a;
-  int s;
-  int v;
-  s = socket(AF_INET, SOCK_STREAM, 0);
-
-  if (s == -1) {
-    perror("socket");
-    exit(1);
-  }
-
-  v = 1;
-
-  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int))) {
-    perror("setsockopt");
-    exit(1);
-  }
-
-  a.sin_family = AF_INET;
-  a.sin_port = htons(port);
-  a.sin_addr.s_addr = inet_addr(addr);
-
-  if (bind(s, (struct sockaddr *)&a, sizeof(a))) {
-    perror("bind");
-    exit(1);
-  }
-
-  if (listen(s, 5)) {
-    perror("listen");
-    exit(1);
-  }
-
-  return s;
-}
-
-static int socket_accept(int s) {
-  struct sockaddr_in a;
-  socklen_t alen;
-  alen = sizeof(a);
-  return accept(s, (struct sockaddr *)&a, &alen);
-}
-
-static 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 *nr_hack(void *_)
-{
-  int s = create_listen_socket("0.0.0.0", 9001);
-  int t;
-
-over:
-  t = socket_accept(s);
-
-  while (1) {
-    char c;
-
-    if (fullread(t, &c, 1) != 1) {
-      close(t);
-      goto over;
-    }
-
-    if (c != '\n') continue;
-
-    printf("setting go_nr to 1\n");
-    go_nr = 1;
-  }
-
-  return 0;
-}
-
-void rrc_endc_hack_init(void)
-{
-  new_thread(nr_hack, NULL);
-}

From b904161f871b1a75a68f2b6b483360624737f4ae Mon Sep 17 00:00:00 2001
From: Francesco Mani 
Date: Fri, 20 Mar 2020 11:15:43 +0100
Subject: [PATCH 330/343] removing is_dmrs_symbol function from pusch in gNB

---
 .../PHY/NR_TRANSPORT/nr_transport_proto.h     |  1 +
 .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c  | 33 +++++++------------
 openair1/SCHED_NR/phy_procedures_nr_gNB.c     | 11 +------
 3 files changed, 13 insertions(+), 32 deletions(-)

diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index a6fcb874f4..9ce56421fc 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -68,6 +68,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
 void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
                                  NR_gNB_PUSCH *pusch_vars,
                                  unsigned char symbol,
+                                 uint8_t is_dmrs_symbol,
                                  nfapi_nr_pusch_pdu_t *pusch_pdu,
                                  NR_DL_FRAME_PARMS *frame_parms);
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index e02278d664..bce8ddcc29 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -226,6 +226,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
 void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
                                  NR_gNB_PUSCH *pusch_vars,
                                  unsigned char symbol,
+                                 uint8_t is_dmrs_symbol,
                                  nfapi_nr_pusch_pdu_t *pusch_pdu,
                                  NR_DL_FRAME_PARMS *frame_parms)
 {
@@ -237,12 +238,13 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
   uint32_t ul_ch0_index = 0;
   uint32_t ul_ch0_ptrs_ext_index = 0;
   uint32_t ul_ch0_ptrs_index = 0;
-  uint8_t is_dmrs_symbol_flag, is_ptrs_symbol_flag,k_prime;
+  uint8_t is_ptrs_symbol_flag,k_prime;
   uint16_t n=0, num_ptrs_symbols;
   int16_t *rxF,*rxF_ext;
   int *ul_ch0,*ul_ch0_ext;
   int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
   uint16_t n_rnti = pusch_pdu->rnti;
+  uint8_t delta = 0;
 
 #ifdef DEBUG_RB_EXT
 
@@ -251,10 +253,9 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
 
 #endif
   
+  uint8_t is_dmrs_re;
   start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
-  
   nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
-  is_dmrs_symbol_flag = 0;
   is_ptrs_symbol_flag = 0;
   num_ptrs_symbols = 0;
 
@@ -278,15 +279,10 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
 
     for (re = 0; re < nb_re_pusch; re++) {
 
-      is_dmrs_symbol_flag =  is_dmrs_symbol(symbol,
-                                            (start_re + re)%frame_parms->ofdm_symbol_size,
-                                            start_re,
-                                            k_prime,
-                                            n,
-                                            0,
-                                            pusch_pdu->nr_of_symbols,
-                                            pusch_pdu->dmrs_config_type,
-                                            frame_parms->ofdm_symbol_size);
+      if (is_dmrs_symbol)
+        is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
+      else
+        is_dmrs_re = 0;
 
       if ( ((pusch_pdu->pdu_bit_map)>>2)& 0x01 ) {
         is_ptrs_symbol_flag = is_ptrs_symbol(symbol,
@@ -311,7 +307,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
       printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol);
   #endif
 
-      if ( is_dmrs_symbol_flag == 0 && is_ptrs_symbol_flag == 0) {
+      if ( is_dmrs_re == 0 && is_ptrs_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)]);
@@ -1065,15 +1061,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
 
   bwp_start_subcarrier = (rel15_ul->rb_start*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->nr_of_symbols,
-                                    rel15_ul->dmrs_config_type,
-                                    frame_parms->ofdm_symbol_size);
+  dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
 
   if (dmrs_symbol_flag == 1){
     nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8);
@@ -1121,6 +1109,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
   nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
                               gNB->pusch_vars[UE_id],
                               symbol,
+                              dmrs_symbol_flag,
                               rel15_ul,
                               frame_parms);
 
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index b28911b495..37a77b1d51 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -226,16 +226,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
   number_symbols = pusch_pdu->nr_of_symbols;
 
   for (l = start_symbol; l < start_symbol + number_symbols; l++)
-      number_dmrs_symbols += is_dmrs_symbol(l,
-                                            0,
-                                            0,
-                                            0,
-                                            0,
-                                            0,
-                                            number_symbols,
-                                            pusch_pdu->dmrs_config_type,
-                                            frame_parms->ofdm_symbol_size);
-
+      number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
 
   nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
 

From 1c2f9bb618831a33ab53e8264553d8b35a58c08f Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Fri, 20 Mar 2020 13:59:40 +0100
Subject: [PATCH 331/343] Fixed some bug in pusch dmrs an assertion fails in
 gnb (need to be fixed)

---
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c     | 18 +++++++++++-------
 openair1/SCHED_NR/phy_procedures_nr_gNB.c      |  4 ++--
 .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c  |  4 ++--
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index bdd8ea8c24..da289e86c2 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -127,6 +127,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   Nid_cell = 0;
   N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
   number_dmrs_symbols = 0;
+  uint8_t mapping_type = UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
 
   for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {
 
@@ -136,7 +137,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     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,
+      number_dmrs_symbols += is_dmrs_symbol((mapping_type)?i-start_symbol:i,
                                             0,
                                             0,
                                             0,
@@ -146,12 +147,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                             UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
                                             frame_parms->ofdm_symbol_size);
 
-    ulsch_ue->length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength;
+    ulsch_ue->length_dmrs = number_dmrs_symbols; // pusch.MaxLenght is redundant here as number_dmrs_symbols
+                                                 // contains all dmrs symbols even for double symbol dmrs
     ulsch_ue->rnti        = n_rnti;
     ulsch_ue->Nid_cell    = Nid_cell;
-    ulsch_ue->nb_re_dmrs  = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
+    ulsch_ue->nb_re_dmrs  = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4);
 
-    N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs - N_PRB_oh;
+    N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs*number_dmrs_symbols - N_PRB_oh;
 
     harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*harq_process_ul_ue->nb_rb*num_of_codewords;
 
@@ -275,7 +277,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   /////////////////////////DMRS Modulation/////////////////////////
   ///////////
   pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
-  n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs);
+  n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs);
   int16_t mod_dmrs[n_dmrs<<1];
   dmrs_type = UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type;
   ///////////
@@ -335,7 +337,7 @@ 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++) {
 
-    is_dmrs = is_dmrs_symbol(l,
+    is_dmrs = is_dmrs_symbol((mapping_type)?l-start_symbol:l,
                              0,
                              0,
                              0,
@@ -386,6 +388,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
     uint8_t k_prime=0;
     uint8_t is_dmrs, is_ptrs;
+    uint8_t l_ref;
     uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
 
     for (l=start_symbol; lnumber_of_symbols; l++) {
@@ -393,6 +396,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
       k = start_sc;
       n = 0;
       dmrs_idx = 0;
+      l_ref = (mapping_type) ? l-start_symbol : l;
 
       for (i=0; inb_rb*NR_NB_SC_PER_RB; i++) {
 
@@ -401,7 +405,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
         is_dmrs = 0;
         is_ptrs = 0;
 
-        is_dmrs = is_dmrs_symbol(l,
+        is_dmrs = is_dmrs_symbol(l_ref,
                                  k,
                                  start_sc,
                                  k_prime,
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 37a77b1d51..292c8106ae 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -228,12 +228,12 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
   for (l = start_symbol; l < start_symbol + number_symbols; l++)
       number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
 
-  nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols;
+  nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4);
 
   G = nr_get_G(pusch_pdu->rb_size,
                number_symbols,
                nb_re_dmrs,
-               1, // FIXME only single dmrs is implemented
+               number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
                pusch_pdu->qam_mod_order,
                pusch_pdu->nrOfLayers);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index f1e2e8e071..1e0fd8d9a2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -759,7 +759,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
   pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.;
   pusch_pdu->nrOfLayers = 1;
   //DMRS
-  pusch_pdu->ul_dmrs_symb_pos = 1;
+  pusch_pdu->ul_dmrs_symb_pos = 1<<2; //for now the gnb assumes dmrs in the first symbol of the scheduled pusch resource
   pusch_pdu->dmrs_config_type = 0;  //dmrs-type 1 (the one with a single DMRS symbol in the beginning)
   pusch_pdu->ul_dmrs_scrambling_id =  0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
   pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
@@ -775,7 +775,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
   //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 = 0;
+  pusch_pdu->start_symbol_index = 2;
   pusch_pdu->nr_of_symbols = 12;
   //Optional Data only included if indicated in pduBitmap
   pusch_pdu->pusch_data.rv_index = 0;

From c71edc21db03ce6b3ff3b2cf4703398d9bc823be Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Fri, 20 Mar 2020 17:08:30 +0100
Subject: [PATCH 332/343] Fixed the assertion in ulsch pdu header rfsim works

---
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index da289e86c2..586630aa66 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -209,8 +209,15 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     	}
         //else if(uplink_counter == 0){ //if(!IS_SOFTMODEM_NOS1){
     	else{
-        	LOG_D(PHY, "Random data to be tranmsitted: \n");
-        	for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) {
+          //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
+          //and block this traffic from being forwarded to the upper layers at the gNB
+          uint16_t payload_offset = 5;
+          LOG_D(PHY, "Random data to be tranmsitted: \n");
+          //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver
+          for (i = 0; ia[i] = 0;
+
+          for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) {
         		harq_process_ul_ue->a[i] = (unsigned char) rand();
         		//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
         	}

From d90f8da36424f1af586397a9f86cb35e465a4c9e Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani 
Date: Sat, 21 Mar 2020 18:43:50 +0100
Subject: [PATCH 333/343] avoiding code duplication

---
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 45 ++++++++--------------
 1 file changed, 15 insertions(+), 30 deletions(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 586630aa66..3b6367e243 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -174,6 +174,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     // to be removed later when MAC is ready
 
     if (harq_process_ul_ue != NULL){
+      data_existing = 0;
 
     	if (IS_SOFTMODEM_NOS1){
     		data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
@@ -191,38 +192,22 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     				printf("\n");
 				#endif
     		}
-    		//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
-    		else{
-    			//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
-    			//and block this traffic from being forwarded to the upper layers at the gNB
-    			uint16_t payload_offset = 5;
-    			LOG_D(PHY, "Random data to be tranmsitted: \n");
-    			//Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver
-    			for (i = 0; ia[i] = 0;
+      }
+      //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
+      else if (!IS_SOFTMODEM_NOS1 || !data_existing) {
+        //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
+        //and block this traffic from being forwarded to the upper layers at the gNB
+        uint16_t payload_offset = 5;
+        LOG_D(PHY, "Random data to be tranmsitted: \n");
+        //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver
+        for (i = 0; ia[i] = 0;
 
-    			for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) {
-    				harq_process_ul_ue->a[i] = (unsigned char) rand();
-    				//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
-    				}
-    		}
-    	}
-        //else if(uplink_counter == 0){ //if(!IS_SOFTMODEM_NOS1){
-    	else{
-          //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
-          //and block this traffic from being forwarded to the upper layers at the gNB
-          uint16_t payload_offset = 5;
-          LOG_D(PHY, "Random data to be tranmsitted: \n");
-          //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver
-          for (i = 0; ia[i] = 0;
-
-          for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) {
-        		harq_process_ul_ue->a[i] = (unsigned char) rand();
-        		//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
-        	}
-        	//uplink_counter++;
+        for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) {
+          harq_process_ul_ue->a[i] = (unsigned char) rand();
+          //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
         }
+      }
     } else {
       LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
       return;

From e21d6efaf56ecd8f775feea2e7c4cb9518ed014e Mon Sep 17 00:00:00 2001
From: Florian Kaltenberger 
Date: Mon, 23 Mar 2020 16:33:35 +0100
Subject: [PATCH 334/343] CI: adding --phy-test command line option to gNB
 real-time test

---
 ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index 30a8772df7..f3e80c576a 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -33,7 +33,7 @@
         
                 Initialize_eNB
                 Initialize gNB USRP
-		-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+		-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test
 		NR
         
 

From d6ce3a5a3147ccfa0ebd8129b70cd8d3dc4584d5 Mon Sep 17 00:00:00 2001
From: Cedric Roux 
Date: Mon, 23 Mar 2020 17:45:59 +0100
Subject: [PATCH 335/343] fix compilation of ldpc libraries - T must be
 processed before

---
 cmake_targets/CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index f29c014150..247bc9e073 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -2941,7 +2941,8 @@ if (${T_TRACER})
         NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
         PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
         L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
-        CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB)
+        CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB
+        ldpc_orig ldpc_optim ldpc_optim8seg ldpc)
     if (TARGET ${i})
       add_dependencies(${i} generate_T)
     endif()

From df0bc30e28733c2f97bac3c5c96775eeec087075 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 24 Mar 2020 15:41:51 +0100
Subject: [PATCH 336/343] Make function static inline, not inline

inline alone does only define a function without a corresponding
declaration. static solves this problem
---
 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 653a97dc61..131710ee02 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -633,7 +633,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
   return 0;
 }
 
-inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
+static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
   if (fp->numerology_index == 0)
     return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
   int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
@@ -641,7 +641,7 @@ inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
   return num_samples;
 }
 
-inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
+static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
   int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
   int next_slot_first_symbol = 0;
   if (slot < (fp->slots_per_frame-1))

From 8a589f5b0886aeebdb77e794047ca9b16b857972 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 24 Mar 2020 15:54:45 +0100
Subject: [PATCH 337/343] Fix: rx_indication length is in bytes

---
 openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 292c8106ae..d9a7ee3c69 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -297,7 +297,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_
 
  gNB->UL_INFO.rx_ind.sfn_sf                    = frame<<4| slot_rx;
  gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
- gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list->rx_indication_rel8.length = gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->TBS>>3;
+ gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list->rx_indication_rel8.length = gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->TBS;
 
  pdu                                    = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus];
 

From 2c21e8229c2548d51f7912c2299b6c94a53c863f Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 24 Mar 2020 15:55:41 +0100
Subject: [PATCH 338/343] Fix: correctly set context before calling pdcp_run()

---
 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 90c56c2ef5..e5840d9cd1 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -308,6 +308,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   //printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP);
 			       
   protocol_ctxt_t   ctxt;
+  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame_txP, slot_txP,module_idP);
   int CC_id, UE_id = 0;
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_UE_list_t *UE_list = &gNB->UE_list;
@@ -351,7 +352,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     } //END if (UE_list->active[i])
   } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
   */
-  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frame_txP, slot_txP,module_idP);
   
   // This schedules MIB
   if((slot_txP == 0) && (frame_txP & 7) == 0){

From 69c16efe07986a207881b4aa1d338517ab647a91 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 24 Mar 2020 16:20:05 +0100
Subject: [PATCH 339/343] Fix: check that UE RRC config files are found

---
 openair2/RRC/NR_UE/rrc_UE.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index 1975bfba1a..87e899845e 100755
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -329,6 +329,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
 	    sprintf(filename,"reconfig.raw");
 	  fd = fopen(filename,"r");
           char buffer[1024];
+	  AssertFatal(fd,
+	              "cannot read file %s: errno %d, %s\n",
+	              filename,
+	              errno,
+	              strerror(errno));
 	  int msg_len=fread(buffer,1,1024,fd);
 	  fclose(fd);
 	  process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
@@ -337,6 +342,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
 	  else
 	    sprintf(filename,"rbconfig.raw");
 	  fd = fopen(filename,"r");
+	  AssertFatal(fd,
+	              "cannot read file %s: errno %d, %s\n",
+	              filename,
+	              errno,
+	              strerror(errno));
 	  msg_len=fread(buffer,1,1024,fd);
 	  fclose(fd);
 	  process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); 

From daefb67c82e35a5468733306149736955b756c7c Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 24 Mar 2020 16:26:47 +0100
Subject: [PATCH 340/343] Fix: correct check for dummy-traffic

---
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 3b6367e243..f1d4a304f9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -194,7 +194,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     		}
       }
       //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
-      else if (!IS_SOFTMODEM_NOS1 || !data_existing) {
+      if (!IS_SOFTMODEM_NOS1 || !data_existing) {
         //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
         //and block this traffic from being forwarded to the upper layers at the gNB
         uint16_t payload_offset = 5;

From 8a47fa484cb30ae4c6faee4330cbdee2cfd6cd63 Mon Sep 17 00:00:00 2001
From: Robert Schmidt 
Date: Tue, 24 Mar 2020 16:32:14 +0100
Subject: [PATCH 341/343] Handle residual MAC PDU < 0 gracefully

---
 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 34be2246b8..ade5200627 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -222,7 +222,10 @@ void nr_process_mac_pdu(
         pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
         pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
 
-        AssertFatal(pdu_len >= 0, "[MAC] nr_process_mac_pdu, residual mac pdu length < 0!\n");
+        if (pdu_len < 0) {
+          LOG_E(MAC, "%s() residual mac pdu length < 0!\n", __func__);
+          return;
+        }
     }
 }
 

From 1cb14c3d9cb4e8fa288557c04b2530a925eb952f Mon Sep 17 00:00:00 2001
From: Gabriele Perrone 
Date: Wed, 1 Apr 2020 13:26:26 +0200
Subject: [PATCH 342/343] Update README.md

---
 targets/ARCH/rfsimulator/README.md | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md
index e3ce219d73..ce2a4c9616 100644
--- a/targets/ARCH/rfsimulator/README.md
+++ b/targets/ARCH/rfsimulator/README.md
@@ -3,6 +3,12 @@ This is an RF simulator that allows to test OAI without an RF board. It replaces
 
 As much as possible, it works like an RF board, but not in real-time: It can run faster than real-time if there is enough CPU, or slower (it is CPU-bound instead of real-time RF sampling-bound).
 
+It can be run either in:
+
+- "noS1" mode: the generated IP traffic is sent and received between gNB and UE IP tunnel interfaces ("oaitun") by applications like ping and iperf
+- "phy-test" mode: random UL and DL traffic is generated at every scheduling opportunity 
+
+
 # build
 
 ## From [build_oai](../../../doc/BUILD.md) script
@@ -84,16 +90,19 @@ make rfsimulator
 ### Launch gNB in one window
 
 ```bash
-sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
+sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD --rfsim --phy-test
 ```
 
 ### Launch UE in another window
 
 ```bash
-sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 
+sudo RFSIMULATOR= ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path ../../../ci-scripts/rrc-files 
 ```
+Note:
+1.  can be 127.0.0.1 if both gNB and nrUE executables run on the same host, OR the IP interface address of the remote host running the gNB executable, if the gNB and nrUE run on separate hosts
+2. the --rrc_config_path parameter can be omitted (but not necessarily) if the gNB and nrUE run on the same host, in which case the gNB provides the nrUE with the necessary rrc configuration
+3. to enable the noS1 mode --noS1 and --nokrnmod 1 options should be added to the command line
 
-Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine.
 
 In the UE, you can add `-d` option to get the softscope.
 

From 36bf56d4108ff2cca3850a8a2d5e85711a9c3784 Mon Sep 17 00:00:00 2001
From: Gabriele Perrone 
Date: Wed, 1 Apr 2020 14:59:09 +0200
Subject: [PATCH 343/343] Update README.md

---
 targets/ARCH/rfsimulator/README.md | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md
index ce2a4c9616..a4b030af85 100644
--- a/targets/ARCH/rfsimulator/README.md
+++ b/targets/ARCH/rfsimulator/README.md
@@ -106,6 +106,24 @@ Note:
 
 In the UE, you can add `-d` option to get the softscope.
 
+### Testing IP traffic (ping and iperf)
+
+```
+ping -I oaitun_enb1 10.0.1.2 (from gNB mchine)
+ping -I oaitun_ue1 10.0.1.1 (from nrUE mchine)
+``` 
+
+```iperf (Downlink):
+Server nrUE machine: iperf -s -i 1 -u -B 10.0.1.2
+Client gNB machine: iperf -c 10.0.1.2 -u -b 0.1M --bind 10.0.1.1
+```
+
+```iperf (Uplink):
+Server gNB machine: iperf -s -i 1 -u -B 10.0.1.1
+Client nrUE machine: iperf -c 10.0.1.1 -u -b 0.1M --bind 10.0.1.2
+Note: iperf tests cannot be performed only when running gNB and nrUE on separate hosts. 
+```
+
 ### Store and replay
 
 You can store emitted I/Q samples. If you set the option `saviq`, the simulator will write all the I/Q samples into this file. Then, you can replay with the executable `replay_node`.