diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index d4fe0d85552532732eaf167c290c9599a29eb0f6..54ceca9603244dc27cdc15ca65ee596c66d6641e 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -31,7 +31,6 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { } def doRedHatBuild = false -def FDD_Band7_B210_Status pipeline { agent { @@ -41,7 +40,7 @@ pipeline { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test-FDD-Band7"]) + gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"]) ansiColor('xterm') } @@ -49,6 +48,9 @@ pipeline { stage ("Verify Parameters") { steps { script { + JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"' + JOB_TIMESTAMP = JOB_TIMESTAMP.trim() + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' def allParametersPresent = true @@ -62,7 +64,7 @@ pipeline { allParametersPresent = false } if (allParametersPresent) { - echo "Performing Red Hat Build" + echo "Performing Red Hat Build" doRedHatBuild = true } else { doRedHatBuild = false @@ -115,37 +117,49 @@ pipeline { stage ("Start VM -- cppcheck") { steps { - sh "./ci-scripts/createVM.sh --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/createVM.sh --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } stage ("Start VM -- enb-usrp") { steps { - sh "./ci-scripts/createVM.sh --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/createVM.sh --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } stage ("Start VM -- basic-sim") { steps { - sh "./ci-scripts/createVM.sh --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/createVM.sh --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } stage ("Start VM -- phy-sim") { steps { - sh "./ci-scripts/createVM.sh --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/createVM.sh --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } stage ("Start VM -- enb-ethernet") { steps { - sh "./ci-scripts/createVM.sh --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/createVM.sh --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } stage ("Start VM -- ue-ethernet") { steps { - sh "./ci-scripts/createVM.sh --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/createVM.sh --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } @@ -154,42 +168,54 @@ pipeline { stage ("Analysis with cppcheck") { steps { gitlabCommitStatus(name: "Analysis with cppcheck") { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } } stage ("Build eNb-USRP") { steps { gitlabCommitStatus(name: "Build eNb-USRP") { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } } stage ("Build basic simulator") { steps { gitlabCommitStatus(name: "Build basic-sim") { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } } } } stage ("Build physical simulators") { steps { gitlabCommitStatus(name: "Build phy-sim") { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } } } } stage ("Build eNb-ethernet") { steps { gitlabCommitStatus(name: "Build eNb-ethernet") { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } } } } stage ("Build UE-ethernet") { steps { gitlabCommitStatus(name: "Build UE-ethernet") { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } } } } @@ -204,7 +230,9 @@ pipeline { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.RedHatRemoteCredentials}", usernameVariable: 'RH_Username', passwordVariable: 'RH_Password'] ]) { - sh "./ci-scripts/buildOnRH.sh --workspace $WORKSPACE --job-name ${JOB_NAME} --build-id ${BUILD_ID} --remote-host ${params.RedHatRemoteServer} --remote-path ${params.RedHatWorkingPath} --remote-user-name ${RH_Username} --remote-password ${RH_Password}" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnRH.sh --workspace $WORKSPACE --job-name ${JOB_NAME} --build-id ${BUILD_ID} --remote-host ${params.RedHatRemoteServer} --remote-path ${params.RedHatWorkingPath} --remote-user-name ${RH_Username} --remote-password ${RH_Password}" + } } } catch (Exception e) { echo "Red Hat build failed not an error now" @@ -238,6 +266,7 @@ pipeline { sh "./ci-scripts/reportBuildLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}" } if(fileExists('build_results.html')) { + sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' build_results.html" archiveArtifacts artifacts: 'build_results.html' } } @@ -250,64 +279,215 @@ pipeline { stage ("Test physical simulators") { steps { gitlabCommitStatus(name: "Test phy-sim") { - sh "./ci-scripts/runTestOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/runTestOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } } stage ("Test basic simulator") { steps { - //gitlabCommitStatus(name: "Test basic-sim") { - sh "./ci-scripts/runTestOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" - //} + gitlabCommitStatus(name: "Test basic-sim") { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/runTestOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } } } - stage ("Test FDD - Band 7 - B210") { - steps { - gitlabCommitStatus(name: "Test-FDD-Band7") { - script { - if ("MERGE".equals(env.gitlabActionType)) { - FDD_Band7_B210_Status = build job: 'eNB-CI-FDD-Band7-B210', - 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) - ] - } else { - FDD_Band7_B210_Status = build job: 'eNB-CI-FDD-Band7-B210', - 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) - ] + stage ("Test on CI bench #1") { + stages { + stage ("Test FDD - Band 7 - B210") { + steps { + script { + try { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-FDD-Band7") { + build job: 'eNB-CI-FDD-Band7-B210', + 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) + ] + } + } else { + gitlabCommitStatus(name: "Test-FDD-Band7") { + build job: 'eNB-CI-FDD-Band7-B210', + 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) + ] + } + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-FDD-Band7-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' + } + } + } } } } - } - post { - // In case of success we really pick the report from the exact slave build number - success { - script { - copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', - filter: 'test_results*.html', - selector: specific("${FDD_Band7_B210_Status.number}")) - if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' + stage ("Test TDD - Band 40 - B210") { + steps { + script { + try { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-TDD-Band40") { + build job: 'eNB-CI-TDD-Band40-B210', + 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) + ] + } + } else { + gitlabCommitStatus(name: "Test-TDD-Band40") { + build job: 'eNB-CI-TDD-Band40-B210', + 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) + ] + } + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-TDD-Band40-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-TDD-Band40-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-TDD-Band40-B210.html' + } + } + } } } } - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. Note that we could use that syntax also in case of success. - // The only drop-back is that we may retrieve the HTML report of a previous build - cleanup { - script { - if (!fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' + stage ("Test IF4p5 - FDD - Band 7 - B210") { + steps { + script { + try { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { + build job: 'eNB-CI-IF4p5-FDD-Band7-B210', + 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) + ] + } + } else { + gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { + build job: 'eNB-CI-IF4p5-FDD-Band7-B210', + 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) + ] + } + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-IF4p5-FDD-Band7-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-FDD-Band7-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-FDD-Band7-B210.html' + } + } + } + } + } + } + stage ("Test IF4p5 - TDD - Band 40 - B210") { + steps { + script { + try { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { + build job: 'eNB-CI-IF4p5-TDD-Band40-B210', + 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) + ] + } + } else { + gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { + build job: 'eNB-CI-IF4p5-TDD-Band40-B210', + 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) + ] + } + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-IF4p5-TDD-Band40-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-TDD-Band40-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-TDD-Band40-B210.html' + } + } } } } @@ -319,12 +499,19 @@ pipeline { always { script { dir ('archives') { - sh "if [ -d */test ]; then zip -r -qq vm_tests_logs.zip */test ; fi" + sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi" } if(fileExists('archives/vm_tests_logs.zip')) { archiveArtifacts artifacts: 'archives/vm_tests_logs.zip' - archiveArtifacts artifacts: 'archives/*/test/results_autotests*.xml' - archiveArtifacts artifacts: 'archives/*/test/*.xsl' + if ("MERGE".equals(env.gitlabActionType)) { + sh "./ci-scripts/reportTestLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" + } else { + sh "./ci-scripts/reportTestLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}" + } + if(fileExists('test_simulator_results.html')) { + sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_simulator_results.html" + archiveArtifacts artifacts: 'test_simulator_results.html' + } } } } @@ -341,6 +528,15 @@ pipeline { script { // Stage destroy may not be run if error in previous stage sh "./ci-scripts/destroyAllRunningVM.sh --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + emailext attachmentsPattern: '*results*.html', + body: '''Hi, +Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS! + +Regards, +OAI CI Team''', + replyTo: 'no-reply@openairinterface.org', + subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', + to: env.gitlabUserEmail } } success { diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 78f62cd8ebde1472cf747098e05ec1e19d3e3ad4..5fd2a09598972a80f75c817a6eda711a938e3df7 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -31,6 +31,9 @@ def testXMLFile = params.pythonTestXmlFile // Name of the test stage def testStageName = params.pipelineTestStageName +// Name of the phone resource +def ciSmartPhoneResource = params.smartphonesResource + // Terminate Status def termUE = 0 def termENB = 1 @@ -57,7 +60,6 @@ pipeline { } options { disableConcurrentBuilds() - timestamps() ansiColor('xterm') } // the following parameter options are commented out so it shows the ones @@ -70,6 +72,7 @@ pipeline { string(name: 'pythonTestXmlFile', defaultValue: 'enb_usrpB210_band7_50PRB.xml', description: 'Location of the Test XML to be run') string(name: 'pipelineTestStageName', defaultValue: 'Test COTS-UE - OAI eNB - LTEBOX EPC', description: 'Naming of the Test Stage') booleanParam(name: 'pipelineZipsConsoleLog', defaultValue: 'True', description: 'If true, the pipeline script retrieves the job console log, zips it and archives it as artifact') + string(name: 'smartphonesResource', defaultValue: 'CI-Bench-1-Phones', description: 'Lockeable Resource to prevent multiple jobs to run simultaneously with the same resource') //eNB parameters string(name: 'eNB_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of eNB') @@ -112,6 +115,9 @@ pipeline { testStageName = 'Template Test Stage' } + if (params.smartphonesResource == null) { + allParametersPresent = false + } if (params.eNB_IPAddress == null) { allParametersPresent = false } @@ -178,6 +184,7 @@ pipeline { steps { script { dir ('ci-scripts') { + lock (ciSmartPhoneResource) { try { echo "\u2705 \u001B[32m${testStageName}\u001B[0m" withCredentials([ @@ -190,6 +197,7 @@ pipeline { } catch (Exception e) { currentBuild.result = 'FAILURE' } + } } } } @@ -320,7 +328,7 @@ pipeline { } if(fileExists("ci-scripts/test_results.html")) { sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's#TEMPLATE_BUILD_ID#${BUILD_ID}#' test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' test_results-${JOB_NAME}.html" archiveArtifacts "test_results-${JOB_NAME}.html" } } diff --git a/ci-scripts/astyle-options.txt b/ci-scripts/astyle-options.txt index 7f28bbb1f01d0a7c3bcae4c6614d9a38ed5a5db1..81c4d68ace94aad5332b9bafba07025c181c469a 100644 --- a/ci-scripts/astyle-options.txt +++ b/ci-scripts/astyle-options.txt @@ -7,6 +7,10 @@ convert-tabs indent=spaces=2 # Indent 'switch' blocks so that the 'case X:' statements are indented in the switch block. indent-switches +# Indent preprocessor blocks at bracket level 0. +indent-preproc-block +# Indent multi-line preprocessor #define statements. +indent-preproc-define # Indent C++ comments beginning in column one. indent-col1-comments # Pad empty lines around header blocks @@ -14,7 +18,9 @@ break-blocks delete-empty-lines # Attach a pointer or reference operator (*, &, or ^) to the variable name (right) align-pointer=name -# The code line length is 200 characters/columns +# The code line length is 200 characters/columns (this is the maximum allowed by astyle) max-code-length=200 +# If the line contains logical conditionals they will be placed first on the new line. break-after-logical +# Force use of the linux end of line lineend=linux diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 76a11c6d383eecabf66c5c5c8b8994461cb1dff9..2a358c9bacf09ce8d27577efc3d1572ce98f80e9 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -86,6 +86,7 @@ JOB_NAME=XX BUILD_ID=XX VM_NAME=ci-enb-usrp VM_MEMORY=2048 +VM_CPU=4 ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt NB_PATTERN_FILES=4 @@ -126,7 +127,7 @@ case $key in ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -w USRP" + BUILD_OPTIONS="--eNB -w USRP --mu" shift ;; -v2) @@ -135,6 +136,8 @@ case $key in LOG_PATTERN=basic_simulator NB_PATTERN_FILES=2 BUILD_OPTIONS="--basic-simulator" + VM_MEMORY=8192 + VM_CPU=4 shift ;; -v3) @@ -178,7 +181,7 @@ case $key in ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -w USRP" + BUILD_OPTIONS="--eNB -w USRP --mu" ;; basic-sim) VM_NAME=ci-basic-sim @@ -186,6 +189,8 @@ case $key in LOG_PATTERN=basic_simulator NB_PATTERN_FILES=2 BUILD_OPTIONS="--basic-simulator" + VM_MEMORY=8192 + VM_CPU=4 ;; phy-sim) VM_NAME=ci-phy-sim @@ -270,7 +275,7 @@ then echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" - uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu 4 --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml fi echo "Waiting for VM to be started" @@ -289,6 +294,7 @@ echo "############################################################" echo "Running install and build script on VM ($VM_NAME)" echo "############################################################" echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS +echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] then echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index a18fc67c75cddcbbf4fbdc97e6297ddf85a84a07..61cbf1256016054c62276550bb7986b4ebcdf17c 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -120,21 +120,34 @@ echo "Source Branch is : $SOURCE_BRANCH" echo "Target Branch is : $TARGET_BRANCH" echo "Merged Commit is : $MERGE_COMMMIT" echo "Target Init is : $TARGET_INIT_COMMIT" +echo "" +echo " ----------------------------------------------------------" +echo "" # Retrieve the list of modified files since the latest develop commit MODIFIED_FILES=`git log $TARGET_INIT_COMMIT..$MERGE_COMMMIT --oneline --name-status | egrep "^M|^A" | sed -e "s@^M\t*@@" -e "s@^A\t*@@" | sort | uniq` NB_TO_FORMAT=0 +if [ -f oai_rules_result_list.txt ] +then + rm -f oai_rules_result_list.txt +fi for FULLFILE in $MODIFIED_FILES do - echo $FULLFILE filename=$(basename -- "$FULLFILE") EXT="${filename##*.}" if [ $EXT = "c" ] || [ $EXT = "h" ] || [ $EXT = "cpp" ] || [ $EXT = "hpp" ] then TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted ` NB_TO_FORMAT=$((NB_TO_FORMAT + TO_FORMAT)) + if [ $TO_FORMAT -ne 0 ] + then + echo $FULLFILE + echo $FULLFILE >> ./oai_rules_result_list.txt + fi fi done +echo "" +echo " ----------------------------------------------------------" echo "Nb Files that do NOT follow OAI rules: $NB_TO_FORMAT" echo $NB_TO_FORMAT > ./oai_rules_result.txt diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..ec968e8cefde3241f81e74abb43af82ce5d0298a --- /dev/null +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -0,0 +1,227 @@ +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; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + 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 = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower =-29; + 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 = -106; + 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; + } + ); + + + 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 = "10.0.0.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = [38]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; +}; diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..c2f69cb1b9680cc6a609174e0a818e0ca6533552 --- /dev/null +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -0,0 +1,227 @@ +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; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + 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; + 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 = 1; + 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 = -106; + 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; + } + ); + + + 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 = "10.0.0.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = [38]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; +}; diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..6bdbd4e39b7ff0d5a9d9d7853b967aaa81529e9c --- /dev/null +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -0,0 +1,227 @@ +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; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + 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 = 1; + 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 = -106; + 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; + } + ); + + + 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 = "10.0.0.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = [38]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; +}; diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 4380bd30be7686e518b5d79ad7191d6e7df76da8..1a566e957900cc5334d7996a60934314213904cb 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,12 +180,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -226,6 +225,15 @@ RUs = ( } ); +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"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index dded9cfdeb8d204a24bb294c74946d763276abd2..fd49fe9d837b6a7a2d0a8b6dd2da863f47c16b12 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,12 +180,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -226,6 +225,15 @@ RUs = ( } ); +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"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 7c4292eb61bdd92bd51ff7bad73910797477ad98..1613dd4c320170e2518aaacb698aa578589f7af0 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,12 +180,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -226,6 +225,15 @@ RUs = ( } ); +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"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf new file mode 100644 index 0000000000000000000000000000000000000000..0211e126a14708955af6173f279b3c0ac403ebb9 --- /dev/null +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -0,0 +1,265 @@ +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"; + } + ); + + 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 = 200; + puCch10xSnr = 200; + } +); + +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 = "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"; + 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/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf new file mode 100644 index 0000000000000000000000000000000000000000..a7bc31eed804858d35dd99bed1d18a272b579d18 --- /dev/null +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -0,0 +1,227 @@ +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; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + 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; + 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 = 1; + 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 = -106; + 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; + } + ); + + + 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"; + } + ); + + 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 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = [38]; + 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 = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..217991f69fce2a71ce74f48d39295ca11ddf2100 --- /dev/null +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -0,0 +1,234 @@ +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 = 92; mnc_length = 2; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + 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 = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower =-29; + 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 = -106; + 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; + } + ); + + + 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 = "10.0.0.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; +}; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..21f4f34ba90d691a6edcff936ed11945792c91d5 --- /dev/null +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -0,0 +1,234 @@ +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 = 92; mnc_length = 2; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + 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; + 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 = 1; + 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 = -106; + 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; + } + ); + + + 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 = "10.0.0.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; +}; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..2fdfa3c4e704906d3174067d2422d400341ff990 --- /dev/null +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -0,0 +1,234 @@ +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 = 92; mnc_length = 2; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 40; + downlink_frequency = 2350000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + 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 = 1; + 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 = -106; + 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; + } + ); + + + 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 = "10.0.0.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + 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"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +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 = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; +}; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..28ffc43b235bac0a2a9b085c070f2408d2ad3e9b --- /dev/null +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -0,0 +1,271 @@ +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 = 92; 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 = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + 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 = -29; + 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 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + 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 = 200; + puCch10xSnr = 200; + } +); + +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 = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; + 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/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..4d064ecc0e32a8457304671236615f2e026a26fe --- /dev/null +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -0,0 +1,271 @@ +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 = 92; 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 = 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 = -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 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + 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 = 200; + puCch10xSnr = 200; + } +); + +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 = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; + 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/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..efb1e823ad66953d19685579e32c48f3c9ac8906 --- /dev/null +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -0,0 +1,271 @@ +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 = 92; 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 = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + 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 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + 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 = 200; + puCch10xSnr = 200; + } +); + +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 = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +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"; + 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/rru.fdd.band7.conf b/ci-scripts/conf_files/rru.fdd.band7.conf new file mode 100644 index 0000000000000000000000000000000000000000..ff5e13908e182b9c983dbaca6c10291aa0cd8f84 --- /dev/null +++ b/ci-scripts/conf_files/rru.fdd.band7.conf @@ -0,0 +1,45 @@ +RUs = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.1" + local_address = "127.0.0.2"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "yes" + tr_preference = "udp_if4p5"; + nb_tx = 1; + nb_rx = 1; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + bands = [7]; + } +); + +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 ="error"; + global_log_verbosity ="medium"; + hw_log_level ="error"; + hw_log_verbosity ="medium"; + phy_log_level ="error"; + phy_log_verbosity ="medium"; + mac_log_level ="error"; + mac_log_verbosity ="high"; + rlc_log_level ="error"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="error"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="error"; + rrc_log_verbosity ="medium"; +}; + diff --git a/ci-scripts/conf_files/rru.tdd.band40.conf b/ci-scripts/conf_files/rru.tdd.band40.conf new file mode 100644 index 0000000000000000000000000000000000000000..775a2fbc67076b6999f02a84e1e1afd7365ede10 --- /dev/null +++ b/ci-scripts/conf_files/rru.tdd.band40.conf @@ -0,0 +1,45 @@ +RUs = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.1" + local_address = "127.0.0.2"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "yes" + tr_preference = "udp_if4p5"; + nb_tx = 1; + nb_rx = 1; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + bands = [40]; + } +); + +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 ="error"; + global_log_verbosity ="medium"; + hw_log_level ="error"; + hw_log_verbosity ="medium"; + phy_log_level ="error"; + phy_log_verbosity ="medium"; + mac_log_level ="error"; + mac_log_verbosity ="high"; + rlc_log_level ="error"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="error"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="error"; + rrc_log_verbosity ="medium"; +}; + diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index 1c3099e8435bc6aaee68de99fbb40063e3ad659b..f972a921ac8bd85117f16d2c77377779ed7b8a1b 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -80,6 +80,7 @@ JOB_NAME=XX BUILD_ID=XX VM_NAME=ci-enb-usrp VM_MEMORY=2048 +VM_CPU=4 while [[ $# -gt 0 ]] do @@ -107,6 +108,7 @@ case $key in ;; -v2) VM_NAME=ci-basic-sim + VM_MEMORY=8192 shift ;; -v3) @@ -116,6 +118,7 @@ case $key in -v4) VM_NAME=ci-cppcheck VM_MEMORY=4096 + VM_CPU=4 shift ;; -v7) @@ -134,6 +137,7 @@ case $key in ;; basic-sim) VM_NAME=ci-basic-sim + VM_MEMORY=8192 ;; phy-sim) VM_NAME=ci-phy-sim @@ -141,6 +145,7 @@ case $key in cppcheck) VM_NAME=ci-cppcheck VM_MEMORY=4096 + VM_CPU=4 ;; enb-ethernet) VM_NAME=ci-enb-ethernet @@ -178,11 +183,12 @@ VM_CMDS=${VM_NAME}_cmds.txt echo "VM_NAME = $VM_NAME" echo "VM_MEMORY = $VM_MEMORY MBytes" +echo "VM_CPU = $VM_CPU" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" -uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu 4 --unsafe-caching --template ci-scripts/template-host.xml +uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d172d6654538f05d124b33cb44eb75d9b4d2528a..52c742fbcb7632f47f23188ebcd1c7000ad7cd6b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -33,6 +33,23 @@ #----------------------------------------------------------- Version = '0.1' +#----------------------------------------------------------- +# Constants +#----------------------------------------------------------- +ALL_PROCESSES_OK = 0 +ENB_PROCESS_FAILED = -1 +ENB_PROCESS_OK = +1 +ENB_PROCESS_SEG_FAULT = -11 +ENB_PROCESS_ASSERTION = -12 +ENB_PROCESS_REALTIME_ISSUE = -13 +HSS_PROCESS_FAILED = -2 +HSS_PROCESS_OK = +2 +MME_PROCESS_FAILED = -3 +MME_PROCESS_OK = +3 +SPGW_PROCESS_FAILED = -4 +SPGW_PROCESS_OK = +4 +UE_IP_ADDRESS_ISSUE = -5 + #----------------------------------------------------------- # Import #----------------------------------------------------------- @@ -77,6 +94,8 @@ class SSHConnection(): self.desc = '' self.Build_eNB_args = '' self.Initialize_eNB_args = '' + self.eNBLogFile = '' + self.eNB_instance = '' self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' @@ -88,40 +107,53 @@ class SSHConnection(): self.htmlHeaderCreated = False self.htmlFooterCreated = False self.htmlUEConnected = 0 + self.htmleNBFailureMsg = '' def open(self, ipaddress, username, password): - self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress], timeout = 5) - self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - self.ssh.sendline('yes') - self.ssh.expect('password:') - self.ssh.sendline(password) - self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - pass - else: - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - sys.exit('SSH Connection Failed') - elif self.sshresponse == 1: - self.ssh.sendline(password) - self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + count = 0 + connect_status = False + while count < 4: + self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress], timeout = 5) + self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) if self.sshresponse == 0: - pass + self.ssh.sendline('yes') + self.ssh.expect('password:') + self.ssh.sendline(password) + self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if self.sshresponse == 0: + count = 10 + connect_status = True + else: + logging.debug('self.sshresponse = ' + str(self.sshresponse)) + elif self.sshresponse == 1: + self.ssh.sendline(password) + self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if self.sshresponse == 0: + count = 10 + connect_status = True + else: + logging.debug('self.sshresponse = ' + str(self.sshresponse)) + elif self.sshresponse == 2: + # Checking if we are really on the remote client defined by its IP address + self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:"', '\$', 5) + result = re.search(str(ipaddress), str(self.ssh.before)) + if result is None: + self.close() + else: + count = 10 + connect_status = True else: + # debug output + logging.debug(str(self.ssh.before)) logging.debug('self.sshresponse = ' + str(self.sshresponse)) - sys.exit('SSH Connection Failed') - elif self.sshresponse == 2: - # Checking if we are really on the remote client defined by its IP address - self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:"', '\$', 5) - result = re.search(str(ipaddress), str(self.ssh.before)) - if result is None: - sys.exit('SSH Connection Failed: TIMEOUT !!!') + # adding a tempo when failure + if not connect_status: + time.sleep(1) + count += 1 + if connect_status: pass else: - # debug output - logging.debug(str(self.ssh.before)) - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - sys.exit('SSH Connection Failed!!!') + sys.exit('SSH Connection Failed') def command(self, commandline, expectedline, timeout): logging.debug(commandline) @@ -129,7 +161,7 @@ class SSHConnection(): self.ssh.sendline(commandline) self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT]) if self.sshresponse == 0: - pass + return 0 elif self.sshresponse == 1: logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m') logging.debug('Expected Line : ' + expectedline) @@ -137,7 +169,11 @@ class SSHConnection(): elif self.sshresponse == 2: logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m') logging.debug('Expected Line : ' + expectedline) - sys.exit(self.sshresponse) + result = re.search('ping |iperf ', str(commandline)) + if result is None: + sys.exit(self.sshresponse) + else: + return -1 else: logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m') logging.debug('Expected Line : ' + expectedline) @@ -154,7 +190,7 @@ class SSHConnection(): else: logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m') - def copy(self, ipaddress, username, password, source, destination): + def copyin(self, ipaddress, username, password, source, destination): logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5) scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) @@ -182,6 +218,34 @@ class SSHConnection(): logging.debug('3 - scp_response = ' + str(scp_response)) sys.exit('SCP failed') + def copyout(self, ipaddress, username, password, source, destination): + logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination) + scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 5) + scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0: + scp_spawn.sendline('yes') + scp_spawn.expect('password:') + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0: + pass + else: + logging.debug('1 - scp_response = ' + str(scp_response)) + sys.exit('SCP failed') + elif scp_response == 1: + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0 or scp_response == 3: + pass + else: + logging.debug('2 - scp_response = ' + str(scp_response)) + sys.exit('SCP failed') + elif scp_response == 2: + pass + else: + logging.debug('3 - scp_response = ' + str(scp_response)) + sys.exit('SCP failed') + def BuildeNB(self): if self.eNBIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '': Usage() @@ -211,7 +275,7 @@ class SSHConnection(): self.command('echo ' + self.eNBPassword + ' | sudo -S mv log/* ' + 'build_log_' + SSH.testCase_id, '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S mv compile_oai_enb.log ' + 'build_log_' + SSH.testCase_id, '\$', 5) self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', 0) + self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) def InitializeHSS(self): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': @@ -232,7 +296,7 @@ class SSHConnection(): 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) self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', 0) + self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) def InitializeMME(self): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': @@ -254,7 +318,7 @@ class SSHConnection(): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_mme', '\$', 5) self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', 0) + self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) def InitializeSPGW(self): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': @@ -270,14 +334,18 @@ class SSHConnection(): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_xGw', '\$', 5) self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', 0) + self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) def InitializeeNB(self): if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '': Usage() sys.exit('Insufficient Parameter') initialize_eNB_flag = True - self.CheckProcessExist(initialize_eNB_flag) + pStatus = self.CheckProcessExist(initialize_eNB_flag) + if (pStatus < 0): + self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) + self.CreateHtmlFooter(False) + sys.exit(1) self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) # Initialize_eNB_args usually start with -O and followed by the location in repository @@ -290,18 +358,25 @@ class SSHConnection(): else: sys.exit('Insufficient Parameter') ci_full_config_file = config_path + '/ci-' + config_file + rruCheck = False + result = re.search('rru', str(config_file)) + if result is not None: + rruCheck = True # 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/mme_ip_address.*$/mme_ip_address = ( { ipv4 = "' + self.EPCIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); self.command('sed -i -e \'s/ENB_IPV4_ADDRESS_FOR_S1_MME.*$/ENB_IPV4_ADDRESS_FOR_S1_MME = "' + self.eNBIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); self.command('sed -i -e \'s/ENB_IPV4_ADDRESS_FOR_S1U.*$/ENB_IPV4_ADDRESS_FOR_S1U = "' + self.eNBIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); + self.command('sed -i -e \'s/ENB_IPV4_ADDRESS_FOR_X2C.*$/ENB_IPV4_ADDRESS_FOR_X2C = "' + self.eNBIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); # Launch eNB with the modified config file self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) - self.command('echo "./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run.sh ', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-run.sh ', '\$', 5) + self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh ', '\$', 5) + self.command('chmod 775 ./my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh ', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + SSH.testCase_id + '.log', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '.log ./my-lte-softmodem-run.sh', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(SSH.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '.log ./my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh', '\$', 5) + if not rruCheck: + self.eNBLogFile = 'enb_' + SSH.testCase_id + '.log' time.sleep(6) doLoop = True loopCounter = 10 @@ -309,35 +384,24 @@ class SSHConnection(): loopCounter = loopCounter - 1 if (loopCounter == 0): doLoop = False - # Checking if process is still alive - #self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) - #result = re.search('lte-softmodem', str(self.ssh.before)) - #if result is None: - # self.command('rsync -v enb_' + SSH.testCase_id + '.log enb_' + SSH.testCase_id + '.txt; stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --color=never -i "segmentation fault"', '\$', 5) - # result = re.search('egmentation fault', str(self.ssh.before)) - # logging.debug('\u001B[1;37;41m eNB process is already down \u001B[0m') - # if result is not None: - # logging.debug('\u001B[1;37;41m Segmentation fault \u001B[0m') - # logging.debug(str(self.ssh.before)) - # self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', 0) - # self.CreateHtmlFooter() - # self.close() - # sys.exit(1) - logging.debug('\u001B[1;30;43m eNB logging system did not show got sync! See with attach later \u001B[0m') - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'eNB not showing got sync!', 0) - # Not getting got sync is bypassed for the moment - #sys.exit(1) + logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') + self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK) + self.CreateHtmlFooter(False) + self.close() + sys.exit(1) else: - self.command('rsync -v enb_' + SSH.testCase_id + '.log enb_' + SSH.testCase_id + '.txt; stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | grep --color=never -i sync', '\$', 4) - result = re.search('got sync', str(self.ssh.before)) + self.command('stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --color=never -i "wait|sync"', '\$', 4) + if rruCheck: + result = re.search('wait RUs', str(self.ssh.before)) + else: + result = re.search('got sync', str(self.ssh.before)) if result is None: time.sleep(6) else: doLoop = False - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', 0) + self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') - self.command('rm -f enb_' + SSH.testCase_id + '.txt', '\$', 5) self.close() def InitializeUE_common(self, device_id): @@ -368,7 +432,7 @@ class SSHConnection(): multi_jobs.append(p) for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def AttachUE_common(self, device_id, statusQueue, lock): try: @@ -399,7 +463,7 @@ class SSHConnection(): break count = count - 1 if count == 15 or count == 30: - logging.debug('\u001B[1;37;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') + logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) time.sleep(0.5) self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) @@ -422,7 +486,12 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') initialize_eNB_flag = False - self.CheckProcessExist(initialize_eNB_flag) + pStatus = self.CheckProcessExist(initialize_eNB_flag) + if (pStatus < 0): + self.CreateHtmlTestRow('N/A', 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) + sys.exit(1) multi_jobs = [] status_queue = SimpleQueue() lock = Lock() @@ -435,7 +504,9 @@ class SSHConnection(): job.join() if (status_queue.empty()): - self.CreateHtmlTestRow('N/A', 'KO', len(self.UEDevices)) + self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK) + self.CreateHtmlFooter(False) + self.AutoTerminateUEandeNB() sys.exit(1) else: attach_status = True @@ -455,7 +526,8 @@ class SSHConnection(): self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) else: self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) - self.CreateHtmlFooter() + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) sys.exit(1) def DetachUE_common(self, device_id): @@ -472,7 +544,12 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') initialize_eNB_flag = False - self.CheckProcessExist(initialize_eNB_flag) + pStatus = self.CheckProcessExist(initialize_eNB_flag) + if (pStatus < 0): + self.CreateHtmlTestRow('N/A', 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) + sys.exit(1) multi_jobs = [] for device_id in self.UEDevices: p = Process(target = SSH.DetachUE_common, args = (device_id,)) @@ -481,7 +558,7 @@ class SSHConnection(): multi_jobs.append(p) for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def RebootUE_common(self, device_id): try: @@ -527,7 +604,11 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') initialize_eNB_flag = False - self.CheckProcessExist(initialize_eNB_flag) + pStatus = self.CheckProcessExist(initialize_eNB_flag) + if (pStatus < 0): + self.CreateHtmlTestRow('N/A', 'KO', pStatus) + self.CreateHtmlFooter(False) + sys.exit(1) multi_jobs = [] for device_id in self.UEDevices: p = Process(target = SSH.RebootUE_common, args = (device_id,)) @@ -536,7 +617,7 @@ class SSHConnection(): multi_jobs.append(p) for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def GetAllUEDevices(self, terminate_ue_flag): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': @@ -555,59 +636,72 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') + ue_ip_status = 0 self.UEIPAddresses = [] self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) for device_id in self.UEDevices: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ip addr show | grep rmnet', '\$', 15) - result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - sys.exit(1) + count = 0 + while count < 4: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell ip addr show | grep rmnet', '\$', 15) + result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', str(self.ssh.before)) + if result is None: + logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') + time.sleep(1) + count += 1 + else: + count = 10 + if count < 9: + ue_ip_status -= 1 + continue UE_IPAddress = result.group('ueipaddress') logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') for ueipaddress in self.UEIPAddresses: if ueipaddress == UE_IPAddress: logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + 'has been existed!' + '\u001B[0m') - sys.exit(1) + ue_ip_status -= 1 + continue self.UEIPAddresses.append(UE_IPAddress) self.close() + return ue_ip_status + + def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message): + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(message) + lock.release() - def Ping_common(self, lock, UE_IPAddress, device_id,statusQueue): + 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) ping_time = re.findall("-c (\d+)",str(self.ping_args)) - self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee -a ping_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee -a ping_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) if result is None: message = 'Packet Loss Not Found!' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(message) - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return packetloss = result.group('packetloss') if float(packetloss) == 100: message = 'Packet Loss is 100%' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(message) - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) if result is None: message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(message) - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return rtt_min = result.group('rtt_min') rtt_avg = result.group('rtt_avg') @@ -631,7 +725,7 @@ class SSHConnection(): packetLossOK = False elif float(packetloss) > 0: qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;37;43m Packet Loss is not 0% \u001B[0m') + logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') if (packetLossOK): statusQueue.put(0) else: @@ -649,8 +743,16 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') initialize_eNB_flag = False - self.CheckProcessExist(initialize_eNB_flag) - self.GetAllUEIPAddresses() + pStatus = self.CheckProcessExist(initialize_eNB_flag) + if (pStatus < 0): + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.CreateHtmlFooter(False) + sys.exit(1) + ueIpStatus = self.GetAllUEIPAddresses() + if (ueIpStatus < 0): + self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) + self.CreateHtmlFooter(False) + sys.exit(1) multi_jobs = [] i = 0 lock = Lock() @@ -666,8 +768,9 @@ class SSHConnection(): job.join() if (status_queue.empty()): - self.CreateHtmlTestRow(self.ping_args, 'KO', len(self.UEDevices)) - self.CreateHtmlFooter() + self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK) + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) sys.exit(1) else: ping_status = True @@ -685,7 +788,8 @@ class SSHConnection(): self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) else: self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - self.CreateHtmlFooter() + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) sys.exit(1) def Iperf_ComputeTime(self): @@ -720,7 +824,37 @@ class SSHConnection(): sys.exit(1) return result + def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): + self.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', str(self.ssh.before)) + if result is not None: + avgbitrate = result.group('average') + maxbitrate = result.group('maximum') + minbitrate = result.group('minimum') + lock.acquire() + logging.debug('\u001B[1;37;44m TCP iperf result (' + UE_IPAddress + ') \u001B[0m') + msg = 'TCP Stats :\n' + if avgbitrate is not None: + logging.debug('\u001B[1;34m Avg Bitrate : ' + avgbitrate + '\u001B[0m') + msg += 'Avg Bitrate : ' + avgbitrate + '\n' + if maxbitrate is not None: + logging.debug('\u001B[1;34m Max Bitrate : ' + maxbitrate + '\u001B[0m') + msg += 'Max Bitrate : ' + maxbitrate + '\n' + if minbitrate is not None: + logging.debug('\u001B[1;34m Min Bitrate : ' + minbitrate + '\u001B[0m') + msg += 'Min Bitrate : ' + minbitrate + '\n' + statusQueue.put(0) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(msg) + lock.release() + return 0 + def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): + result = re.search('-u', str(iperf_real_options)) + if result is None: + return self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options) + result = re.search('Server Report:', str(self.ssh.before)) if result is None: result = re.search('read failed: Connection refused', str(self.ssh.before)) @@ -798,23 +932,13 @@ class SSHConnection(): def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): if (not os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put('Could not analyze from server log') - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') return # Computing the requested bandwidth in float result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) if result is None: logging.debug('Iperf bandwidth Not Found!') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put('Could not compute Iperf bandwidth!') - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!') return else: req_bandwidth = result.group('iperf_bandwidth') @@ -900,12 +1024,7 @@ class SSHConnection(): logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') lock.release() else: - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put('Could not analyze from server log') - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') server_file.close() @@ -946,9 +1065,14 @@ class SSHConnection(): statusQueue.put(-1) statusQueue.put(device_id) statusQueue.put(UE_IPAddress) + statusQueue.put(msg) lock.release() def Iperf_UL_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): + udpIperf = True + result = re.search('-u', str(self.iperf_args)) + if result is None: + udpIperf = False ipnumbers = UE_IPAddress.split('.') if (len(ipnumbers) == 4): ipnumbers[3] = '1' @@ -959,7 +1083,10 @@ class SSHConnection(): self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) self.command('rm -f iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) port = 5001 + idx - self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + if udpIperf: + self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + else: + self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) time.sleep(0.5) self.close() @@ -969,23 +1096,35 @@ class SSHConnection(): iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) + if udpIperf: + modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) + else: + modified_options = str(self.iperf_args) modified_options = modified_options.replace('-R','') time.sleep(0.5) self.command('rm -f iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) - 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 -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + 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 -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + # TIMEOUT Case + if iperf_status < 0: + self.close() + message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) + self.close() - # Launch iperf server on EPC side + # Kill iperf server on EPC side self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5) self.close() + # in case of failure, retrieve server log if (clientStatus == -1): time.sleep(1) if (os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): os.remove('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log') - self.copy(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): @@ -994,6 +1133,7 @@ class SSHConnection(): if SSH.iperf_profile == 'single-ue' and idx != 0: return useIperf3 = False + udpIperf = True 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 self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) @@ -1005,15 +1145,9 @@ class SSHConnection(): result = re.search('iperf', str(self.ssh.before)) if result is None: message = 'Neither iperf nor iperf3 installed on UE!' - lock.acquire() logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(message) - lock.release() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return - #sys.exit(1) else: useIperf3 = True # in case of iperf, UL has its own function @@ -1028,7 +1162,12 @@ class SSHConnection(): self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) else: self.command('rm -f iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + result = re.search('-u', str(self.iperf_args)) + if result is None: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + udpIperf = False + else: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) time.sleep(0.5) self.close() @@ -1037,7 +1176,10 @@ class SSHConnection(): iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) + if udpIperf: + modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) + else: + modified_options = str(self.iperf_args) time.sleep(0.5) self.command('rm -f iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) @@ -1047,8 +1189,13 @@ class SSHConnection(): clientStatus = 0 self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) else: - self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - + iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if iperf_status < 0: + self.close() + message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) self.close() @@ -1063,7 +1210,7 @@ class SSHConnection(): time.sleep(1) if (os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): os.remove('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log') - self.copy(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') + self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) except: os.kill(os.getppid(),signal.SIGUSR1) @@ -1073,8 +1220,18 @@ class SSHConnection(): Usage() sys.exit('Insufficient Parameter') initialize_eNB_flag = False - self.CheckProcessExist(initialize_eNB_flag) - self.GetAllUEIPAddresses() + pStatus = self.CheckProcessExist(initialize_eNB_flag) + if (pStatus < 0): + self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) + sys.exit(1) + ueIpStatus = self.GetAllUEIPAddresses() + if (ueIpStatus < 0): + self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE) + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) + sys.exit(1) multi_jobs = [] i = 0 ue_num = len(self.UEIPAddresses) @@ -1091,8 +1248,9 @@ class SSHConnection(): job.join() if (status_queue.empty()): - self.CreateHtmlTestRow(self.iperf_args, 'KO', len(self.UEDevices)) - self.CreateHtmlFooter() + self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK) + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) sys.exit(1) else: iperf_status = True @@ -1115,44 +1273,65 @@ class SSHConnection(): self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) else: self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.CreateHtmlFooter() + self.AutoTerminateUEandeNB() + self.CreateHtmlFooter(False) sys.exit(1) def CheckProcessExist(self, initialize_eNB_flag): multi_jobs = [] - p = Process(target = SSH.CheckHSSProcess, args = ()) + status_queue = SimpleQueue() + p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) - p = Process(target = SSH.CheckMMEProcess, args = ()) + p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) - p = Process(target = SSH.CheckSPGWProcess, args = ()) + p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) if initialize_eNB_flag == False: - p = Process(target = SSH.CheckeNBProcess, args = ()) + p = Process(target = SSH.CheckeNBProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) for job in multi_jobs: job.join() - def CheckeNBProcess(self): + if (status_queue.empty()): + return -15 + else: + result = 0 + while (not status_queue.empty()): + status = status_queue.get() + if (status < 0): + result = status + if result == ENB_PROCESS_FAILED: + fileCheck = re.search('enb_', str(self.eNBLogFile)) + if fileCheck is not None: + self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + logStatus = self.AnalyzeLogFile_eNB() + if logStatus < 0: + result = logStatus + return result + + def CheckeNBProcess(self, status_queue): try: self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) result = re.search('lte-softmodem', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') - sys.exit(1) + status_queue.put(ENB_PROCESS_FAILED) + else: + status_queue.put(ENB_PROCESS_OK) self.close() except: os.kill(os.getppid(),signal.SIGUSR1) - def CheckHSSProcess(self): + def CheckHSSProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never hss', '\$', 5) @@ -1162,12 +1341,14 @@ class SSHConnection(): result = re.search('hss_sim s6as diam_hss', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m HSS Process Not Found! \u001B[0m') - sys.exit(1) + status_queue.put(HSS_PROCESS_FAILED) + else: + status_queue.put(HSS_PROCESS_OK) self.close() except: os.kill(os.getppid(),signal.SIGUSR1) - def CheckMMEProcess(self): + def CheckMMEProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never mme', '\$', 5) @@ -1177,12 +1358,14 @@ class SSHConnection(): result = re.search('mme', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m') - sys.exit(1) + status_queue.put(MME_PROCESS_FAILED) + else: + status_queue.put(MME_PROCESS_OK) self.close() except: os.kill(os.getppid(),signal.SIGUSR1) - def CheckSPGWProcess(self): + def CheckSPGWProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) if re.match('OAI', self.EPCType, re.IGNORECASE): @@ -1193,16 +1376,141 @@ class SSHConnection(): result = re.search('xGw', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m') - sys.exit(1) + status_queue.put(SPGW_PROCESS_FAILED) + else: + status_queue.put(SPGW_PROCESS_OK) self.close() except: os.kill(os.getppid(),signal.SIGUSR1) + def AnalyzeLogFile_eNB(self): + if (not os.path.isfile('./' + SSH.eNBLogFile)): + return -1 + enb_log_file = open('./' + SSH.eNBLogFile, 'r') + foundAssertion = False + msgAssertion = '' + msgLine = 0 + foundSegFault = False + foundRealTimeIssue = False + rrcSetupRequest = 0 + rrcSetupComplete = 0 + rrcReleaseRequest = 0 + rrcReconfigRequest = 0 + rrcReconfigComplete = 0 + rrcReestablishRequest = 0 + rrcReestablishComplete = 0 + rrcReestablishReject = 0 + uciStatMsgCount = 0 + pdcpFailure = 0 + ulschFailure = 0 + for line in enb_log_file.readlines(): + result = re.search('[Ss]egmentation [Ff]ault', str(line)) + if result is not None: + foundSegFault = True + result = re.search('[Cc]ore [dD]ump', str(line)) + if result is not None: + foundSegFault = True + result = re.search('[Aa]ssertion', str(line)) + if result is not None: + foundAssertion = True + result = re.search('LLL', str(line)) + if result is not None: + foundRealTimeIssue = True + if foundAssertion and (msgLine < 3): + msgLine += 1 + msgAssertion += str(line) + result = re.search('Generating RRCConnectionSetup', str(line)) + if result is not None: + rrcSetupRequest += 1 + result = re.search('RRCConnectionSetupComplete from UE', str(line)) + if result is not None: + rrcSetupComplete += 1 + result = re.search('Generate RRCConnectionRelease', str(line)) + if result is not None: + rrcReleaseRequest += 1 + result = re.search('Generate RRCConnectionReconfiguration', str(line)) + if result is not None: + rrcReconfigRequest += 1 + result = re.search('RRCConnectionReconfigurationComplete from UE rnti', str(line)) + if result is not None: + rrcReconfigComplete += 1 + result = re.search('RRCConnectionReestablishmentRequest', str(line)) + if result is not None: + rrcReestablishRequest += 1 + result = re.search('RRCConnectionReestablishmentComplete', str(line)) + if result is not None: + rrcReestablishComplete += 1 + result = re.search('RRCConnectionReestablishmentReject', str(line)) + if result is not None: + rrcReestablishReject += 1 + result = re.search('uci->stat', str(line)) + if result is not None: + uciStatMsgCount += 1 + result = re.search('PDCP.*Out of Resources.*reason', str(line)) + if result is not None: + pdcpFailure += 1 + result = re.search('ULSCH in error in round', str(line)) + if result is not None: + ulschFailure += 1 + enb_log_file.close() + self.htmleNBFailureMsg = '' + if uciStatMsgCount > 0: + statMsg = 'eNB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmleNBFailureMsg += statMsg + '\n' + if pdcpFailure > 0: + statMsg = 'eNB showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmleNBFailureMsg += statMsg + '\n' + if ulschFailure > 0: + statMsg = 'eNB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmleNBFailureMsg += statMsg + '\n' + if rrcSetupRequest > 0 or rrcSetupComplete > 0: + rrcMsg = 'eNB requested ' + str(rrcSetupRequest) + ' RRC Connection Setup(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + rrcMsg = ' -- ' + str(rrcSetupComplete) + ' were completed' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + if rrcReleaseRequest > 0: + rrcMsg = 'eNB requested ' + str(rrcReleaseRequest) + ' RRC Connection Release(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + if rrcReconfigRequest > 0 or rrcReconfigComplete > 0: + rrcMsg = 'eNB requested ' + str(rrcReconfigRequest) + ' RRC Connection Reconfiguration(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + rrcMsg = ' -- ' + str(rrcReconfigComplete) + ' were completed' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + if rrcReestablishRequest > 0 or rrcReestablishComplete > 0 or rrcReestablishReject > 0: + rrcMsg = 'eNB requested ' + str(rrcReestablishRequest) + ' RRC Connection Reestablishment(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + rrcMsg = ' -- ' + str(rrcReestablishComplete) + ' were completed' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + if foundSegFault: + logging.debug('\u001B[1;37;41m eNB ended with a Segmentation Fault! \u001B[0m') + return ENB_PROCESS_SEG_FAULT + if foundAssertion: + logging.debug('\u001B[1;37;41m eNB ended with an assertion! \u001B[0m') + self.htmleNBFailureMsg += msgAssertion + return ENB_PROCESS_ASSERTION + if foundRealTimeIssue: + logging.debug('\u001B[1;37;41m eNB faced real time issues! \u001B[0m') + return ENB_PROCESS_REALTIME_ISSUE + return 0 + def TerminateeNB(self): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb_daemon --stop', '\$', 5) - self.command('rm -f my-lte-softmodem-run.sh', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(SSH.eNB_instance) + '_daemon --stop', '\$', 5) + self.command('rm -f my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) time.sleep(5) self.command('stdbuf -o0 ps -aux | grep -v grep | grep lte-softmodem', '\$', 5) @@ -1210,7 +1518,19 @@ class SSHConnection(): if result is not None: self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) self.close() - self.CreateHtmlTestRow('N/A', 'OK', 0) + result = re.search('enb_', str(self.eNBLogFile)) + if result is not None: + self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + logStatus = self.AnalyzeLogFile_eNB() + if (logStatus < 0): + self.CreateHtmlTestRow('N/A', 'KO', logStatus) + self.CreateHtmlFooter(False) + sys.exit(1) + else: + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.eNBLogFile = '' + else: + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateHSS(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) @@ -1232,7 +1552,7 @@ class SSHConnection(): self.command('echo ' + self.EPCPassword + ' | sudo -S ./kill_hss.sh', '\$', 5) self.command('rm ./kill_hss.sh', '\$', 5) self.close() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateMME(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) @@ -1247,7 +1567,7 @@ class SSHConnection(): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_mme', '\$', 5) self.close() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateSPGW(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) @@ -1262,7 +1582,7 @@ class SSHConnection(): self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_xGw', '\$', 5) self.close() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateUE_common(self, device_id): try: @@ -1290,7 +1610,18 @@ class SSHConnection(): multi_jobs.append(p) for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', 0) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + + def AutoTerminateUEandeNB(self): + self.testCase_id = 'AUTO-KILL-UE' + self.desc = 'Automatic Termination of UE' + self.ShowTestID() + self.TerminateUE() + self.testCase_id = 'AUTO-KILL-eNB' + self.desc = 'Automatic Termination of eNB' + self.ShowTestID() + self.eNB_instance = '0' + self.TerminateeNB() def LogCollectBuild(self): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) @@ -1305,9 +1636,9 @@ class SSHConnection(): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) self.command('cd cmake_targets', '\$', 5) - self.command('rm -f enb.log.zip', '\$', 5) - self.command('zip enb.log.zip enb*.log', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core*', '\$', 60) + self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core*', '\$', 5) self.close() def LogCollectPing(self): @@ -1376,14 +1707,13 @@ class SSHConnection(): self.htmlFile.write('<html class="no-js" lang="en-US">\n') self.htmlFile.write('<head>\n') self.htmlFile.write(' <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n') - self.htmlFile.write(' <base href = "http://www.openairinterface.org/" />\n') self.htmlFile.write('</head>\n') self.htmlFile.write('<body>\n') self.htmlFile.write(' <table style="border-collapse: collapse; border: none;">\n') self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n') self.htmlFile.write(' <td style="border-collapse: collapse; border: none;">\n') self.htmlFile.write(' <a href="http://www.openairinterface.org/">\n') - self.htmlFile.write(' <img src="/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n') + self.htmlFile.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n') self.htmlFile.write(' </img>\n') self.htmlFile.write(' </a>\n') self.htmlFile.write(' </td>\n') @@ -1395,8 +1725,12 @@ class SSHConnection(): self.htmlFile.write(' <br>\n') self.htmlFile.write(' <table border = "1">\n') self.htmlFile.write(' <tr>\n') + self.htmlFile.write(' <td bgcolor = "lightcyan" >Build Start Time (UTC)</td>\n') + self.htmlFile.write(' <td>TEMPLATE_BUILD_TIME</td>\n') + self.htmlFile.write(' </tr>\n') + self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <td bgcolor = "lightcyan" >GIT Repository</td>\n') - self.htmlFile.write(' <td>' + SSH.eNBRepository + '</td>\n') + self.htmlFile.write(' <td><a href="' + SSH.eNBRepository + '">' + SSH.eNBRepository + '</a></td>\n') self.htmlFile.write(' </tr>\n') self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <td bgcolor = "lightcyan" >Job Trigger</td>\n') @@ -1429,9 +1763,13 @@ class SSHConnection(): terminate_ue_flag = True SSH.GetAllUEDevices(terminate_ue_flag) self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write('<h2>' + str(self.htmlUEConnected) + ' UE(s) is(are) connected to ADB bench server</h2>\n') + self.htmlFile.write(' <h2><a href="#FinalStatus">Jump to Final Status</a></h2>\n') self.htmlFile.write(' <br>\n') + + self.htmlFile.write(' <h2>' + str(self.htmlUEConnected) + ' UE(s) is(are) connected to ADB bench server</h2>\n') + self.htmlFile.write(' <br>\n') + self.htmlFile.write(' <h2>Test Summary for ' + SSH.testXMLfile + '</h2>\n') self.htmlFile.write(' <table border = "1">\n') self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n') @@ -1446,15 +1784,22 @@ class SSHConnection(): self.htmlFile.write(' </tr>\n') self.htmlHeaderCreated = True - def CreateHtmlFooter(self): + def CreateHtmlFooter(self, passStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): + self.htmlFile.write(' <tr id="FinalStatus">\n') + self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan=2>Final Status</th>\n') + if passStatus: + self.htmlFile.write(' <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS</font></th>\n') + else: + self.htmlFile.write(' <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL</font></th>\n') + self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </table>\n') self.htmlFile.write('</body>\n') self.htmlFile.write('</html>\n') self.htmlFile.close() self.htmlFooterCreated = False - def CreateHtmlTestRow(self, options, status, ue_status): + def CreateHtmlTestRow(self, options, status, processesStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <td bgcolor = "lightcyan" >' + SSH.testCase_id + '</td>\n') @@ -1463,16 +1808,44 @@ class SSHConnection(): if (str(status) == 'OK'): self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') elif (str(status) == 'KO'): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') + if (processesStatus == 0): + self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') + elif (processesStatus == ENB_PROCESS_FAILED): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n') + elif (processesStatus == ENB_PROCESS_SEG_FAULT): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process ended in Segmentation Fault</td>\n') + elif (processesStatus == ENB_PROCESS_ASSERTION): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process ended in Assertion</td>\n') + elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process faced Real Time issue(s)/td>\n') + elif (processesStatus == HSS_PROCESS_FAILED): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n') + elif (processesStatus == MME_PROCESS_FAILED): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - MME process not found</td>\n') + elif (processesStatus == SPGW_PROCESS_FAILED): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n') + elif (processesStatus == UE_IP_ADDRESS_ISSUE): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n') + else: + self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') else: self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - i = 0 - while (i < self.htmlUEConnected): - if (i < ue_status): - self.htmlFile.write(' <td>-</td>\n') + if (len(str(self.htmleNBFailureMsg)) > 2): + cellBgColor = 'white' + result = re.search('ended with|faced real time issues', self.htmleNBFailureMsg) + if result is not None: + cellBgColor = 'red' else: + result = re.search('showed|Reestablishment', self.htmleNBFailureMsg) + if result is not None: + cellBgColor = 'orange' + self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre>' + self.htmleNBFailureMsg + '</pre></td>\n') + self.htmleNBFailureMsg = '' + else: + i = 0 + while (i < self.htmlUEConnected): self.htmlFile.write(' <td>-</td>\n') - i += 1 + i += 1 self.htmlFile.write(' </tr>\n') def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): @@ -1504,6 +1877,15 @@ class SSHConnection(): i += 1 self.htmlFile.write(' </tr>\n') +#----------------------------------------------------------- +# ShowTestID() +#----------------------------------------------------------- + def ShowTestID(self): + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') + logging.debug('\u001B[1m' + self.desc + '\u001B[0m') + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + #----------------------------------------------------------- # Usage() #----------------------------------------------------------- @@ -1535,15 +1917,6 @@ def Usage(): print(' --XMLTestFile=[XML Test File to be run]') print('------------------------------------------------------------') -#----------------------------------------------------------- -# ShowTestID() -#----------------------------------------------------------- -def ShowTestID(): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1mTest ID:' + SSH.testCase_id + '\u001B[0m') - logging.debug('\u001B[1m' + SSH.desc + '\u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - def CheckClassValidity(action,id): if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW': logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) @@ -1556,6 +1929,14 @@ def GetParametersFromXML(action): if action == 'Initialize_eNB': SSH.Initialize_eNB_args = test.findtext('Initialize_eNB_args') + SSH.eNB_instance = test.findtext('eNB_instance') + if (SSH.eNB_instance is None): + SSH.eNB_instance = '0' + + if action == 'Terminate_eNB': + SSH.eNB_instance = test.findtext('eNB_instance') + if (SSH.eNB_instance is None): + SSH.eNB_instance = '0' if action == 'Ping': SSH.ping_args = test.findtext('ping_args') @@ -1730,6 +2111,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): Usage() sys.exit('Insufficient Parameter') + SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp") SSH.CreateHtmlHeader() #read test_case_list.xml file @@ -1791,7 +2173,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): action = test.findtext('class') if (CheckClassValidity(action, id) == False): continue - ShowTestID() + SSH.ShowTestID() GetParametersFromXML(action) if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE': terminate_ue_flag = False @@ -1831,7 +2213,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): else: sys.exit('Invalid action') - SSH.CreateHtmlFooter() + SSH.CreateHtmlFooter(True) else: Usage() sys.exit('Invalid mode') diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 609af5f166b05e2343bc7d7fcb8f5e7d977586a2..a499fa3b66149e17d14947a6d523c14ff8a2a8a1 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -260,7 +260,7 @@ function sca_summary_table_footer { echo " </tr>" >> ./build_results.html echo " </table>" >> ./build_results.html echo " <p>Full details in zipped artifact (cppcheck/cppcheck.xml) </p>" >> ./build_results.html - echo " <p>Graphical Interface tool : <code>cppcheck-gui -l cppcheck/cppcheck.xml</code> </p>" >> ./build_results.html + echo " <p style=\"margin-left: 30px\">Graphical Interface tool : <strong><code>cppcheck-gui -l cppcheck/cppcheck.xml</code></strong></p>" >> ./build_results.html } jb_checker=0 @@ -438,6 +438,10 @@ echo " </table>" >> ./build_results.html echo " <br>" >> ./build_results.html echo " <table border = \"1\">" >> ./build_results.html echo " <tr>" >> ./build_results.html +echo " <td bgcolor = \"lightcyan\" >Build Start Time (UTC)</td>" >> ./build_results.html +echo " <td>TEMPLATE_BUILD_TIME</td>" >> ./build_results.html +echo " </tr>" >> ./build_results.html +echo " <tr>" >> ./build_results.html echo " <td bgcolor = \"lightcyan\" >GIT Repository</td>" >> ./build_results.html echo " <td>$GIT_URL</td>" >> ./build_results.html echo " </tr>" >> ./build_results.html @@ -490,12 +494,20 @@ then then if [ $PU_TRIG -eq 1 ]; then echo " <td bgcolor = \"green\">All files in repository follow OAI rules. </td>" >> ./build_results.html; fi if [ $MR_TRIG -eq 1 ]; then echo " <td bgcolor = \"green\">All modified files in Merge-Request follow OAI rules.</td>" >> ./build_results.html; fi + echo " </tr>" >> ./build_results.html + echo " </table>" >> ./build_results.html else if [ $PU_TRIG -eq 1 ]; then echo " <td bgcolor = \"orange\">$NB_FILES files in repository DO NOT follow OAI rules. </td>" >> ./build_results.html; fi if [ $MR_TRIG -eq 1 ]; then echo " <td bgcolor = \"orange\">$NB_FILES modified files in Merge-Request DO NOT follow OAI rules.</td>" >> ./build_results.html; fi + echo " </tr>" >> ./build_results.html + if [ -f ./oai_rules_result_list.txt ] + then + awk '{print " <tr><td></td><td>"$1"</td></tr>"}' ./oai_rules_result_list.txt >> ./build_results.html + fi + echo " </table>" >> ./build_results.html + echo " <p>Please apply the following command to this(ese) file(s): </p>" >> ./build_results.html + echo " <p style=\"margin-left: 30px\"><strong><code>astyle --options=ci-scripts/astyle-options.txt filename(s)</code></strong></p>" >> ./build_results.html fi - echo " </tr>" >> ./build_results.html - echo " </table>" >> ./build_results.html fi echo " <h2>Ubuntu 16.04 LTS -- Summary</h2>" >> ./build_results.html diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh new file mode 100755 index 0000000000000000000000000000000000000000..e00956199c8f1ddd6b283e7e42b48f1a4fc1a306 --- /dev/null +++ b/ci-scripts/reportTestLocally.sh @@ -0,0 +1,590 @@ +#!/bin/bash +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ + +function usage { + echo "OAI Test Report script" + echo " Original Author: Raphael Defosseux" + echo "" + echo "Usage:" + echo "------" + echo "" + echo " reportTestLocally.sh [OPTIONS]" + echo "" + echo "Options:" + echo "--------" + echo "" + echo " --help OR -h" + echo " Print this help message." + echo "" + echo "Job Options:" + echo "------------" + echo "" + echo " --git-url #### OR -gu ####" + echo " Specify the URL of the GIT Repository." + echo "" + echo " --job-name #### OR -jn ####" + echo " Specify the name of the Jenkins job." + echo "" + echo " --build-id #### OR -id ####" + echo " Specify the build ID of the Jenkins job." + echo "" + echo " --trigger merge-request OR -mr" + echo " --trigger push OR -pu" + echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event." + echo "" + echo "Merge-Request Options:" + echo "----------------------" + echo "" + echo " --src-branch #### OR -sb ####" + echo " Specify the source branch of the merge request." + echo "" + echo " --src-commit #### OR -sc ####" + echo " Specify the source commit ID (SHA-1) of the merge request." + echo "" + echo " --target-branch #### OR -tb ####" + echo " Specify the target branch of the merge request (usually develop)." + echo "" + echo " --target-commit #### OR -tc ####" + echo " Specify the target commit ID (SHA-1) of the merge request." + echo "" + echo "Push Options:" + echo "----------------------" + echo "" + echo " --branch #### OR -br ####" + echo " Specify the branch of the push event." + echo "" + echo " --commit #### OR -co ####" + echo " Specify the commit ID (SHA-1) of the push event." + echo "" + echo "" +} + +function trigger_usage { + echo "OAI Test Report script" + echo " Original Author: Raphael Defosseux" + echo "" + echo " --trigger merge-request OR -mr" + echo " --trigger push OR -pu" + echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event." + echo "" +} + +jb_checker=0 +mr_checker=0 +pu_checker=0 +MR_TRIG=0 +PU_TRIG=0 +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -h|--help) + shift + usage + exit 0 + ;; + -gu|--git-url) + GIT_URL="$2" + let "jb_checker|=0x1" + shift + shift + ;; + -jn|--job-name) + JOB_NAME="$2" + let "jb_checker|=0x2" + shift + shift + ;; + -id|--build-id) + BUILD_ID="$2" + let "jb_checker|=0x4" + shift + shift + ;; + --trigger) + TRIG="$2" + case $TRIG in + merge-request) + MR_TRIG=1 + ;; + push) + PU_TRIG=1 + ;; + *) + echo "" + echo "Syntax Error: Invalid Trigger option -> $TRIG" + echo "" + trigger_usage + exit + ;; + esac + let "jb_checker|=0x8" + shift + shift + ;; + -mr) + MR_TRIG=1 + let "jb_checker|=0x8" + shift + ;; + -pu) + PU_TRIG=1 + let "jb_checker|=0x8" + shift + ;; + -sb|--src-branch) + SOURCE_BRANCH="$2" + let "mr_checker|=0x1" + shift + shift + ;; + -sc|--src-commit) + SOURCE_COMMIT_ID="$2" + let "mr_checker|=0x2" + shift + shift + ;; + -tb|--target-branch) + TARGET_BRANCH="$2" + let "mr_checker|=0x4" + shift + shift + ;; + -tc|--target-commit) + TARGET_COMMIT_ID="$2" + let "mr_checker|=0x8" + shift + shift + ;; + -br|--branch) + SOURCE_BRANCH="$2" + let "pu_checker|=0x1" + shift + shift + ;; + -co|--commit) + SOURCE_COMMIT_ID="$2" + let "pu_checker|=0x2" + shift + shift + ;; + *) + echo "Syntax Error: unknown option: $key" + echo "" + usage + exit 1 + ;; +esac + +done + +if [ $jb_checker -ne 15 ] +then + echo "" + echo "Syntax Error: missing job information." + # TODO : list missing info + echo "" + exit 1 +fi + +if [ $PU_TRIG -eq 1 ] && [ $MR_TRIG -eq 1 ] +then + echo "" + echo "Syntax Error: trigger action incoherent." + echo "" + trigger_usage + exit 1 +fi + +if [ $PU_TRIG -eq 1 ] +then + if [ $pu_checker -ne 3 ] + then + echo "" + echo "Syntax Error: missing push information." + # TODO : list missing info + echo "" + exit 1 + fi +fi + +if [ $MR_TRIG -eq 1 ] +then + if [ $mr_checker -ne 15 ] + then + echo "" + echo "Syntax Error: missing merge-request information." + # TODO : list missing info + echo "" + exit 1 + fi +fi + +echo "<!DOCTYPE html>" > ./test_simulator_results.html +echo "<html class=\"no-js\" lang=\"en-US\">" >> ./test_simulator_results.html +echo "<head>" >> ./test_simulator_results.html +echo " <title>Simulator Results for $JOB_NAME job build #$BUILD_ID</title>" >> ./test_simulator_results.html +echo " <base href = \"http://www.openairinterface.org/\" />" >> ./test_simulator_results.html +echo "</head>" >> ./test_simulator_results.html +echo "<body>" >> ./test_simulator_results.html +echo " <table style=\"border-collapse: collapse; border: none;\">" >> ./test_simulator_results.html +echo " <tr style=\"border-collapse: collapse; border: none;\">" >> ./test_simulator_results.html +echo " <td style=\"border-collapse: collapse; border: none;\">" >> ./test_simulator_results.html +echo " <a href=\"http://www.openairinterface.org/\">" >> ./test_simulator_results.html +echo " <img src=\"/wp-content/uploads/2016/03/cropped-oai_final_logo2.png\" alt=\"\" border=\"none\" height=50 width=150>" >> ./test_simulator_results.html +echo " </img>" >> ./test_simulator_results.html +echo " </a>" >> ./test_simulator_results.html +echo " </td>" >> ./test_simulator_results.html +echo " <td style=\"border-collapse: collapse; border: none; vertical-align: center;\">" >> ./test_simulator_results.html +echo " <b><font size = \"6\">Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID</font></b>" >> ./test_simulator_results.html +echo " </td>" >> ./test_simulator_results.html +echo " </tr>" >> ./test_simulator_results.html +echo " </table>" >> ./test_simulator_results.html +echo " <br>" >> ./test_simulator_results.html +echo " <table border = \"1\">" >> ./test_simulator_results.html +echo " <tr>" >> ./test_simulator_results.html +echo " <td bgcolor = \"lightcyan\" >Build Start Time (UTC)</td>" >> ./test_simulator_results.html +echo " <td>TEMPLATE_BUILD_TIME</td>" >> ./test_simulator_results.html +echo " </tr>" >> ./test_simulator_results.html +echo " <tr>" >> ./test_simulator_results.html +echo " <td bgcolor = \"lightcyan\" >GIT Repository</td>" >> ./test_simulator_results.html +echo " <td><a href=\"$GIT_URL\">$GIT_URL</a></td>" >> ./test_simulator_results.html +echo " </tr>" >> ./test_simulator_results.html +echo " <tr>" >> ./test_simulator_results.html +echo " <td bgcolor = \"lightcyan\" >Job Trigger</td>" >> ./test_simulator_results.html +if [ $PU_TRIG -eq 1 ]; then echo " <td>Push Event</td>" >> ./test_simulator_results.html; fi +if [ $MR_TRIG -eq 1 ]; then echo " <td>Merge-Request</td>" >> ./test_simulator_results.html; fi +echo " </tr>" >> ./test_simulator_results.html +if [ $PU_TRIG -eq 1 ] +then + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" >Branch</td>" >> ./test_simulator_results.html + echo " <td>$SOURCE_BRANCH</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" >Commit ID</td>" >> ./test_simulator_results.html + echo " <td>$SOURCE_COMMIT_ID</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html +fi +if [ $MR_TRIG -eq 1 ] +then + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" >Source Branch</td>" >> ./test_simulator_results.html + echo " <td>$SOURCE_BRANCH</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" >Source Commit ID</td>" >> ./test_simulator_results.html + echo " <td>$SOURCE_COMMIT_ID</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" >Target Branch</td>" >> ./test_simulator_results.html + echo " <td>$TARGET_BRANCH</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" >Target Commit ID</td>" >> ./test_simulator_results.html + echo " <td>$TARGET_COMMIT_ID</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html +fi +echo " </table>" >> ./test_simulator_results.html +echo " <h2>Test Summary</h2>" >> ./test_simulator_results.html + +ARCHIVES_LOC=archives/basic_sim/test +if [ -d $ARCHIVES_LOC ] +then + echo " <h3>Basic Simulator Check</h3>" >> ./test_simulator_results.html + + echo " <table border = \"1\">" >> ./test_simulator_results.html + echo " <tr bgcolor = \"#33CCFF\" >" >> ./test_simulator_results.html + echo " <th>Log File Name</th>" >> ./test_simulator_results.html + echo " <th>Command</th>" >> ./test_simulator_results.html + echo " <th>Status</th>" >> ./test_simulator_results.html + echo " <th>Statistics</th>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + + TRANS_MODES=("fdd" "tdd") + BW_CASES=(05 10 20) + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_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 " <tr>" >> ./test_simulator_results.html + echo " <td>$NAME_ENB --- $NAME_UE</td>" >> ./test_simulator_results.html + echo " <td>N/A</td>" >> ./test_simulator_results.html + NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "got UE capabilities for UE" $ENB_LOG` + if [ $NB_ENB_GOT_SYNC -eq 1 ] && [ $NB_UE_GOT_SYNC -eq 2 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ] + then + echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + fi + echo " <td><pre>" >> ./test_simulator_results.html + if [ $NB_ENB_GOT_SYNC -eq 1 ] + then + echo "<font color = \"blue\">- eNB --> got sync</font>" >> ./test_simulator_results.html + else + echo "<font color = \"red\"><b>- eNB NEVER got sync</b></font>" >> ./test_simulator_results.html + fi + if [ $NB_UE_GOT_SYNC -eq 2 ] + then + echo "<font color = \"blue\">- UE --> got sync</font>" >> ./test_simulator_results.html + else + echo "<font color = \"red\"><b>- UE NEVER got sync</b></font>" >> ./test_simulator_results.html + fi + if [ $NB_ENB_SYNCED_WITH_UE -eq 1 ] + then + echo "<font color = \"blue\">- UE attached to eNB</font>" >> ./test_simulator_results.html + else + echo "<font color = \"red\"><b>- UE NEVER attached to eNB</b></font>" >> ./test_simulator_results.html + fi + NB_SEGFAULT_ENB=`egrep -i -c "Segmentation Fault" $ENB_LOG` + if [ $NB_SEGFAULT_ENB -ne 0 ] + then + echo "<font color = \"red\"><b>- eNB --> Segmentation Fault</b></font>" >> ./test_simulator_results.html + fi + NB_SEGFAULT_UE=`egrep -i -c "Segmentation Fault" $UE_LOG` + if [ $NB_SEGFAULT_UE -ne 0 ] + then + echo "<font color = \"red\"><b>- UE --> Segmentation Fault</b></font>" >> ./test_simulator_results.html + fi + NB_ASSERTION_ENB=`egrep -i -c "Assertion" $ENB_LOG` + if [ $NB_ASSERTION_ENB -ne 0 ] + then + echo "<font color = \"red\"><b>- eNB --> Assertion</b></font>" >> ./test_simulator_results.html + awk 'BEGIN{assertion=10}{if(assertion < 3){print " " $0; assertion++};if ($0 ~/Assertion/){print " " $0;assertion=1}}END{}' $ENB_LOG >> ./test_simulator_results.html + fi + NB_ASSERTION_UE=`egrep -i -c "Assertion" $UE_LOG` + if [ $NB_ASSERTION_UE -ne 0 ] + then + echo "<font color = \"red\"><b>- eNB --> Assertion</b></font>" >> ./test_simulator_results.html + awk 'BEGIN{assertion=10}{if(assertion < 3){print " " $0; assertion++};if ($0 ~/Assertion/){print " " $0;assertion=1}}END{}' $UE_LOG >> ./test_simulator_results.html + fi + echo " </pre></td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + fi + PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_ue.txt + if [ -f $PING_CASE ] + then + echo " <tr>" >> ./test_simulator_results.html + NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " <td>$NAME</td>" >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` + echo " <td>$CMD</td>" >> ./test_simulator_results.html + FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + echo " <td>N/A</td>" >> ./test_simulator_results.html + else + NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` + NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` + if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] + then + echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + fi + echo " <td>" >> ./test_simulator_results.html + echo " <pre>" >> ./test_simulator_results.html + STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"` + echo "Packet Loss : $STATS" >> ./test_simulator_results.html + RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'` + echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html + RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'` + echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html + RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'` + echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html + echo " </pre>" >> ./test_simulator_results.html + echo " </td>" >> ./test_simulator_results.html + fi + echo " </tr>" >> ./test_simulator_results.html + fi + + if [ -f $ARCHIVES_LOC/${TMODE}_${BW}*iperf*dl*client*txt ] + then + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}*iperf*client*txt` + else + echo "There are no iperf files" + IPERF_TESTS="" + fi + for IPERF_CASE in $IPERF_TESTS + do + echo " <tr>" >> ./test_simulator_results.html + NAME=`echo $IPERF_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " <td>$NAME</td>" >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $IPERF_CASE | sed -e "s#COMMAND IS: ##"` + echo " <td>$CMD</td>" >> ./test_simulator_results.html + REQ_BITRATE=`echo $CMD | sed -e "s#^.*-b ##" -e "s#-i 1.*##"` + if [[ $REQ_BITRATE =~ .*K.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#K##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000.0" | bc -l` + fi + if [[ $REQ_BITRATE =~ .*M.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#M##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000.0" | bc -l` + fi + if [[ $REQ_BITRATE =~ .*G.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#G##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000000.0" | bc -l` + fi + FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` + FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` + EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` + PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` + PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` + PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` + else + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Kbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000" | bc -l` + fi + if [[ $EFFECTIVE_BITRATE =~ .*Mbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Mbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000" | bc -l` + fi + if [[ $EFFECTIVE_BITRATE =~ .*Gbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Gbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000000" | bc -l` + fi + PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` + if [[ $PERF_INT -lt 90 ]] + then + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"green\" >OK</td>" >> ./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#).*##"` + fi + echo " <td>" >> ./test_simulator_results.html + echo " <pre>" >> ./test_simulator_results.html + echo "Bitrate : $EFFECTIVE_BITRATE" >> ./test_simulator_results.html + echo "Bitrate Perf : $PERF %" >> ./test_simulator_results.html + echo "Jitter : $JITTER" >> ./test_simulator_results.html + echo "Packet Loss : $PACKETLOSS" >> ./test_simulator_results.html + echo " </pre>" >> ./test_simulator_results.html + echo " </td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + done + done + done + + echo " </table>" >> ./test_simulator_results.html +fi + +ARCHIVES_LOC=archives/phy_sim/test +if [ -d $ARCHIVES_LOC ] +then + echo " <h3>Physical Simulators Check</h3>" >> ./test_simulator_results.html + + echo " <table border = \"1\">" >> ./test_simulator_results.html + echo " <tr bgcolor = \"#33CCFF\" >" >> ./test_simulator_results.html + echo " <th>Log File Name</th>" >> ./test_simulator_results.html + echo " <th>Nb Tests</th>" >> ./test_simulator_results.html + echo " <th>Nb Errors</th>" >> ./test_simulator_results.html + echo " <th>Nb Failures</th>" >> ./test_simulator_results.html + echo " <th>Nb Failures</th>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + + XML_TESTS=`ls $ARCHIVES_LOC/*xml` + for XML_FILE in $XML_TESTS + do + echo " <tr>" >> ./test_simulator_results.html + NAME=`echo $XML_FILE | sed -e "s#$ARCHIVES_LOC/##"` + NB_TESTS=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*tests='##" -e "s#' *time=.*##"` + NB_ERRORS=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*errors='##" -e "s#' *failures=.*##"` + NB_FAILURES=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*failures='##" -e "s#' *hostname=.*##"` + NB_SKIPPED=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*skipped='##" -e "s#' *tests=.*##"` + if [ $NB_ERRORS -eq 0 ] && [ $NB_FAILURES -eq 0 ] + then + echo " <td bgcolor = \"green\" >$NAME</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"red\" >$NAME</td>" >> ./test_simulator_results.html + fi + echo " <td>$NB_TESTS</td>" >> ./test_simulator_results.html + echo " <td>$NB_ERRORS</td>" >> ./test_simulator_results.html + echo " <td>$NB_FAILURES</td>" >> ./test_simulator_results.html + echo " <td>$NB_SKIPPED</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + done + + echo " </table>" >> ./test_simulator_results.html + + echo " <h4>Details</h4>" >> ./test_simulator_results.html + for XML_FILE in $XML_TESTS + do + echo " <table border = \"1\">" >> ./test_simulator_results.html + echo " <tr bgcolor = \"#33CCFF\" >" >> ./test_simulator_results.html + echo " <th>Test Name</th>" >> ./test_simulator_results.html + echo " <th>Description</th>" >> ./test_simulator_results.html + echo " <th>Result</th>" >> ./test_simulator_results.html + echo " <th>Time</th>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + TESTCASES_LIST=`sed -e "s# #@#g" $XML_FILE | grep testcase` + for TESTCASE in $TESTCASES_LIST + do + echo " <tr>" >> ./test_simulator_results.html + NAME=`echo $TESTCASE | sed -e "s#^.*name='##" -e "s#'@description=.*##" | sed -e "s#@# #g"` + echo " <td>$NAME</td>" >> ./test_simulator_results.html + DESC=`echo $TESTCASE | sed -e "s#^.*description='##" -e "s#'@Run_result=.*##" | sed -e "s#@# #g"` + echo " <td>$DESC</td>" >> ./test_simulator_results.html + RESULT=`echo $TESTCASE | sed -e "s#^.*RESULT='##" -e "s#'.*##" | sed -e "s#@# #g"` + if [[ $RESULT =~ .*PASS.* ]] + then + echo " <td bgcolor = \"green\" >$RESULT</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"red\" >$RESULT</td>" >> ./test_simulator_results.html + fi + TIME=`echo $TESTCASE | sed -e "s#^.*time='##" -e "s#'@RESULT=.*##" | sed -e "s#@# #g"` + echo " <td>$TIME</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + done + echo " </table>" >> ./test_simulator_results.html + done +fi + +echo "</body>" >> ./test_simulator_results.html +echo "</html>" >> ./test_simulator_results.html + +exit 0 diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 68438758f5bf41936520958be57f33c9addc86a8..efdfcec3e09ac4572caee49ae28770b8a114a9c9 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -70,6 +70,232 @@ function variant_usage { echo "" } +function start_basic_sim_enb { + local LOC_VM_IP_ADDR=$2 + local LOC_EPC_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_NB_RBS=$5 + local LOC_CONF_FILE=$6 + echo "cd /home/ubuntu/tmp" > $1 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"export ENODEB=1\"" >> $1 + echo "export ENODEB=1" >> $1 + echo "echo \"source oaienv\"" >> $1 + echo "source oaienv" >> $1 + echo "cd ci-scripts/conf_files/" >> $1 + echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 + echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 + echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/basic_simulator/enb/\"" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/basic_simulator/enb/" >> $1 + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1 + echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 + echo "cat ./my-lte-softmodem-run.sh" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/basic_simulator/enb -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 + + ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 + sleep 10 + rm $1 +} + +function start_basic_sim_ue { + local LOC_UE_LOG_FILE=$3 + local LOC_NB_RBS=$4 + local LOC_FREQUENCY=$5 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/basic_simulator/ue\"" > $1 + echo "cd /home/ubuntu/tmp/cmake_targets/basic_simulator/ue" > $1 + echo "echo \"./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_NB_RBS --ue-rxgain 140\" > ./my-lte-uesoftmodem-run.sh" >> $1 + echo "chmod 775 ./my-lte-uesoftmodem-run.sh" >> $1 + echo "cat ./my-lte-uesoftmodem-run.sh" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/basic_simulator/ue -o /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE ./my-lte-uesoftmodem-run.sh" >> $1 + + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 + + local i="0" + echo "ifconfig oip1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + UE_SYNC=0 + else + UE_SYNC=1 + fi +} + +function get_ue_ip_addr { + echo "ifconfig oip1 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 + UE_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1` + echo "UE IP Address for EPC is : $UE_IP_ADDR" + rm $1 +} + +function ping_ue_ip_addr { + echo "echo \"ping -c 20 $3\"" > $1 + echo "echo \"COMMAND IS: ping -c 20 $3\" > $4" > $1 + echo "ping -c 20 $UE_IP_ADDR | tee -a $4" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm -f $1 +} + +function check_ping_result { + local LOC_PING_FILE=$1 + local LOC_NB_PINGS=$2 + if [ -f $LOC_PING_FILE ] + then + local FILE_COMPLETE=`egrep -c "ping statistics" $LOC_PING_FILE` + if [ $FILE_COMPLETE -eq 0 ] + then + PING_STATUS=-1 + else + local ALL_PACKET_RECEIVED=`egrep -c "$LOC_NB_PINGS received" $LOC_PING_FILE` + if [ $ALL_PACKET_RECEIVED -eq 1 ] + then + echo "got all ping packets" + else + PING_STATUS=-1 + fi + fi + else + PING_STATUS=-1 + fi +} + +function iperf_dl { + local REQ_BANDWIDTH=$5 + local BASE_LOG_FILE=$6 + echo "echo \"iperf -u -s -i 1\"" > $1 + echo "echo \"COMMAND IS: iperf -u -s -i 1\" > tmp/cmake_targets/log/${BASE_LOG_FILE}_server.txt" > $1 + echo "nohup iperf -u -s -i 1 >> tmp/cmake_targets/log/${BASE_LOG_FILE}_server.txt &" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 + + echo "echo \"iperf -c $UE_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\"" > $3 + echo "echo \"COMMAND IS: iperf -c $UE_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\" > ${BASE_LOG_FILE}_client.txt" > $3 + echo "iperf -c $UE_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1 | tee -a ${BASE_LOG_FILE}_client.txt" >> $3 + ssh -o StrictHostKeyChecking=no ubuntu@$4 < $3 + rm -f $3 + + echo "killall --signal SIGKILL iperf" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 +} + +function iperf_ul { + local REQ_BANDWIDTH=$5 + local BASE_LOG_FILE=$6 + echo "echo \"iperf -u -s -i 1\"" > $3 + echo "echo \"COMMAND IS: iperf -u -s -i 1\" > ${BASE_LOG_FILE}_server.txt" > $3 + echo "nohup iperf -u -s -i 1 >> ${BASE_LOG_FILE}_server.txt &" >> $3 + ssh -o StrictHostKeyChecking=no ubuntu@$4 < $3 + rm $3 + + echo "echo \"iperf -c $REAL_EPC_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\"" > $1 + echo "echo \"COMMAND IS: iperf -c $REAL_EPC_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\" > /home/ubuntu/tmp/cmake_targets/log/${BASE_LOG_FILE}_client.txt" > $1 + echo "iperf -c $REAL_EPC_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1 | tee -a /home/ubuntu/tmp/cmake_targets/log/${BASE_LOG_FILE}_client.txt" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm -f $1 + + echo "killall --signal SIGKILL iperf" >> $3 + ssh -o StrictHostKeyChecking=no ubuntu@$4 < $3 + rm $3 +} + +function check_iperf { + local LOC_BASE_LOG=$1 + local LOC_REQ_BW=$2 + local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` + if [ -f ${LOC_BASE_LOG}_client.txt ] + then + local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` + if [ $FILE_COMPLETE -eq 0 ] + then + IPERF_STATUS=-1 + else + local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + IPERF_STATUS=-1 + fi + fi + else + IPERF_STATUS=-1 + fi +} + +function terminate_enb_ue_basic_sim { + echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" > $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=enb_daemon --stop\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=enb_daemon --stop; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=ue_daemon --stop\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=ue_daemon --stop; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 + echo "echo \"ps -aux | grep softmodem\"" >> $1 + echo "ps -aux | grep softmodem | grep -v grep" >> $1 + echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGINT lte-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGINT lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 + echo "echo \"ps -aux | grep softmodem\"" >> $1 + echo "ps -aux | grep softmodem | grep -v grep" >> $1 + echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-uesoftmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-uesoftmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 + echo "echo \"ps -aux | grep softmodem\"" >> $1 + echo "ps -aux | grep softmodem | grep -v grep" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm -f $1 +} + +function recover_core_dump { + local IS_SEG_FAULT=`egrep -ic "segmentation fault" $3` + if [ $IS_SEG_FAULT -ne 0 ] + then + local TC=`echo $3 | sed -e "s#^.*enb_##" -e "s#Hz.*#Hz#"` + echo "Segmentation fault detected on enb -> recovering core dump" + echo "cd /home/ubuntu/tmp/cmake_targets/basic_simulator/enb" > $1 + echo "sync" >> $1 + echo "sudo tar -cjhf basic-simulator-enb-core-${TC}.bz2 core lte-softmodem *.so ci-lte-basic-sim.conf my-lte-softmodem-run.sh" >> $1 + echo "sudo rm core" >> $1 + echo "rm ci-lte-basic-sim.conf" >> $1 + echo "sync" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/basic_simulator/enb/basic-simulator-enb-core-${TC}.bz2 $4 + rm -f $1 + fi +} + +function terminate_ltebox_epc { + echo "echo \"cd /opt/ltebox/tools\"" > $1 + echo "cd /opt/ltebox/tools" >> $1 + echo "echo \"sudo ./stop_ltebox\"" >> $1 + echo "sudo ./stop_ltebox" >> $1 + echo "echo \"sudo daemon --name=simulated_hss --stop\"" >> $1 + echo "sudo daemon --name=simulated_hss --stop" >> $1 + echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1 + echo "sudo killall --signal SIGKILL hss_sim" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 +} + if [ $# -lt 1 ] || [ $# -gt 9 ] then echo "Syntax Error: not the correct number of arguments" @@ -122,6 +348,8 @@ case $key in ;; -v2) VM_NAME=ci-basic-sim + RUN_OPTIONS="complex" + ARCHIVES_LOC=basic_sim/test shift ;; -v3) @@ -150,6 +378,8 @@ case $key in ;; basic-sim) VM_NAME=ci-basic-sim + RUN_OPTIONS="complex" + ARCHIVES_LOC=basic_sim/test ;; phy-sim) VM_NAME=ci-phy-sim @@ -210,8 +440,11 @@ echo "$VM_NAME has for IP addr = $VM_IP_ADDR" if [ "$RUN_OPTIONS" == "none" ] then echo "No run on VM testing for this variant currently" -else + exit $STATUS +fi +if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]] +then echo "############################################################" echo "Running test script on VM ($VM_NAME)" echo "############################################################" @@ -271,7 +504,7 @@ else rm -f $VM_CMDS echo "############################################################" - echo "Checking build status" + echo "Checking run status" echo "############################################################" LOG_FILES=`ls $ARCHIVES_LOC/results_autotests*.xml` @@ -306,13 +539,493 @@ else if [ $NB_RUNS -eq 0 ]; then STATUS=-1; fi if [ $NB_FAILURES -ne 0 ]; then STATUS=-1; fi - if [ $STATUS -eq 0 ] +fi + +if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-basic-sim.* ]] +then + PING_STATUS=0 + IPERF_STATUS=0 + if [ -d $ARCHIVES_LOC ] then - echo "STATUS seems OK" - else - echo "STATUS failed?" + rm -Rf $ARCHIVES_LOC + fi + mkdir --parents $ARCHIVES_LOC + + EPC_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#epc#"` + LTEBOX=0 + if [ -d /opt/ltebox-archives/ ] + then + # Checking if all ltebox archives are available to run ltebx epc on a brand new VM + if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ] + then + echo "############################################################" + echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox" + echo "############################################################" + LTEBOX=1 + fi + fi + # Here we could have other types of EPC detection + + # Do we need to start the EPC VM + EPC_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#epc-cmds#"` + echo "EPC_VM_CMD_FILE = $EPC_VM_CMDS" + IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $EPC_VM_NAME` + if [ $IS_EPC_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base" + echo "############################################################" + uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching + fi + + uvt-kvm wait $EPC_VM_NAME --insecure + EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` + echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR" + scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + + # ltebox specific actions (install and start) + LTE_BOX_TO_INSTALL=1 + if [ $LTEBOX -eq 1 ] + then + echo "ls -ls /opt/ltebox/tools/start_ltebox" > $EPC_VM_CMDS + RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` + NB_EXES=`echo $RESPONSE | grep -c ltebox` + if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi + fi + + if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ] + then + echo "############################################################" + echo "Copying ltebox archives into EPC VM ($EPC_VM_NAME)" + echo "############################################################" + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + + echo "############################################################" + echo "Install EPC on EPC VM ($EPC_VM_NAME)" + echo "############################################################" + echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $EPC_VM_CMDS + echo "touch /home/ubuntu/.hushlogin" >> $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\"" >> $EPC_VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $EPC_VM_CMDS + echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $EPC_VM_CMDS + + # Installing HSS + echo "echo \"cd /opt\"" >> $EPC_VM_CMDS + echo "cd /opt" >> $EPC_VM_CMDS + echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $EPC_VM_CMDS + echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $EPC_VM_CMDS + echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS + echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS + + # Installing ltebox + echo "echo \"cd /home/ubuntu\"" >> $EPC_VM_CMDS + echo "cd /home/ubuntu" >> $EPC_VM_CMDS + echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $EPC_VM_CMDS + echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $EPC_VM_CMDS + + echo "echo \"cd /opt/ltebox/etc/\"" >> $EPC_VM_CMDS + echo "cd /opt/ltebox/etc/" >> $EPC_VM_CMDS + echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $EPC_VM_CMDS + echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $EPC_VM_CMDS + echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' gw.conf" >> $EPC_VM_CMDS + echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' mme.conf" >> $EPC_VM_CMDS + fi + + # Starting EPC + if [ $LTEBOX -eq 1 ] + then + echo "############################################################" + echo "Start EPC on EPC VM ($EPC_VM_NAME)" + echo "############################################################" + echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS + echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS + echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $EPC_VM_CMDS + echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $EPC_VM_CMDS + + echo "echo \"cd /opt/ltebox/tools/\"" >> $EPC_VM_CMDS + echo "cd /opt/ltebox/tools/" >> $EPC_VM_CMDS + echo "echo \"sudo ./start_ltebox\"" >> $EPC_VM_CMDS + echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $EPC_VM_CMDS + + ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS + rm -f $EPC_VM_CMDS + + # We may have some adaptation to do + if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ] + then + echo "############################################################" + echo "Doing some adaptation on UE side" + echo "############################################################" + ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt + fi + + i="0" + echo "ifconfig tun5 | egrep -c \"inet addr\"" > $EPC_VM_CMDS + while [ $i -lt 10 ] + do + sleep 2 + CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $EPC_VM_CMDS + if [ $i -lt 50 ] + then + echo "Problem w/ starting ltebox EPC" + exit -1 + fi + fi + + # HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC + + # Retrieve EPC real IP address + if [ $LTEBOX -eq 1 ] + then + # in our configuration file, we are using pool 5 + echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $EPC_VM_CMDS + REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` + echo "EPC IP Address is : $REAL_EPC_IP_ADDR" + rm $EPC_VM_CMDS + fi + + echo "############################################################" + echo "Starting the eNB in FDD-5MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in FDD-5MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=fdd_05MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + 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 "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + + echo "############################################################" + echo "Iperf UL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_ul + iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 + + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + + echo "############################################################" + echo "Starting the eNB in FDD-10MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_10MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-fdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in FDD-10MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_10MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=fdd_10MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + 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 "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + + echo "############################################################" + echo "Iperf UL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_ul + iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 + + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + + echo "############################################################" + echo "Starting the eNB in FDD-20MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_20MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-fdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in FDD-20MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_20MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=fdd_20MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + 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 "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_20MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + + echo "############################################################" + echo "Starting the eNB in TDD-5MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=tdd_05MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-tdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in TDD-5MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=tdd_05MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2350 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=tdd_05MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + 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 + +# Bug in TDD 5Mhz --- not running it +# echo "############################################################" +# echo "Iperf DL" +# echo "############################################################" +# CURR_IPERF_LOG_BASE=tdd_05MHz_iperf_dl +# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC +# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 + + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + + echo "############################################################" + echo "Starting the eNB in TDD-10MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in TDD-10MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=tdd_10MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + 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 "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + +# Disabling TDD-20MHz test since it is very unstable +# +# echo "############################################################" +# echo "Starting the eNB in TDD-20MHz mode" +# echo "############################################################" +# CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log +# start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf +# +# echo "############################################################" +# echo "Starting the UE in TDD-20MHz mode" +# echo "############################################################" +# CURRENT_UE_LOG_FILE=tdd_20MHz_ue.log +# start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2350 +# if [ $UE_SYNC -eq 0 ] +# then +# echo "Problem w/ eNB and UE not syncing" +# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC +# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR +# exit -1 +# fi +# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR +# +# echo "############################################################" +# echo "Pinging the UE" +# echo "############################################################" +# PING_LOG_FILE=tdd_20MHz_ping_ue.txt +# ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE +# 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 "############################################################" +# echo "Iperf DL" +# echo "############################################################" +# CURR_IPERF_LOG_BASE=tdd_20MHz_iperf_dl +# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC +# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 +# +# echo "############################################################" +# echo "Terminate enb/ue simulators" +# echo "############################################################" +# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC +# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + + echo "############################################################" + echo "Terminate EPC" + echo "############################################################" + + if [ $LTEBOX -eq 1 ] + then + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + fi + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + +fi + +if [ $STATUS -eq 0 ] +then + echo "STATUS seems OK" +else + echo "STATUS failed?" fi exit $STATUS diff --git a/ci-scripts/tcp_iperf_stats.awk b/ci-scripts/tcp_iperf_stats.awk new file mode 100644 index 0000000000000000000000000000000000000000..e5c64b628353635412f0824a52a83f2f1736c00e --- /dev/null +++ b/ci-scripts/tcp_iperf_stats.awk @@ -0,0 +1,14 @@ +BEGIN{max=0;min=10000} +{ + if ($0 ~/Mbits/) { + split($0,a,"MBytes") + split(a[2],b) + if (b[1]>max) { + max=b[1] + } + if (b[1]<min) { + min=b[1] + } + } +} +END{print "Avg Bitrate : " b[1] " Mbits/sec Max Bitrate : " max " Mbits/sec Min Bitrate : " min " Mbits/sec"} diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index b8a2439106b21632ed5f4bed8f4569da84c785d6..0785ad815d28a9fe85e65a6d6a3a9f5ff96f2861 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -21,7 +21,14 @@ --> <testCaseList> - <TestCaseRequestedList>010101 050101 060101 070101 040101 030101 040301 040501 040601 040602 040603 040604 040605 040641 040642 040401 040201 030201 030111 040301 040511 040611 040612 040613 040614 040615 040651 040652 040401 040201 030201 030121 040301 040521 040621 040622 040623 040624 040625 040662 040661 040401 040201 030201 </TestCaseRequestedList> + <TestCaseRequestedList> + 010101 + 050101 060101 070101 040101 + 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 + 030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201 + 030121 040301 040521 040623 040624 040625 040626 040627 040662 040661 040663 040664 040401 040201 030201 + 050201 060201 070201 + </TestCaseRequestedList> <TestCaseExclusionList></TestCaseExclusionList> <testCase id="010101"> @@ -94,162 +101,222 @@ <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> - <testCase id="040601"> + <testCase id="040603"> <class>Iperf</class> - <desc>iperf (5MHz - DL/6Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 6M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - </testCase> + <iperf_profile>balanced</iperf_profile> + </testCase> - <testCase id="040602"> + <testCase id="040604"> <class>Iperf</class> - <desc>iperf (5MHz - DL/13Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 13M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> </testCase> - <testCase id="040603"> + <testCase id="040605"> <class>Iperf</class> - <desc>iperf (5MHz - DL/15Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 15M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> </testCase> - <testCase id="040604"> + <testCase id="040606"> <class>Iperf</class> - <desc>iperf (5MHz - DL/15Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 15M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> - <testCase id="040605"> + <testCase id="040607"> <class>Iperf</class> - <desc>iperf (5MHz - DL/15Mbps/UDP)(60 sec)(unbalanced profile)</desc> - <iperf_args>-u -b 15M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - DL/TCP)(30 sec)(balanced profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>unbalanced</iperf_profile> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040641"> <class>Iperf</class> - <desc>iperf (5MHz - UL/9Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 9M -t 60 -i 1 -R</iperf_args> + <desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile)</desc> + <iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040642"> <class>Iperf</class> - <desc>iperf (5MHz - UL/9Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 9M -t 60 -i 1 -R</iperf_args> + <desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> - <testCase id="040611"> + <testCase id="040643"> <class>Iperf</class> - <desc>iperf (10MHz - DL/10Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 10M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - </testCase> + <iperf_profile>single-ue</iperf_profile> + </testCase> - <testCase id="040612"> + <testCase id="040644"> <class>Iperf</class> - <desc>iperf (10MHz - DL/20Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 20M -t 60 -i 1</iperf_args> + <desc>iperf (5MHz - UL/TCP)(30 sec)(balanced profile)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040613"> <class>Iperf</class> - <desc>iperf (10MHz - DL/30Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 30M -t 60 -i 1</iperf_args> + <desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile)</desc> + <iperf_args>-u -b 30M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040614"> <class>Iperf</class> - <desc>iperf (10MHz - DL/30Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 30M -t 60 -i 1</iperf_args> + <desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 30M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> <testCase id="040615"> <class>Iperf</class> - <desc>iperf (10MHz - DL/30Mbps/UDP)(60 sec)(unbalanced profile)</desc> - <iperf_args>-u -b 30M -t 60 -i 1</iperf_args> + <desc>iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile)</desc> + <iperf_args>-u -b 30M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040616"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040617"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/TCP)(30 sec)(balanced profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + <testCase id="040651"> <class>Iperf</class> - <desc>iperf (10MHz - UL/20Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 20M -t 60 -i 1 -R</iperf_args> + <desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)</desc> + <iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040652"> <class>Iperf</class> - <desc>iperf (10MHz - UL/20Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 20M -t 60 -i 1 -R</iperf_args> + <desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> - <testCase id="040621"> + <testCase id="040653"> <class>Iperf</class> - <desc>iperf (20MHz - DL/20Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 20M -t 60 -i 1</iperf_args> + <desc>iperf (10MHz - UL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - </testCase> + <iperf_profile>single-ue</iperf_profile> + </testCase> - <testCase id="040622"> + <testCase id="040654"> <class>Iperf</class> - <desc>iperf (20MHz - DL/40Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 40M -t 60 -i 1</iperf_args> + <desc>iperf (10MHz - UL/TCP)(30 sec)(balanced profile)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040623"> <class>Iperf</class> - <desc>iperf (20MHz - DL/70Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 70M -t 60 -i 1</iperf_args> + <desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile)</desc> + <iperf_args>-u -b 70M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040624"> <class>Iperf</class> - <desc>iperf (20MHz - DL/70Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 70M -t 60 -i 1</iperf_args> + <desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 70M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> <testCase id="040625"> <class>Iperf</class> - <desc>iperf (20MHz - DL/70Mbps/UDP)(60 sec)(unbalanced profile)</desc> - <iperf_args>-u -b 70M -t 60 -i 1</iperf_args> + <desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile)</desc> + <iperf_args>-u -b 70M -t 30 -i 1</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040626"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040627"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/TCP)(30 sec)(balanced profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + <testCase id="040661"> <class>Iperf</class> - <desc>iperf (20MHz - UL/20Mbps/UDP)(60 sec)</desc> - <iperf_args>-u -b 20M -t 60 -i 1 -R</iperf_args> + <desc>iperf (20MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)</desc> + <iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040662"> <class>Iperf</class> - <desc>iperf (20MHz - UL/20Mbps/UDP)(60 sec)(single-ue profile)</desc> - <iperf_args>-u -b 20M -t 60 -i 1 -R</iperf_args> + <desc>iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> + <testCase id="040663"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040664"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/TCP)(30 sec)(balanced profile)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + <testCase id="050101"> <class>Initialize_HSS</class> <desc>Initialize HSS</desc> @@ -265,4 +332,19 @@ <desc>Initialize SPGW</desc> </testCase> + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + </testCaseList> diff --git a/ci-scripts/xml_files/enb_usrpb210_band40.xml b/ci-scripts/xml_files/enb_usrpb210_band40.xml new file mode 100644 index 0000000000000000000000000000000000000000..1af1c319cfe4eaf6d8c7d60eafd4019ae130e5ab --- /dev/null +++ b/ci-scripts/xml_files/enb_usrpb210_band40.xml @@ -0,0 +1,226 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <TestCaseRequestedList> + 010101 + 050101 060101 070101 040101 + 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 + 030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201 + 050201 060201 070201 + </TestCaseRequestedList> + <!-- 20MHz is not stable enough to be run --> + <!-- + 030124 040301 040521 040622 040621 040623 040662 040661 040663 040401 040201 030201 + --> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="010101"> + <class>Build_eNB</class> + <desc>Build eNB (USRP)</desc> + <Build_eNB_args>-w USRP -c --eNB</Build_eNB_args> + </testCase> + + <testCase id="030104"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (TDD/Band40/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + </testCase> + + <testCase id="030114"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (TDD/Band40/10MHz/info)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + </testCase> + + <testCase id="030106"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (TDD/Band40/20MHz/info)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate eNB</desc> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040501"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>25</ping_packetloss_threshold> + </testCase> + + <testCase id="040511"> + <class>Ping</class> + <desc>ping (10MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>25</ping_packetloss_threshold> + </testCase> + + <testCase id="040601"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced)</desc> + <iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040602"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040603"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> + </testCase> + + <testCase id="040611"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc> + <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040612"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040613"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> + </testCase> + + <testCase id="040641"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040642"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040643"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> + </testCase> + + <testCase id="040651"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040652"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040653"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> + </testCase> + + <testCase id="050101"> + <class>Initialize_HSS</class> + <desc>Initialize HSS</desc> + </testCase> + + <testCase id="060101"> + <class>Initialize_MME</class> + <desc>Initialize MME</desc> + </testCase> + + <testCase id="070101"> + <class>Initialize_SPGW</class> + <desc>Initialize SPGW</desc> + </testCase> + + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40.xml b/ci-scripts/xml_files/if4p5_usrp210_band40.xml new file mode 100644 index 0000000000000000000000000000000000000000..9c1b721bef1863d4db73b4c1f4a5ea8cb5d2c1d2 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40.xml @@ -0,0 +1,219 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <!-- Only 5MHz is tested since neither 10MHz nor 20MHz work in this configuration --> + <!-- Also no UL iperf in 5MHz (040642) --> + <TestCaseRequestedList> + 010101 + 050101 060101 070101 040101 + 030104 030105 040301 040501 040602 040401 040201 030201 030202 + 050201 060201 070201 + </TestCaseRequestedList> + <!-- + 030104 030105 040301 040501 040602 040642 040401 040201 030201 030202 + 030114 030115 040301 040511 040612 040652 040401 040201 030201 030202 + 030124 030125 040301 040521 040622 040662 040401 040201 030201 030202 + --> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="010101"> + <class>Build_eNB</class> + <desc>Build eNB (USRP -- Ethernet Fronthaul)</desc> + <Build_eNB_args>-t ETHERNET -w USRP -c --eNB</Build_eNB_args> + </testCase> + + <testCase id="030104"> + <class>Initialize_eNB</class> + <desc>Initialize RRU (TDD/Band40)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030105"> + <class>Initialize_eNB</class> + <desc>Initialize RCC (TDD/Band40/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030114"> + <class>Initialize_eNB</class> + <desc>Initialize RRU (TDD/Band40)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030115"> + <class>Initialize_eNB</class> + <desc>Initialize RCC (TDD/Band40/10MHz/info)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030124"> + <class>Initialize_eNB</class> + <desc>Initialize RRU (TDD/Band40)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030125"> + <class>Initialize_eNB</class> + <desc>Initialize RCC (TDD/Band40/20MHz/info)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate RCC</desc> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate RRU</desc> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040501"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>25</ping_packetloss_threshold> + </testCase> + + <testCase id="040511"> + <class>Ping</class> + <desc>ping (10MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>25</ping_packetloss_threshold> + </testCase> + + <testCase id="040521"> + <class>Ping</class> + <desc>ping (20MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>25</ping_packetloss_threshold> + </testCase> + + <testCase id="040602"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 6.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040612"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040622"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040642"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040652"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040662"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="050101"> + <class>Initialize_HSS</class> + <desc>Initialize HSS</desc> + </testCase> + + <testCase id="060101"> + <class>Initialize_MME</class> + <desc>Initialize MME</desc> + </testCase> + + <testCase id="070101"> + <class>Initialize_SPGW</class> + <desc>Initialize SPGW</desc> + </testCase> + + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7.xml b/ci-scripts/xml_files/if4p5_usrp210_band7.xml new file mode 100644 index 0000000000000000000000000000000000000000..a3e5ecd72c39b0facc4cdc140cdfdf297b812a43 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7.xml @@ -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 + +--> +<testCaseList> + <!-- Only 5MHz is tested since neither 10MHz nor 20MHz work in this configuration --> + <TestCaseRequestedList> + 010101 + 050101 060101 070101 040101 + 030101 030102 040301 040501 040604 040642 040401 040201 030201 030202 + 050201 060201 070201 + </TestCaseRequestedList> + <!-- + 030111 030112 040301 040511 040614 040652 040401 040201 030201 030202 + 030121 030122 040301 040521 040624 040662 040401 040201 030201 030202 + --> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="010101"> + <class>Build_eNB</class> + <desc>Build eNB (USRP -- Ethernet Fronthaul)</desc> + <Build_eNB_args>-t ETHERNET -w USRP -c --eNB</Build_eNB_args> + </testCase> + + <testCase id="030101"> + <class>Initialize_eNB</class> + <desc>Initialize RRU (FDD/Band7)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030102"> + <class>Initialize_eNB</class> + <desc>Initialize RCC (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030111"> + <class>Initialize_eNB</class> + <desc>Initialize RRU (FDD/Band7)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030112"> + <class>Initialize_eNB</class> + <desc>Initialize RCC (FDD/Band7/10MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030121"> + <class>Initialize_eNB</class> + <desc>Initialize RRU (FDD/Band7)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030122"> + <class>Initialize_eNB</class> + <desc>Initialize RCC (FDD/Band7/20MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate RCC</desc> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate RRU</desc> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040501"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040604"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040642"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040511"> + <class>Ping</class> + <desc>ping (10MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040614"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 32M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040652"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040521"> + <class>Ping</class> + <desc>ping (20MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040624"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 70M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040662"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="050101"> + <class>Initialize_HSS</class> + <desc>Initialize HSS</desc> + </testCase> + + <testCase id="060101"> + <class>Initialize_MME</class> + <desc>Initialize MME</desc> + </testCase> + + <testCase id="070101"> + <class>Initialize_SPGW</class> + <desc>Initialize SPGW</desc> + </testCase> + + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + +</testCaseList> diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5efb13594f5f0bea5dba30a590d1b3e5d9235391..23d96afc545720b140473a29088dcd0c49f4834e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -170,11 +170,12 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ") # add autotools definitions that were maybe used! set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -DASN_DISABLE_OER_SUPPORT -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" + "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" ) set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 " + "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" ) +add_definitions("-DASN_DISABLE_OER_SUPPORT") ######################### @@ -256,16 +257,13 @@ add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the b 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 (ITTI_DIR ${OPENAIR_DIR}/common/utils/itti) +set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) if (${ENABLE_ITTI}) add_library(ITTI # add .h files if depend on (this one is generated) - ${ITTI_DIR}/intertask_interface.h - ${ITTI_DIR}/intertask_interface.c - ${ITTI_DIR}/backtrace.c - ${ITTI_DIR}/memory_pools.c - ${ITTI_DIR}/signals.c - ${ITTI_DIR}/timer.c + ${OCP_ITTI}/intertask_interface.cpp + ${OPENAIR_DIR}/common/utils/backtrace.c + ${OPENAIR_DIR}/common/utils/memory_pools.c ) set(ITTI_LIB ITTI) set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c) @@ -474,6 +472,16 @@ add_library(X2AP_LIB include_directories ("${X2AP_C_DIR}") include_directories ("${X2AP_DIR}") +add_library(X2AP_ENB + ${X2AP_DIR}/x2ap_eNB.c + ${X2AP_DIR}/x2ap_eNB_decoder.c + ${X2AP_DIR}/x2ap_eNB_encoder.c + ${X2AP_DIR}/x2ap_eNB_handler.c + ${X2AP_DIR}/x2ap_eNB_itti_messaging.c + ${X2AP_DIR}/x2ap_eNB_management_procedures.c + ${X2AP_DIR}/x2ap_eNB_generate_messages.c + ) + # Hardware dependant options ################################### add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") @@ -744,11 +752,14 @@ include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0") include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES") include_directories("${OPENAIR2_DIR}/RRC/LTE") include_directories("${OPENAIR_DIR}/common/utils") -include_directories("${OPENAIR_DIR}/common/utils/itti") +include_directories("${OPENAIR_DIR}/common/utils/ocp_itti") include_directories("${OPENAIR3_DIR}/NAS/COMMON") include_directories("${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK") include_directories("${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG") include_directories("${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG") +include_directories("${OPENAIR3_DIR}/NAS/UE/ESM") +include_directories("${OPENAIR3_DIR}/NAS/UE/EMM") +include_directories("${OPENAIR3_DIR}/NAS/UE/API/USER") include_directories("${OPENAIR3_DIR}/NAS/COMMON/IES") include_directories("${OPENAIR3_DIR}/NAS/COMMON/UTIL") include_directories("${OPENAIR3_DIR}/SECU") @@ -860,6 +871,7 @@ add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c ) set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) #include_directories(${OPENAIR2_DIR}/ENB_APP) @@ -882,12 +894,9 @@ add_library(HASHTABLE ) include_directories(${OPENAIR_DIR}/common/utils/hashtable) -if (MESSAGE_CHART_GENERATOR) - add_library(MSC - ${OPENAIR_DIR}/common/utils/msc/msc.c - ) - set(MSC_LIB MSC) -endif() +add_library(msc MODULE ${OPENAIR_DIR}/common/utils/msc/msc.c ) +target_link_libraries (msc LFDS) + include_directories(${OPENAIR_DIR}/common/utils/msc) set(UTIL_SRC @@ -1108,6 +1117,7 @@ set(PHY_SRC # actual source ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots_mbsfn.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -1137,6 +1147,7 @@ set(PHY_SRC_RU ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c + ${OPENAIR1_DIR}/PHY/MODULATION/gen_75KHz.cpp ${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c ${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c ${OPENAIR1_DIR}/PHY/INIT/lte_init_ru.c @@ -1147,6 +1158,7 @@ set(PHY_SRC_RU set(PHY_SRC_UE # actual source ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sss_ue.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c @@ -1382,7 +1394,6 @@ include_directories(${NFAPI_USER_DIR}) add_library(CN_UTILS ${OPENAIR3_DIR}/UTILS/conversions.c ${OPENAIR3_DIR}/UTILS/enum_string.c - ${OPENAIR3_DIR}/UTILS/log.c ${OPENAIR3_DIR}/UTILS/mcc_mnc_itu.c ) @@ -1557,7 +1568,6 @@ set(libnas_ies_OBJS set (libnas_utils_OBJS ${NAS_SRC}COMMON/UTIL/device.c ${NAS_SRC}COMMON/UTIL/memory.c - ${NAS_SRC}COMMON/UTIL/nas_log.c ${NAS_SRC}COMMON/UTIL/nas_timer.c ${NAS_SRC}COMMON/UTIL/socket.c ${NAS_SRC}COMMON/UTIL/stty.c @@ -1937,7 +1947,7 @@ add_executable(lte-softmodem target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_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 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 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -1974,7 +1984,7 @@ add_executable(lte-softmodem-nos1 ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${RAL_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl ) @@ -2013,7 +2023,7 @@ add_executable(lte-uesoftmodem target_link_libraries (lte-uesoftmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB 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 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 ${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) @@ -2052,7 +2062,7 @@ add_executable(lte-uesoftmodem-nos1 target_link_libraries (lte-uesoftmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${RAL_LIB} ${ITTI_LIB} ${MIH_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 ) @@ -2116,7 +2126,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_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) @@ -2130,7 +2140,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 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 GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_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 @@ -2150,7 +2160,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 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 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} ) @@ -2186,7 +2196,7 @@ if (${T_TRACER}) dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim ulsim #all "add_library" definitions - ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB + ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_eth_transpro FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index f0b3256015834e0c774a3de3353ef0c4372e6c89..e7f274c2d027846170eb26f7039157d9a00f9efa 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -990,12 +990,12 @@ <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> <pre_exec_args></pre_exec_args> <main_exec> $OPENAIR_DIR/targets/bin/ulsim.Rel14</main_exec> - <main_exec_args> -B25 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 - -B25 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 - -B50 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 - -B50 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 - -B100 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 - -B100 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 </main_exec_args> + <main_exec_args> -BnbRBs=25 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=25 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=50 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=50 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=100 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=100 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 </main_exec_args> <tags>ulsim.test1 ulsim.test2 ulsim.test3 ulsim.test4 ulsim.test5 ulsim.test6</tags> <search_expr_true>"passed"</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf index e2ea056ea17c1ab0a31c597d057eaf01bb9426a9..398b76388898bd51b8814bd036ade8d45520a6cd 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth6"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.82/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; log_config : diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf index b2ac3ccf4224581389dc09d43d992ea4039bf502..46b648473742a635aba7181cae46388b6d090372 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth6"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.82/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; log_config : diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf index 006d59d2a54ca908d9b2dde9fb9141b9cf086bb5..93b82773e6461939d1dc6e9cb74e49e428fc2c18 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth6"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.82/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; log_config : diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf index 8c76d95d4c86d978198e922168888d368838b6fa..b412b00e523074bbe34f547c76d2978572fdb451 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.19/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; log_config : diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf index 0d2bb27dcc7c18c3b8446699a87357a529567611..f0d688903a6894508928af20ac76002badb57798 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.19/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; log_config : diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf index c418f355f20903326675577272da21d6dc8230e1..929c91fffbdb6c1a2b4a00db9208c760f23bf8b6 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.19/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; log_config : diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf index 89e06d2b1e4511f212507069db0d074b87adeb9f..98358eb269bd7305c7a94c28e3278ae4f49a3e29 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.18/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.18/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.18/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; rrh_gw_config = ( diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf index c8e6c861e0fddc61ec4a0cb7c9ce169bb36eaf20..bc31e051e57db834520b1bc29ccf60fac7ce97d7 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.18/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.18/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.18/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; rrh_gw_config = ( diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf index cc00f4f3ea584d662e58bfdeb7f95ea3073bc9ac..2cfc227e67aeef229152a853908bbb9648da88be 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -146,12 +143,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.18/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.18/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.18/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; rrh_gw_config = ( diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf index 6e1e776fed0da4bf219f6525b82db0accd8be758..9b135a94982c8214a6bfc17270d04c4e1b815cab 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -148,12 +145,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth3"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.215/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; rrh_gw_config = ( diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf index 7e7c3c185d41be1f6b7ed09fca0cec75d7fd3e85..9f84057299cd8ce552598399e85d52edd45c142e 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -148,12 +145,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth3"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.215/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; rrh_gw_config = ( diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf index 3098660c8de40e967d5e4adf7dc870b31d3ee1c3..7197e93322e56c63a6b77abd0a4256bdc6fdaeee 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -148,12 +145,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth3"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.215/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; rrh_gw_config = ( diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index c15e1e8ec788b1057aa07c7aba346656bf4f994f..3954827c0949fde7efa828f436cd54e21246463b 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -40,7 +40,7 @@ set_openair_env gen_nvram_path=$OPENAIR_DIR/targets/bin conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -MSC_GEN="False" +MSC_GEN=0 XFORMS="True" UE_EXPANSION="False" PRINT_STATS="False" @@ -155,6 +155,10 @@ Options Disable all LOG_* macros --build-eclipse Build eclipse project files. Paths are auto corrected by fixprj.sh +--build-telnet + Build telnet server, specify --telnetsrv on command line to start it (eNB only) +--build-msc + Build MSC tracing utility, specify --msc on command line to start it (eNB and UE) --usrp-recplay Build for I/Q record-playback modes --ue-nas-use-tun @@ -345,6 +349,10 @@ function main() { --build-telnetsrv) BUILD_TELNETSRV=1 echo_info "Build embedded telnet server" + shift ;; + --build-msc) + MSC_GEN=1 + echo_info "Build MSC tracing utility" shift ;; --usrp-recplay) USRP_REC_PLAY="True" @@ -690,6 +698,15 @@ function main() { $build_dir telnetsrv \ libtelnetsrv.so $dbin/libtelnetsrv.so + fi + # Telnet server compilation + ##################### + if [ "$MSC_GEN" = "1" ] ; then + build_dir=$lte_build_dir + compilations \ + $build_dir msc \ + libmsc.so $dbin/libmsc.so + fi # build RF device and transport protocol libraries ##################################### diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 81e3fe4b3ce7ac256ed4fea630ee30ec9425b2a1..c1a0bb419b74666eccc6a9c522a2394e4a688695 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -27,7 +27,6 @@ set(CONF2UEDATA_LIB_SRC ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c - ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c ${OPENAIR_DIR}/common/utils/utils.c diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 3363bd2e7658feef8f91ec18b80f738b43cc440b..18e0d5474612541276573ec79ed74927423679ca 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -683,7 +683,7 @@ install_asn1c_from_source(){ # better to use a given commit than a branch in case the branch # is updated and requires modifications in the source of OAI #git checkout velichkov_s1ap_plus_option_group - git checkout 73d6b23dcec9ab36605b4af884143824392134c1 + git checkout d3aed06bb2bec7df1b5c6d0333f8c7dfc5993372 autoreconf -iv ./configure make -j`nproc` diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 8b3026c22b96e2fa85bbe46c79561ab7266e6121..3bd41cf6cc481239a379a616553b3f878ae5a840 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -35,10 +35,11 @@ #include <stdio.h> #include <ctype.h> #include <errno.h> +#include <platform_types.h> #include "config_userapi.h" -void parse_stringlist(paramdef_t *cfgoptions, char *val) +int parse_stringlist(paramdef_t *cfgoptions, char *val) { char *atoken; char *tokctx; @@ -63,7 +64,7 @@ int numelt=0; printf_params("[LIBCONFIG] %s[%i]: %s\n", cfgoptions->optname,i,cfgoptions->strlistptr[i]); atoken=strtok_r(NULL, ",",&tokctx); } - cfgoptions->numelt=numelt; + return (cfgoptions->numelt > 0); } int processoption(paramdef_t *cfgoptions, char *value) @@ -95,7 +96,7 @@ char defbool[2]="1"; break; case TYPE_STRINGLIST: - parse_stringlist(cfgoptions,tmpval); + optisset=parse_stringlist(cfgoptions,tmpval); break; case TYPE_UINT32: case TYPE_INT32: @@ -141,25 +142,16 @@ char defbool[2]="1"; int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) { - - -int c = config_get_if()->argc; -int i,j; -char *pp; -char *cfgpath; + int c = config_get_if()->argc; + int i,j; + char *pp; + char cfgpath[512]; /* 512 should be enough for the sprintf below */ - j = (prefix ==NULL) ? 0 : strlen(prefix); - cfgpath = malloc( j + MAX_OPTNAME_SIZE +1); - if (cfgpath == NULL) { - fprintf(stderr,"[CONFIG] %s %i malloc error, %s\n", __FILE__, __LINE__,strerror(errno)); - return -1; - } - j = 0; i = 0; while (c > 0 ) { char *oneargv = strdup(config_get_if()->argv[i]); /* we use strtok_r which modifies its string paramater, and we don't want argv to be modified */ -/* first check help options, either --help, -h or --help_<section> */ + /* first check help options, either --help, -h or --help_<section> */ if (strncmp(oneargv, "-h",2) == 0 || strncmp(oneargv, "--help",6) == 0 ) { char *tokctx; pp=strtok_r(oneargv, "_",&tokctx); @@ -182,7 +174,7 @@ char *cfgpath; } } -/* now, check for non help options */ + /* now, check for non help options */ if (oneargv[0] == '-') { for(int n=0;n<numoptions;n++) { if ( ( cfgoptions[n].paramflags & PARAMFLAG_DISABLECMDLINE) != 0) { @@ -223,9 +215,5 @@ char *cfgpath; c--; } /* fin du while */ printf_cmdl("[CONFIG] %s %i options set from command line\n",((prefix == NULL) ? "(root)":prefix),j); - free(cfgpath); return j; } /* parse_cmdline*/ - - - diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 3f3651aa011d7743a342ded3550e87eb11a3efc1..0ec2e2379042042841ceac490adc58be97ee9de2 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -29,6 +29,9 @@ * \note * \warning */ + +#define _GNU_SOURCE + #include <string.h> #include <stdlib.h> #include <stdio.h> @@ -37,8 +40,8 @@ #include <dlfcn.h> #include <arpa/inet.h> +#include <platform_types.h> #include "config_userapi.h" -extern void exit_fun(const char* s); // lte-softmodem clean exit function configmodule_interface_t *config_get_if(void) @@ -210,6 +213,36 @@ configmodule_interface_t *cfgif = config_get_if(); return ret; } +int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix) +{ + if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { + fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); + return -1; + } + if (!config_get_if()) + return -1; + + const int ret = config_get_if()->getlist(ParamList, params, numparams, prefix); + if (ret >= 0 && params) { + char *newprefix; + if (prefix) { + int rc = asprintf(&newprefix, "%s.%s", prefix, ParamList->listname); + if (rc < 0) newprefix = NULL; + } else { + newprefix = ParamList->listname; + } + char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */ + for (int i = 0; i < ParamList->numelt; ++i) { + // TODO config_process_cmdline? + sprintf(cfgpath, "%s.[%i]", newprefix, i); + config_execcheck(ParamList->paramarray[i], numparams, cfgpath); + } + if (prefix) + free(newprefix); + } + return ret; +} + int config_isparamset(paramdef_t *params,int paramidx) { if ((params[paramidx].paramflags & PARAMFLAG_PARAMSET) != 0) { diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 217310db36ee4c71fdbbe811361c5b2304080354..2b40f8401be2466cda9adfbbb3725910b83fd828 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -38,8 +38,6 @@ extern "C" { #endif -/* get rid of "exit_fun undeclared" warning */ -extern void exit_fun(const char* s); #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) @@ -59,7 +57,7 @@ extern int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr); /* apis to get parameters, to be used by oai modules, at configuration time */ extern int config_get(paramdef_t *params,int numparams, char *prefix); -#define config_getlist config_get_if()->getlist +extern int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix); /* apis to retrieve parameters info after calling get or getlist functions */ extern int config_isparamset(paramdef_t *params,int paramidx); diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index f192fd2dc57c0af28e5df3c72238b4b730e3c81d..cb6fa46293ed77aa97812e557f8d6c4843c10ef9 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -91,8 +91,6 @@ int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpat int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) { - - config_setting_t *setting; char *str; int i,u; @@ -103,15 +101,9 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) int notfound; int defval; int fatalerror=0; - char *cfgpath; /* listname.[listindex].paramname */ int numdefvals=0; - - i = (prefix ==NULL) ? 0 : strlen(prefix); - cfgpath = malloc( i+ MAX_OPTNAME_SIZE +1); - if (cfgpath == NULL) { - fprintf(stderr,"[LIBCONFIG] %s %i malloc error, %s\n", __FILE__, __LINE__,strerror(errno)); - return -1; - } + char cfgpath[512]; /* 512 should be enough for the sprintf below */ + for(i=0;i<numoptions;i++) { if (prefix != NULL) { @@ -253,7 +245,6 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_libconfig_end(); end_configmodule(); } - free(cfgpath); return status; } diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 02ee849202e285aeb936312a12b754ae6f21b19f..d6dd97e34fc13e3dc1e807a67afdaf82971d3791 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -54,7 +54,6 @@ mapping log_level_names[] = { {"error", OAILOG_ERR}, - {"file", OAILOG_FILE}, {"warn", OAILOG_WARNING}, {"info", OAILOG_INFO}, {"debug", OAILOG_DEBUG}, @@ -70,18 +69,10 @@ mapping log_options[] = { }; -mapping log_maskmap[] = { - {"prach", DEBUG_PRACH}, - {"RU", DEBUG_RU}, - {"LTEESTIM", DEBUG_LTEESTIM}, - {"ctrlsocket", DEBUG_CTRLSOCKET}, - {"UE_PHYPROC", DEBUG_UE_PHYPROC}, - {"UE_TIMING", UE_TIMING}, - {NULL,-1} -}; +mapping log_maskmap[] = LOG_MASKMAP_INIT; -char *log_level_highlight_start[] = {LOG_RED, LOG_GREEN, LOG_ORANGE, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */ -char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ +char *log_level_highlight_start[] = {LOG_RED, LOG_ORANGE, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */ +char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ int write_file_matlab(const char *fname,const char *vname,void *data,int length,int dec,char format) @@ -243,14 +234,14 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length, /* get log parameters from configuration file */ void log_getconfig(log_t *g_log) { char *gloglevel = NULL; - int level; + int consolelog ; paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)]; - paramdef_t logparams_matlab[sizeof(log_maskmap)/sizeof(mapping)]; + paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)]; int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX); if (ret <0) { @@ -258,6 +249,7 @@ void log_getconfig(log_t *g_log) { return; } +/* set LOG display options (enable/disable color, thread name, level ) */ for(int i=0; i<logparams_defaults[LOG_OPTIONS_IDX].numelt ; i++) { for(int j=0; log_options[j].name != NULL ; j++) { if (strcmp(logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i],log_options[j].name) == 0) { @@ -303,38 +295,40 @@ void log_getconfig(log_t *g_log) { config_get( logparams_logfile, MAX_LOG_PREDEF_COMPONENTS,CONFIG_STRING_LOG_PREFIX); /* now set the log levels and infile option, according to what we read */ for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) { - level = map_str_to_int(log_level_names, *(logparams_level[i].strptr)); - set_log(i, level,1); + g_log->log_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr)); + set_log(i, g_log->log_component[i].level); if (*(logparams_logfile[i].uptr) == 1) set_component_filelog(i); } -/* build then read the debug and matlab parameter array */ +/* build then read the debug and dump parameter array */ for (int i=0;log_maskmap[i].name != NULL ; i++) { - sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name); - sprintf(logparams_matlab[i].optname, LOG_CONFIG_MATLAB_FORMAT, log_maskmap[i].name); + sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name); + sprintf(logparams_dump[i].optname, LOG_CONFIG_DUMP_FORMAT, log_maskmap[i].name); logparams_debug[i].defuintval = 0; logparams_debug[i].type = TYPE_UINT; logparams_debug[i].paramflags = PARAMFLAG_BOOL; logparams_debug[i].uptr = NULL; logparams_debug[i].chkPptr = NULL; logparams_debug[i].numelt = 0; - logparams_matlab[i].defuintval = 0; - logparams_matlab[i].type = TYPE_UINT; - logparams_matlab[i].paramflags = PARAMFLAG_BOOL; - logparams_matlab[i].uptr = NULL; - logparams_matlab[i].chkPptr = NULL; - logparams_matlab[i].numelt = 0; + logparams_dump[i].defuintval = 0; + logparams_dump[i].type = TYPE_UINT; + logparams_dump[i].paramflags = PARAMFLAG_BOOL; + logparams_dump[i].uptr = NULL; + logparams_dump[i].chkPptr = NULL; + logparams_dump[i].numelt = 0; } config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); - config_get( logparams_matlab,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); + config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); /* set the debug mask according to the debug parameters values */ for (int i=0; log_maskmap[i].name != NULL ; i++) { if (*(logparams_debug[i].uptr) ) g_log->debug_mask = g_log->debug_mask | log_maskmap[i].value; - if (*(logparams_matlab[i].uptr) ) - g_log->matlab_mask = g_log->matlab_mask | log_maskmap[i].value; + if (*(logparams_dump[i].uptr) ) + g_log->dump_mask = g_log->dump_mask | log_maskmap[i].value; } +/* log globally enabled/disabled */ + set_glog_onlinelog(consolelog); } int register_log_component(char *name, char *fext, int compidx) @@ -354,11 +348,9 @@ int computed_compidx=compidx; } if (computed_compidx >= 0 && computed_compidx <MAX_LOG_COMPONENTS) { g_log->log_component[computed_compidx].name = strdup(name); - g_log->log_component[computed_compidx].level = LOG_ERR; - g_log->log_component[computed_compidx].interval = 1; - g_log->log_component[computed_compidx].stream = NULL; + g_log->log_component[computed_compidx].stream = stdout; g_log->log_component[computed_compidx].filelog = 0; - g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s rounded to ^2 */ + g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/<name>.%s */ sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext); } else { fprintf(stderr,"{LOG} %s %d Couldn't register componemt %s\n",__FILE__,__LINE__,name); @@ -418,26 +410,20 @@ int logInit (void) register_log_component("S1AP","",S1AP); + register_log_component("X2AP","",X2AP); register_log_component("SCTP","",SCTP); - register_log_component("RRH","",RRH); - - + register_log_component("X2AP","",X2AP); + register_log_component("LOADER","log",LOADER); + register_log_component("ASN","log",ASN); + for (int i=0 ; log_level_names[i].name != NULL ; i++) + g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name - g_log->level2string[OAILOG_ERR] = "E"; // ERROR - g_log->level2string[OAILOG_WARNING] = "W"; // WARNING - g_log->level2string[OAILOG_INFO] = "I"; //INFO - g_log->level2string[OAILOG_DEBUG] = "D"; // DEBUG - g_log->level2string[OAILOG_FILE] = "F"; // file - g_log->level2string[OAILOG_TRACE] = "T"; // TRACE - - g_log->onlinelog = 1; //online log file - g_log->filelog = 0; @@ -446,19 +432,6 @@ int logInit (void) log_getconfig(g_log); - // 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].stream = fopen(g_log->log_component[i].filelog_name,"w"); - g_log->log_component[i].fwrite = vfprintf; - } else if (g_log->log_component[i].filelog == 1 ) { - g_log->log_component[i].stream = fopen(g_log->filelog_name,"w"); - g_log->log_component[i].fwrite = vfprintf; - } else if (g_log->onlinelog == 1 ) { - g_log->log_component[i].stream = stdout; - g_log->log_component[i].fwrite = vfprintf; - } - } // set all unused component items to 0, they are for non predefined components for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { @@ -470,8 +443,6 @@ int logInit (void) } - - char *log_getthreadname(char *threadname, int bufsize) { int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ; @@ -483,11 +454,20 @@ int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ; } } +static int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) { + char threadname[PR_SET_NAME]; +return snprintf(log_buffer, buffsize , "%s%s[%s]%c %s %s%s", + log_level_highlight_end[level], + ( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]), + g_log->log_component[comp].name, + ( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:' '), + ( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""), + format, + log_level_highlight_end[level]); +} void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char* format, ... ) { - - char threadname[PR_SET_NAME]; char log_buffer[MAX_LOG_TOTAL]; va_list args; @@ -496,38 +476,63 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, int le - - - snprintf(log_buffer, MAX_LOG_TOTAL , "%s%s[%s]%s %s %s", - log_level_highlight_end[level], - ( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]), - g_log->log_component[comp].name, - ( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:""), - ( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""), - format); - - g_log->log_component[comp].fwrite(g_log->log_component[comp].stream,log_buffer, args); + log_header(log_buffer,MAX_LOG_TOTAL ,comp, level,format); + g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args); va_end(args); } +void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ) { +va_list args; +char *wbuf; + + switch(datatype) { + case LOG_DUMP_DOUBLE: + wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL); + break; + case LOG_DUMP_CHAR: + default: + wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL); + break; + } + if (wbuf != NULL) { + va_start(args, format); + int pos=log_header(wbuf,MAX_LOG_TOTAL ,component, OAILOG_INFO,""); + int pos2=vsprintf(wbuf+pos,format, args); + pos=pos+pos2; + va_end(args); + + for (int i=0; i<buffsize; i++) { + switch(datatype) { + case LOG_DUMP_DOUBLE: + pos = pos + sprintf(wbuf+pos,"%04.4lf ", (double)((double *)buffer)[i]); + break; + case LOG_DUMP_CHAR: + default: + pos = pos + sprintf(wbuf+pos,"%02x ", (unsigned char)((unsigned char *)buffer)[i]); + break; + } + } + sprintf(wbuf+pos,"\n"); + g_log->log_component[component].print(g_log->log_component[component].stream,wbuf); + free(wbuf); + } +} -int set_log(int component, int level, int interval) +int set_log(int component, int level) { /* Checking parameters */ DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); - DevCheck((level < NUM_LOG_LEVEL) && (level >= OAILOG_ERR), level, NUM_LOG_LEVEL, + DevCheck((level < NUM_LOG_LEVEL) && (level >= OAILOG_DISABLE), level, NUM_LOG_LEVEL, OAILOG_ERR); - DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); + if ( g_log->log_component[component].level != OAILOG_DISABLE ) + g_log->log_component[component].savedlevel = g_log->log_component[component].level; g_log->log_component[component].level = level; - - g_log->log_component[component].interval = interval; - return 0; } @@ -536,32 +541,67 @@ int set_log(int component, int level, int interval) void set_glog(int level) { for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { - g_log->log_component[c].level = level; + set_log(c, level); } } void set_glog_onlinelog(int enable) { - g_log->onlinelog = enable; + for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { + if ( enable ) { + g_log->log_component[c].level = g_log->log_component[c].savedlevel; + g_log->log_component[c].vprint = vfprintf; + g_log->log_component[c].print = fprintf; + g_log->log_component[c].stream = stdout; + } else { + g_log->log_component[c].level = OAILOG_DISABLE; + } + } } void set_glog_filelog(int enable) { - g_log->filelog = enable; +static FILE *fptr; + + if ( enable ) { + fptr = fopen(g_log->filelog_name,"w"); + + for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { + close_component_filelog(c); + g_log->log_component[c].stream = fptr; + g_log->log_component[c].filelog = 1; + } + } else { + for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { + g_log->log_component[c].filelog = 0; + if (fptr != NULL) { + fclose(fptr); + } + g_log->log_component[c].stream = stdout; + } + } } 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].stream == NULL) { + if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) { g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w"); } - } + g_log->log_component[comp].vprint = vfprintf; + g_log->log_component[comp].print = fprintf; + g_log->log_component[comp].filelog = 1; +} +void close_component_filelog(int comp) +{ + g_log->log_component[comp].filelog = 0; + if (g_log->log_component[comp].stream != NULL && g_log->log_component[comp].stream != stdout ) { + fclose(g_log->log_component[comp].stream); + g_log->log_component[comp].stream = stdout; + } + g_log->log_component[comp].vprint = vfprintf; + g_log->log_component[comp].print = fprintf; + } - - /* * for the two functions below, the passed array must have a final entry @@ -616,15 +656,13 @@ int is_newline( char *str, int size) void logClean (void) { int i; - LOG_I(PHY,"\n"); + LOG_UI(PHY,"\n"); for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - if (g_log->log_component[i].stream != NULL) { - fclose(g_log->log_component[i].stream); - } + close_component_filelog(i); } } @@ -650,8 +688,8 @@ int test_log(void) LOG_D(MAC, "1 debug MAC \n"); LOG_W(MAC, "1 warning MAC \n"); - set_log(EMU, OAILOG_INFO, FLAG_ONLINE); - set_log(MAC, OAILOG_WARNING, 0); + set_log(EMU, OAILOG_INFO); + set_log(MAC, OAILOG_WARNING); LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); @@ -661,7 +699,7 @@ int test_log(void) LOG_I(MAC, "2 info MAC \n"); - set_log(MAC, OAILOG_NOTICE, 1); + set_log(MAC, OAILOG_NOTICE); LOG_ENTER(MAC); LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n", @@ -670,8 +708,8 @@ int test_log(void) LOG_W(MAC, "3 warning MAC \n"); LOG_I(MAC, "3 info MAC \n"); - set_log(MAC, LOG_DEBUG,1); - set_log(EMU, LOG_DEBUG,1); + set_log(MAC, LOG_DEBUG); + set_log(EMU, LOG_DEBUG); LOG_ENTER(MAC); LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n", @@ -681,8 +719,8 @@ int test_log(void) LOG_I(MAC, "4 info MAC \n"); - set_log(MAC, LOG_DEBUG,0); - set_log(EMU, LOG_DEBUG,0); + set_log(MAC, LOG_DEBUG); + set_log(EMU, LOG_DEBUG); LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); @@ -691,8 +729,8 @@ int test_log(void) LOG_I(MAC, "5 info MAC \n"); - set_log(MAC, LOG_TRACE,0X07F); - set_log(EMU, LOG_TRACE,0X07F); + set_log(MAC, LOG_TRACE); + set_log(EMU, LOG_TRACE); LOG_ENTER(MAC); LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n", diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 4a0552d4942843e5a453b6e2e0223ad0c5adf80e..767c1dbb356046a1eec1558fac95f44442d3019f 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -81,15 +81,14 @@ extern "C" { * @ingroup _macro * @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8 * @{*/ - -# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" fuctinalities */ -# define OAILOG_FILE 1 /*!< \brief important informational messages, but everything OK */ -# define OAILOG_WARNING 2 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */ -# define OAILOG_INFO 3 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */ -# define OAILOG_DEBUG 4 /*!< \brief first level debug-level messages, for developers , may impact real-time behavior */ -# define OAILOG_TRACE 5 /*!< \brief second level debug-level messages, for developers ,likely impact real-time behavior*/ - -#define NUM_LOG_LEVEL 6 /*!< \brief the number of message levels users have with LOG */ +# define OAILOG_DISABLE -1 /*!< \brief disable all LOG messages, cannot be used in LOG macros, use only in LOG module */ +# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" fuctinalities */ +# define OAILOG_WARNING 1 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */ +# define OAILOG_INFO 2 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */ +# define OAILOG_DEBUG 3 /*!< \brief first level debug-level messages, for developers , may impact real-time behavior */ +# define OAILOG_TRACE 4 /*!< \brief second level debug-level messages, for developers ,likely impact real-time behavior*/ + +#define NUM_LOG_LEVEL 5 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/ /* @}*/ @@ -128,21 +127,53 @@ extern "C" { /** @defgroup macros to identify a debug entity * @ingroup each macro is a bit mask where the unique bit set identifies an entity to be debugged - * it allows to dynamically activate or not blocks of code + * it allows to dynamically activate or not blocks of code. The LOG_MASKMAP_INIT macro + * is used to map a character string name to each debug bit, it allows to set or clear + * the corresponding bit via the defined name, from the configuration or from the telnet + * server. * @brief * @{*/ #define DEBUG_PRACH (1<<0) #define DEBUG_RU (1<<1) #define DEBUG_UE_PHYPROC (1<<2) #define DEBUG_LTEESTIM (1<<3) +#define DEBUG_DLCELLSPEC (1<<4) +#define DEBUG_ULSCH (1<<5) +#define DEBUG_RRC (1<<6) +#define DEBUG_PDCP (1<<7) +#define DEBUG_DFT (1<<8) +#define DEBUG_ASN1 (1<<9) #define DEBUG_CTRLSOCKET (1<<10) +#define DEBUG_SECURITY (1<<11) +#define DEBUG_NAS (1<<12) #define UE_TIMING (1<<20) -#define SET_LOG_DEBUG(O) g_log->debug_mask = (g_log->debug_mask | O) -#define CLEAR_LOG_DEBUG(O) g_log->debug_mask = (g_log->debug_mask & (~O)) -#define SET_LOG_MATLAB(O) g_log->matlab_mask = (g_log->matlab_mask | O) -#define CLEAR_LOG_MATLAB(O) g_log->matlab_mask = (g_log->matlab_mask & (~O)) +#define LOG_MASKMAP_INIT {\ + {"PRACH", DEBUG_PRACH},\ + {"RU", DEBUG_RU},\ + {"UE_PHYPROC", DEBUG_UE_PHYPROC},\ + {"LTEESTIM", DEBUG_LTEESTIM},\ + {"DLCELLSPEC", DEBUG_DLCELLSPEC},\ + {"ULSCH", DEBUG_ULSCH},\ + {"RRC", DEBUG_RRC},\ + {"PDCP", DEBUG_PDCP},\ + {"DFT", DEBUG_DFT},\ + {"ASN1", DEBUG_ASN1},\ + {"CTRLSOCKET", DEBUG_CTRLSOCKET},\ + {"SECURITY", DEBUG_SECURITY},\ + {"NAS", DEBUG_NAS},\ + {"UE_TIMING", UE_TIMING},\ + {NULL,-1}\ +} + + + +#define SET_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask | B) +#define CLEAR_LOG_DEBUG(B) g_log->debug_mask = (g_log->debug_mask & (~B)) + +#define SET_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask | B) +#define CLEAR_LOG_DUMP(B) g_log->dump_mask = (g_log->dump_mask & (~B)) @@ -183,9 +214,9 @@ typedef enum { TMR, USIM, LOCALIZE, - RRH, X2AP, LOADER, + ASN, MAX_LOG_PREDEF_COMPONENTS, } comp_name_t; @@ -199,17 +230,18 @@ typedef struct { int value; /*!< \brief integer value of mapping */ } mapping; -typedef int(*log_write_func_t)(FILE *stream, const char *format, va_list ap ); - +typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap ); +typedef int(*log_print_func_t)(FILE *stream, const char *format, ... ); typedef struct { - const char *name; - int level; - int flag; - int interval; - int filelog; - char *filelog_name; - FILE *stream; - log_write_func_t fwrite; + const char *name; + int level; + int savedlevel; + int flag; + int filelog; + char *filelog_name; + FILE *stream; + log_vprint_func_t vprint; + log_print_func_t print; /* SR: make the log buffer component relative */ char log_buffer[MAX_LOG_TOTAL]; } log_component_t; @@ -217,13 +249,11 @@ typedef struct { typedef struct { log_component_t log_component[MAX_LOG_COMPONENTS]; - char* level2string[NUM_LOG_LEVEL]; - int onlinelog; + char level2string[NUM_LOG_LEVEL]; int flag; - int filelog; char* filelog_name; uint64_t debug_mask; - uint64_t matlab_mask; + uint64_t dump_mask; } log_t; @@ -254,14 +284,15 @@ extern log_t *g_log; /*----------------------------------------------------------------------------*/ int logInit (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); - -int set_log(int component, int level, int interval); +void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ); +int set_log(int component, int level); void set_glog(int level); void set_glog_onlinelog(int enable); void set_glog_filelog(int enable); void set_component_filelog(int comp); - +void close_component_filelog(int comp); +void set_component_consolelog(int comp); int map_str_to_int(mapping *map, const char *str); char *map_int_to_str(mapping *map, int val); void logClean (void); @@ -293,7 +324,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define LOG_CONFIG_LEVEL_FORMAT "%s_log_level" #define LOG_CONFIG_LOGFILE_FORMAT "%s_log_infile" #define LOG_CONFIG_DEBUG_FORMAT "%s_debug" -#define LOG_CONFIG_MATLAB_FORMAT "%s_matlab" +#define LOG_CONFIG_DUMP_FORMAT "%s_dump" #define LOG_CONFIG_HELP_OPTIONS " list of comma separated options to enable log module behavior. Available options: \n"\ " nocolor: disable color usage in log messages\n"\ @@ -309,7 +340,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOG_GLOBALPARAMS_DESC { \ {LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ -{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(g_log->onlinelog), defintval:1, TYPE_INT, 0}, \ +{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ {LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \ } @@ -319,23 +350,25 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int * @ingroup _macro * @brief Macro used to call logIt function with different message levels * @{*/ - -// debugging macros(g_log->log_component[component].interval?logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) +#define LOG_DUMP_CHAR 0 +#define LOG_DUMP_DOUBLE 1 +// 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 */ -# 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) -# 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_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) # define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0) # define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0) -# define LOG_F(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_FILE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_FILE, x) ;}} 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) /* */ # define nfapi_log(FILE, FNC, LN, COMP, LVL, F...) do { if (T_stdout) { logRecord_mt(__FILE__, __FUNCTION__, __LINE__,COMP, LVL, F) ;}} while (0) /* */ /* bitmask dependant macros, to isolate debugging code */ -# define LOG_DEBUG_BEGIN(D) if (g_log->debug_mask & D) { -# define LOG_DEBUG_END } - /* bitmask dependant macros, to generate matlab files */ -# define LOG_M_BEGIN(D) if (g_log->matlab_mask & D) { -# define LOG_M_END } +# define LOG_DEBUGFLAG(D) (g_log->debug_mask & D) + + /* bitmask dependant 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 */ # define LOG_VAR(A,B) A B @@ -345,22 +378,22 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_E(c, x...) /* */ # define LOG_D(c, x...) /* */ # define LOG_T(c, x...) /* */ -# define LOG_F(c, x...) /* */ + +# define LOG_DUMPMSG(c, b, s, x...) /* */ # define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) -# define LOG_DEBUG_BEGIN(D) if (0) { -# define LOG_DEBUG_END } -# define LOG_M_BEGIN(D) if (0) { -# define LOG_M_END } +# define LOG_DEBUGFLAG(D) ( 0 ) +# define LOG_DUMPFLAG(D) ( 0 ) # define LOG_M(file, vector, data, len, dec, format) # define LOG_VAR(A,B) # endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ -#define LOG_USEDINLOG_VAR(A,B) __attribute__((unused)) A B +#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 */ #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) /* */ /* @}*/ @@ -368,9 +401,12 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int * @ingroup _macro * @brief Macro of some useful functions defined by LOG * @{*/ -#define LOG_ENTER(c) do {LOG_T(c, "Entering\n");}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */ -#define LOG_EXIT(c) do {LOG_T(c,"Exiting\n"); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */ -#define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ +#define LOG_ENTER(c) do {LOG_T(c, "Entering %s\n",__FUNCTION__);}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */ +#define LOG_END(c) do {LOG_T(c, "End of %s\n",__FUNCTION__);}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */ +#define LOG_EXIT(c) do { LOG_END(c); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */ +#define LOG_RETURN(c,r) do {LOG_T(c,"Leaving %s (rc = %08lx)\n", __FUNCTION__ , (unsigned long)(r) );return(r);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ + + /* @}*/ static __inline__ uint64_t rdtsc(void) { diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 607fe857031ca1a06ea747bae8e1b36d26396c11..666bf46d44135b7a6cb233032426e24f438e38f1 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -44,7 +44,6 @@ #include <unistd.h> #include "assertions.h" -#include "signals.h" #include "vcd_signal_dumper.h" diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 676f329a0eb08fc4c2fb8e4efb2c69345e671f0e..2bce891ac93c425321f5aa05580498c7e1b9b4b3 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -750,6 +750,27 @@ ID = LEGACY_OSA_TRACE GROUP = ALL:LEGACY_OSA:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_ASN_INFO + DESC = ASN legacy logs - info level + GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_ASN_ERROR + DESC = ASN legacy logs - error level + GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_ASN_WARNING + DESC = ASN legacy logs - warning level + GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_ASN_DEBUG + DESC = ASN legacy logs - debug level + GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_ASN_TRACE + DESC = ASN legacy logs - trace level + GROUP = ALL:LEGACY_ASN:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_SIM_INFO DESC = SIM legacy logs - info level GROUP = ALL:LEGACY_SIM:LEGACY_GROUP_INFO:LEGACY diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 9c7456b5cdc7663bcb36e18c012d31624107cec4..7b8c130ea868ead1e78ee76fb732707d54c41b40 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -150,7 +150,17 @@ x_image *x_create_image(x_connection *_x, unsigned char *data, vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask | VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask | VisualBitsPerRGBMask, &template, &nvs); - if (vs == NULL || nvs == 0) ERR("no good visual found\n"); + + if (vs == NULL) { + /* try again with 32 bpp */ + template.depth = 32; + vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask | + VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask | + VisualBitsPerRGBMask, &template, &nvs); + } + + if (vs == NULL) ERR("no good visual found\n"); + v = vs[0].visual; XFree(vs); diff --git a/common/utils/assertions.h b/common/utils/assertions.h index f6728caf7bb5ee213b4f1c8b175c911d92a8962d..b872b009e258408e799f6dfaaf0cc2697c1913f4 100644 --- a/common/utils/assertions.h +++ b/common/utils/assertions.h @@ -19,9 +19,72 @@ * contact@openairinterface.org */ -#ifndef UTILS_ASSERTIONS_H_ -#define UTILS_ASSERTIONS_H_ +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> +#ifdef CMAKER +#include <platform_types.h> +#endif -#include "./itti/assertions.h" +#if defined(ENB_MODE) +# define display_backtrace() +#else +# include "backtrace.h" +#endif -#endif /* UTILS_ASSERTIONS_H_ */ +#ifndef ASSERTIONS_H_ +#define ASSERTIONS_H_ + +void output_log_mem(void); +#define _Assert_Exit_ \ +{ \ + fprintf(stderr, "\nExiting execution\n"); \ + display_backtrace(); \ + fflush(stdout); \ + fflush(stderr); \ + exit(EXIT_FAILURE); \ +} + +#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \ +do { \ + if (!(cOND)) { \ + fprintf(stderr, "\nAssertion ("#cOND") failed!\n" \ + "In %s() %s:%d\n" fORMAT, \ + __FUNCTION__, __FILE__, __LINE__, ##aRGS); \ + aCTION; \ + } \ +} while(0) + +#define AssertFatal(cOND, fORMAT, aRGS...) _Assert_(cOND, _Assert_Exit_, fORMAT, ##aRGS) + +#define AssertError(cOND, aCTION, fORMAT, aRGS...) _Assert_(cOND, aCTION, fORMAT, ##aRGS) + + + +#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \ +_Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n\n", \ + (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3) + +#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \ +_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \ + (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4) + +#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3) + +#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "") + +#define DevMessage(mESSAGE) _Assert_(0, _Assert_Exit_, #mESSAGE) + +#define CHECK_INIT_RETURN(fCT) \ +do { \ + int fct_ret; \ + if ((fct_ret = (fCT)) != 0) { \ + fprintf(stderr, "Function "#fCT" has failed\n" \ + "returning %d\n", fct_ret); \ + fflush(stdout); \ + fflush(stderr); \ + exit(EXIT_FAILURE); \ + } \ +} while(0) + +#endif /* ASSERTIONS_H_ */ diff --git a/common/utils/itti/backtrace.c b/common/utils/backtrace.c similarity index 100% rename from common/utils/itti/backtrace.c rename to common/utils/backtrace.c diff --git a/common/utils/itti/backtrace.h b/common/utils/backtrace.h similarity index 100% rename from common/utils/itti/backtrace.h rename to common/utils/backtrace.h diff --git a/common/utils/itti/Makefile.am b/common/utils/itti/Makefile.am deleted file mode 100644 index 93f57046032a3db9fea32c30b12488a59da1e0c2..0000000000000000000000000000000000000000 --- a/common/utils/itti/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -AM_CFLAGS = @ADD_CFLAGS@ \ - -I$(top_srcdir)/UTILS \ - -I$(top_srcdir)/COMMON \ - -I$(OPENAIR2_DIR)/UTIL/LFDS/liblfds6.1.1/liblfds611/inc \ - -DENABLE_EVENT_FD - -noinst_LTLIBRARIES = libitti.la - -BUILT_SOURCES = $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin/liblfds611.a - -$(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin/liblfds611.a: - @if [ ! -d $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin ]; then mkdir -p $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin; fi; - @if [ ! -d $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/obj ]; then mkdir -p $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/obj; fi; - @$(MAKE) -C $(OPENAIR2_DIR)/UTIL/LFDS/liblfds6.1.1/liblfds611/ -f makefile.linux OUTDIR=$(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611 - -libitti_la_LDFLAGS = -all-static -libitti_la_SOURCES = \ - gtpv1_u_messages_def.h gtpv1_u_messages_types.h \ - nas_messages_def.h nas_messages_types.h \ - timer_messages_def.h timer_messages_types.h \ - s11_messages_def.h s11_messages_types.h \ - s1ap_messages_def.h s1ap_messages_types.h \ - s6a_messages_def.h s6a_messages_types.h \ - sgw_lite_def.h sgw_lite_messages_types.h \ - sctp_messages_def.h sctp_messages_types.h \ - udp_message_def.h udp_messages_types.h \ - intertask_interface.c intertask_interface.h \ - intertask_interface_dump.c intertask_interface_dump.h \ - assertions.h \ - backtrace.c backtrace.h \ - signals.c signals.h \ - timer.c timer.h diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h deleted file mode 100644 index b872b009e258408e799f6dfaaf0cc2697c1913f4..0000000000000000000000000000000000000000 --- a/common/utils/itti/assertions.h +++ /dev/null @@ -1,90 +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 - */ - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> -#ifdef CMAKER -#include <platform_types.h> -#endif - -#if defined(ENB_MODE) -# define display_backtrace() -#else -# include "backtrace.h" -#endif - -#ifndef ASSERTIONS_H_ -#define ASSERTIONS_H_ - -void output_log_mem(void); -#define _Assert_Exit_ \ -{ \ - fprintf(stderr, "\nExiting execution\n"); \ - display_backtrace(); \ - fflush(stdout); \ - fflush(stderr); \ - exit(EXIT_FAILURE); \ -} - -#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \ -do { \ - if (!(cOND)) { \ - fprintf(stderr, "\nAssertion ("#cOND") failed!\n" \ - "In %s() %s:%d\n" fORMAT, \ - __FUNCTION__, __FILE__, __LINE__, ##aRGS); \ - aCTION; \ - } \ -} while(0) - -#define AssertFatal(cOND, fORMAT, aRGS...) _Assert_(cOND, _Assert_Exit_, fORMAT, ##aRGS) - -#define AssertError(cOND, aCTION, fORMAT, aRGS...) _Assert_(cOND, aCTION, fORMAT, ##aRGS) - - - -#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \ -_Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n\n", \ - (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3) - -#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \ -_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \ - (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4) - -#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3) - -#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "") - -#define DevMessage(mESSAGE) _Assert_(0, _Assert_Exit_, #mESSAGE) - -#define CHECK_INIT_RETURN(fCT) \ -do { \ - int fct_ret; \ - if ((fct_ret = (fCT)) != 0) { \ - fprintf(stderr, "Function "#fCT" has failed\n" \ - "returning %d\n", fct_ret); \ - fflush(stdout); \ - fflush(stderr); \ - exit(EXIT_FAILURE); \ - } \ -} while(0) - -#endif /* ASSERTIONS_H_ */ diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c deleted file mode 100644 index d088b59c041b8abeaf2408f0369a98588574537a..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface.c +++ /dev/null @@ -1,930 +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 - */ - -#define _GNU_SOURCE -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <signal.h> - -#include <sys/epoll.h> -#include <sys/eventfd.h> - -#if !defined(TRUE) -#define TRUE 1 -#endif - -#include "liblfds611.h" - -#include "assertions.h" -#include "intertask_interface.h" - -#if T_TRACER -#include "T.h" -#endif - -/* Includes "intertask_interface_init.h" to check prototype coherence, but - * disable threads and messages information generation. - */ -#define CHECK_PROTOTYPE_ONLY -#include "intertask_interface_init.h" -#undef CHECK_PROTOTYPE_ONLY - -#include "signals.h" -#include "timer.h" - -/* ITTI DEBUG groups */ -#define ITTI_DEBUG_POLL (1<<0) -#define ITTI_DEBUG_SEND (1<<1) -#define ITTI_DEBUG_EVEN_FD (1<<2) -#define ITTI_DEBUG_INIT (1<<3) -#define ITTI_DEBUG_EXIT (1<<4) -#define ITTI_DEBUG_ISSUES (1<<5) -#define ITTI_DEBUG_MP_STATISTICS (1<<6) - -const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS); - -# define ITTI_DEBUG(m, x, args...) do { if ((m) & itti_debug) {fprintf(stdout, "[ITTI][D]"x, ##args); fflush (stdout);} } while(0); -#define ITTI_ERROR(x, args...) do { fprintf(stdout, "[ITTI][E]"x, ##args); fflush (stdout); } while(0); - -/* Global message size */ -#define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size) - - -extern int emulate_rf; - -typedef enum task_state_s { - TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX, -} task_state_t; - -/* This list acts as a FIFO of messages received by tasks (RRC, NAS, ...) */ -typedef struct message_list_s { - MessageDef *msg; ///< Pointer to the message - - message_number_t message_number; ///< Unique message number - uint32_t message_priority; ///< Message priority -} message_list_t; - -typedef struct thread_desc_s { - /* pthread associated with the thread */ - pthread_t task_thread; - - /* State of the thread */ - volatile task_state_t task_state; - - /* This fd is used internally by ITTI. */ - int epoll_fd; - - /* The thread fd */ - int task_event_fd; - - /* Number of events to monitor */ - uint16_t nb_events; - - - /* Array of events monitored by the task. - * By default only one fd is monitored (the one used to received messages - * from other tasks). - * More events can be suscribed later by the task itself. - */ - struct epoll_event *events; - - int epoll_nb_events; - - /* Flag to mark real time thread */ - unsigned real_time; - - /* Counter to indicate that messages are pending for the thread */ - unsigned messages_pending; -} thread_desc_t; - -typedef struct task_desc_s { - /* Queue of messages belonging to the task */ - struct lfds611_queue_state *message_queue; -} task_desc_t; - -typedef struct itti_desc_s { - thread_desc_t *threads; - task_desc_t *tasks; - - /* Current message number. Incremented every call to send_msg_to_task */ - message_number_t message_number __attribute__((aligned(8))); - - thread_id_t thread_max; - task_id_t task_max; - MessagesIds messages_id_max; - - boolean_t thread_handling_signals; - pthread_t thread_ref; - - const task_info_t *tasks_info; - const message_info_t *messages_info; - - itti_lte_time_t lte_time; - - int running; - - volatile uint32_t created_tasks; - volatile uint32_t ready_tasks; - volatile int wait_tasks; -} itti_desc_t; - -static itti_desc_t itti_desc; - -void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size) -{ - void *ptr = NULL; - - ptr = malloc (size); - if (ptr) memset(ptr,0,size); - - AssertFatal (ptr != NULL, "Memory allocation of %d bytes failed (%d -> %d)!\n", (int) size, origin_task_id, destination_task_id); - - return ptr; -} - -int itti_free(task_id_t task_id, void *ptr) -{ - int result = EXIT_SUCCESS; - AssertFatal (ptr != NULL, "Trying to free a NULL pointer (%d)!\n", task_id); - - free (ptr); - - return (result); -} - -static inline message_number_t itti_increment_message_number(void) -{ - /* Atomic operation supported by GCC: returns the current message number - * and then increment it by 1. - * This can be done without mutex. - */ - return __sync_fetch_and_add (&itti_desc.message_number, 1); -} - -static inline uint32_t itti_get_message_priority(MessagesIds message_id) -{ - AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); - - return (itti_desc.messages_info[message_id].priority); -} - -const char *itti_get_message_name(MessagesIds message_id) -{ - AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); - - return (itti_desc.messages_info[message_id].name); -} - -const char *itti_get_task_name(task_id_t task_id) -{ - if (itti_desc.task_max > 0) { - AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max); - } else { - return ("ITTI NOT INITIALIZED !!!"); - } - - return (itti_desc.tasks_info[task_id].name); -} - -static task_id_t itti_get_current_task_id(void) -{ - task_id_t task_id; - thread_id_t thread_id; - pthread_t thread = pthread_self (); - - for (task_id = TASK_FIRST; task_id < itti_desc.task_max; task_id++) { - thread_id = TASK_GET_THREAD_ID(task_id); - - if (itti_desc.threads[thread_id].task_thread == thread) { - return task_id; - } - } - - return TASK_UNKNOWN; -} - -void itti_update_lte_time(uint32_t frame, uint8_t slot) -{ - itti_desc.lte_time.frame = frame; - itti_desc.lte_time.slot = slot; -} - -int itti_send_broadcast_message(MessageDef *message_p) -{ - task_id_t destination_task_id; - task_id_t origin_task_id; - thread_id_t origin_thread_id; - uint32_t thread_id; - int ret = 0; - int result; - - AssertFatal (message_p != NULL, "Trying to broadcast a NULL message!\n"); - - origin_task_id = message_p->ittiMsgHeader.originTaskId; - origin_thread_id = TASK_GET_THREAD_ID(origin_task_id); - - destination_task_id = TASK_FIRST; - - for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) { - MessageDef *new_message_p; - - while (thread_id != TASK_GET_THREAD_ID(destination_task_id)) { - destination_task_id++; - } - - /* Skip task that broadcast the message */ - if (thread_id != origin_thread_id) { - /* Skip tasks which are not running */ - if (itti_desc.threads[thread_id].task_state == TASK_STATE_READY) { - size_t size = sizeof(MessageHeader) + message_p->ittiMsgHeader.ittiMsgSize; - new_message_p = itti_malloc( origin_task_id, destination_task_id, size ); - AssertFatal (new_message_p != NULL, "New message allocation failed!\n"); - - memcpy( new_message_p, message_p, size ); - result = itti_send_msg_to_task (destination_task_id, INSTANCE_DEFAULT, new_message_p); - AssertFatal (result >= 0, "Failed to send message %d to thread %d (task %d)!\n", message_p->ittiMsgHeader.messageId, thread_id, destination_task_id); - } - } - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - - return ret; -} - -MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size) -{ - MessageDef *temp = NULL; - - AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); - - if (origin_task_id == TASK_UNKNOWN) { - /* Try to identify real origin task ID */ - origin_task_id = itti_get_current_task_id(); - } - - temp = itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) + size); - - temp->ittiMsgHeader.messageId = message_id; - temp->ittiMsgHeader.originTaskId = origin_task_id; - temp->ittiMsgHeader.ittiMsgSize = size; - - return temp; -} - -MessageDef *itti_alloc_new_message(task_id_t origin_task_id, MessagesIds message_id) -{ - return itti_alloc_new_message_sized(origin_task_id, message_id, itti_desc.messages_info[message_id].size); -} - -int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) -{ - thread_id_t destination_thread_id; - task_id_t origin_task_id; - message_list_t *new; - uint32_t priority; - message_number_t message_number; - uint32_t message_id; - - AssertFatal (message != NULL, "Message is NULL!\n"); - AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max); - - destination_thread_id = TASK_GET_THREAD_ID(destination_task_id); - message->ittiMsgHeader.destinationTaskId = destination_task_id; - message->ittiMsgHeader.instance = instance; - message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame; - message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot; - message_id = message->ittiMsgHeader.messageId; - AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); - - origin_task_id = ITTI_MSG_ORIGIN_ID(message); - - priority = itti_get_message_priority (message_id); - - /* Increment the global message number */ - message_number = itti_increment_message_number (); - - if (destination_task_id != TASK_UNKNOWN) { - - if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED || - itti_desc.threads[destination_thread_id].task_state == TASK_STATE_NOT_CONFIGURED) { - ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), unconfigured or ended destination task!\n", - itti_desc.messages_info[message_id].name, - message_number, - priority, - itti_get_task_name(origin_task_id), - destination_task_id, - itti_get_task_name(destination_task_id)); - } else { - if(!emulate_rf){ - /* We cannot send a message if the task is not running */ - AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY, - "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n", - itti_get_task_name(origin_task_id), - itti_desc.messages_info[message_id].name, - message_id, - destination_thread_id, - itti_desc.threads[destination_thread_id].task_state); - } - - /* Allocate new list element */ - new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s)); - - /* Fill in members */ - new->msg = message; - new->message_number = message_number; - new->message_priority = priority; - - /* Enqueue message in destination task queue */ - if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { - AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n"); - } - - { - /* Only use event fd for tasks, subtasks will pool the queue */ - if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) { - ssize_t write_ret; - eventfd_t sem_counter = 1; - - /* Call to write for an event fd must be of 8 bytes */ - write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); - AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n", - destination_thread_id, (int) write_ret, (int) sizeof(sem_counter)); - } - } - - ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n", - itti_desc.messages_info[message_id].name, - message_number, - priority, - itti_get_task_name(origin_task_id), - destination_task_id, - itti_get_task_name(destination_task_id)); - } - } else { - /* This is a debug message to TASK_UNKNOWN, we can release safely release it */ - int result = itti_free(origin_task_id, message); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - - return 0; -} - -/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */ -/* TODO: this is a hack - the whole logic needs a proper rework. */ -/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ -int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) -{ - thread_id_t destination_thread_id; - task_id_t origin_task_id; - message_list_t *new; - uint32_t priority; - message_number_t message_number; - uint32_t message_id; - - AssertFatal (message != NULL, "Message is NULL!\n"); - AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max); - - destination_thread_id = TASK_GET_THREAD_ID(destination_task_id); - message->ittiMsgHeader.destinationTaskId = destination_task_id; - message->ittiMsgHeader.instance = instance; - message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame; - message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot; - message_id = message->ittiMsgHeader.messageId; - AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); - - origin_task_id = ITTI_MSG_ORIGIN_ID(message); - - priority = itti_get_message_priority (message_id); - - /* Increment the global message number */ - message_number = itti_increment_message_number (); - - if (destination_task_id != TASK_UNKNOWN) { - - if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED || - itti_desc.threads[destination_thread_id].task_state == TASK_STATE_NOT_CONFIGURED) { - ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), unconfigured or ended destination task!\n", - itti_desc.messages_info[message_id].name, - message_number, - priority, - itti_get_task_name(origin_task_id), - destination_task_id, - itti_get_task_name(destination_task_id)); - } else { - /* We cannot send a message if the task is not running */ - AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY, - "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n", - itti_get_task_name(origin_task_id), - itti_desc.messages_info[message_id].name, - message_id, - destination_thread_id, - itti_desc.threads[destination_thread_id].task_state); - - /* Allocate new list element */ - new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s)); - - /* Fill in members */ - new->msg = message; - new->message_number = message_number; - new->message_priority = priority; - - /* Enqueue message in destination task queue */ - if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { - itti_free(origin_task_id, new); - return -1; - } - - { - /* Only use event fd for tasks, subtasks will pool the queue */ - if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) { - ssize_t write_ret; - eventfd_t sem_counter = 1; - - /* Call to write for an event fd must be of 8 bytes */ - write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); - AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n", - destination_thread_id, (int) write_ret, (int) sizeof(sem_counter)); - } - } - - ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n", - itti_desc.messages_info[message_id].name, - message_number, - priority, - itti_get_task_name(origin_task_id), - destination_task_id, - itti_get_task_name(destination_task_id)); - } - } else { - /* This is a debug message to TASK_UNKNOWN, we can release safely release it */ - int result = itti_free(origin_task_id, message); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - - return 0; -} - -void itti_subscribe_event_fd(task_id_t task_id, int fd) -{ - thread_id_t thread_id; - struct epoll_event event; - - AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max); - - thread_id = TASK_GET_THREAD_ID(task_id); - itti_desc.threads[thread_id].nb_events++; - - /* Reallocate the events */ - itti_desc.threads[thread_id].events = realloc( - itti_desc.threads[thread_id].events, - itti_desc.threads[thread_id].nb_events * sizeof(struct epoll_event)); - - event.events = EPOLLIN | EPOLLERR; - event.data.u64 = 0; - event.data.fd = fd; - - /* Add the event fd to the list of monitored events */ - if (epoll_ctl(itti_desc.threads[thread_id].epoll_fd, EPOLL_CTL_ADD, fd, - &event) != 0) { - /* Always assert on this condition */ - AssertFatal (0, "epoll_ctl (EPOLL_CTL_ADD) failed for task %s, fd %d: %s!\n", - itti_get_task_name(task_id), fd, strerror(errno)); - } - - ITTI_DEBUG(ITTI_DEBUG_EVEN_FD, " Successfully subscribed fd %d for task %s\n", fd, itti_get_task_name(task_id)); -} - -void itti_unsubscribe_event_fd(task_id_t task_id, int fd) -{ - thread_id_t thread_id; - - AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max); - AssertFatal (fd >= 0, "File descriptor (%d) is invalid!\n", fd); - - thread_id = TASK_GET_THREAD_ID(task_id); - - /* Add the event fd to the list of monitored events */ - if (epoll_ctl(itti_desc.threads[thread_id].epoll_fd, EPOLL_CTL_DEL, fd, NULL) != 0) { - /* Always assert on this condition */ - AssertFatal (0, "epoll_ctl (EPOLL_CTL_DEL) failed for task %s, fd %d: %s!\n", - itti_get_task_name(task_id), fd, strerror(errno)); - } - - itti_desc.threads[thread_id].nb_events--; - itti_desc.threads[thread_id].events = realloc( - itti_desc.threads[thread_id].events, - itti_desc.threads[thread_id].nb_events * sizeof(struct epoll_event)); -} - -int itti_get_events(task_id_t task_id, struct epoll_event **events) -{ - thread_id_t thread_id; - - AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)\n", task_id, itti_desc.task_max); - - thread_id = TASK_GET_THREAD_ID(task_id); - *events = itti_desc.threads[thread_id].events; - - return itti_desc.threads[thread_id].epoll_nb_events; -} - -static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t polling, MessageDef **received_msg) -{ - thread_id_t thread_id; - int epoll_ret = 0; - int epoll_timeout = 0; - int i; - - AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max); - AssertFatal (received_msg != NULL, "Received message is NULL!\n"); - - thread_id = TASK_GET_THREAD_ID(task_id); - *received_msg = NULL; - - if (polling) { - /* In polling mode we set the timeout to 0 causing epoll_wait to return - * immediately. - */ - epoll_timeout = 0; - } else { - /* timeout = -1 causes the epoll_wait to wait indefinitely. - */ - epoll_timeout = -1; - } - - do { - epoll_ret = epoll_wait(itti_desc.threads[thread_id].epoll_fd, - itti_desc.threads[thread_id].events, - itti_desc.threads[thread_id].nb_events, - epoll_timeout); - } while (epoll_ret < 0 && errno == EINTR); - - if (epoll_ret < 0) { - AssertFatal (0, "epoll_wait failed for task %s: %s!\n", itti_get_task_name(task_id), strerror(errno)); - } - - if (epoll_ret == 0 && polling) { - /* No data to read -> return */ - return; - } - - itti_desc.threads[thread_id].epoll_nb_events = epoll_ret; - - for (i = 0; i < epoll_ret; i++) { - /* Check if there is an event for ITTI for the event fd */ - if ((itti_desc.threads[thread_id].events[i].events & EPOLLIN) && - (itti_desc.threads[thread_id].events[i].data.fd == itti_desc.threads[thread_id].task_event_fd)) { - struct message_list_s *message = NULL; - eventfd_t sem_counter; - ssize_t read_ret; - int result; - - /* Read will always return 1 */ - read_ret = read (itti_desc.threads[thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); - AssertFatal (read_ret == sizeof(sem_counter), "Read from task message FD (%d) failed (%d/%d)!\n", thread_id, (int) read_ret, (int) sizeof(sem_counter)); - - if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) { - /* No element in list -> this should not happen */ - AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret); - } - - AssertFatal(message != NULL, "Message from message queue is NULL!\n"); - *received_msg = message->msg; - - - result = itti_free (ITTI_MSG_ORIGIN_ID(*received_msg), message); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - - - /* Mark that the event has been processed */ - itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN; - return; - } - } -} - -void itti_receive_msg(task_id_t task_id, MessageDef **received_msg) -{ - - itti_receive_msg_internal_event_fd(task_id, 0, received_msg); - -} - -void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) -{ - AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max); - - *received_msg = NULL; - - { - struct message_list_s *message; - - if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 1) { - int result; - - *received_msg = message->msg; - result = itti_free (ITTI_MSG_ORIGIN_ID(*received_msg), message); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - } - - if (*received_msg == NULL) { - ITTI_DEBUG(ITTI_DEBUG_POLL, " No message in queue[(%u:%s)]\n", task_id, itti_get_task_name(task_id)); - } - -} - -int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) -{ - thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); - int result; - - AssertFatal (start_routine != NULL, "Start routine is NULL!\n"); - AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max); - AssertFatal (itti_desc.threads[thread_id].task_state == TASK_STATE_NOT_CONFIGURED, "Task %d, thread %d state is not correct (%d)!\n", - task_id, thread_id, itti_desc.threads[thread_id].task_state); - - itti_desc.threads[thread_id].task_state = TASK_STATE_STARTING; - - ITTI_DEBUG(ITTI_DEBUG_INIT, " Creating thread for task %s ...\n", itti_get_task_name(task_id)); - - result = pthread_create (&itti_desc.threads[thread_id].task_thread, NULL, start_routine, args_p); - AssertFatal (result >= 0, "Thread creation for task %d, thread %d failed (%d)!\n", task_id, thread_id, result); - char name[16]; - snprintf( name, sizeof(name), "ITTI %d", thread_id ); - pthread_setname_np( itti_desc.threads[thread_id].task_thread, name ); - - itti_desc.created_tasks ++; - - /* Wait till the thread is completely ready */ - while (itti_desc.threads[thread_id].task_state != TASK_STATE_READY) - usleep (1000); - - return 0; -} - -void itti_set_task_real_time(task_id_t task_id) -{ - thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); - - DevCheck(thread_id < itti_desc.thread_max, thread_id, itti_desc.thread_max, 0); - - itti_desc.threads[thread_id].real_time = TRUE; -} - -void itti_wait_ready(int wait_tasks) -{ - itti_desc.wait_tasks = wait_tasks; - - ITTI_DEBUG(ITTI_DEBUG_INIT, - " wait for tasks: %s, created tasks %d, ready tasks %d\n", - itti_desc.wait_tasks ? "yes" : "no", - itti_desc.created_tasks, - itti_desc.ready_tasks); - - AssertFatal (itti_desc.created_tasks == itti_desc.ready_tasks, "Number of created tasks (%d) does not match ready tasks (%d), wait task %d!\n", - itti_desc.created_tasks, itti_desc.ready_tasks, itti_desc.wait_tasks); -} - -void itti_mark_task_ready(task_id_t task_id) -{ - thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); - - AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max); - - /* Mark the thread as using LFDS queue */ - lfds611_queue_use(itti_desc.tasks[task_id].message_queue); - -#if defined(UE_EXPANSION) || defined(RTAI) - /* Assign low priority to created threads */ - { - struct sched_param sched_param; - sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1; - sched_setscheduler(0, SCHED_FIFO, &sched_param); - } -#endif - - itti_desc.threads[thread_id].task_state = TASK_STATE_READY; - itti_desc.ready_tasks ++; - - while (itti_desc.wait_tasks != 0) { - usleep (10000); - } - - ITTI_DEBUG(ITTI_DEBUG_INIT, " task %s started\n", itti_get_task_name(task_id)); -} - -void itti_exit_task(void) -{ - task_id_t task_id = itti_get_current_task_id(); - thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); - -#if defined(OAI_EMU) || defined(RTAI) - if (task_id > TASK_UNKNOWN) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_ITTI_RECV_MSG, - __sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id))); - } -#endif - - itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED; - itti_desc.created_tasks--; - ITTI_DEBUG(ITTI_DEBUG_EXIT, "Thread for task %s (%d) exits\n", itti_get_task_name(task_id), task_id); - pthread_exit (NULL); -} - -void itti_terminate_tasks(task_id_t task_id) -{ - // Sends Terminate signals to all tasks. - itti_send_terminate_message (task_id); - - if (itti_desc.thread_handling_signals) { - pthread_kill (itti_desc.thread_ref, SIGUSR1); - } - - pthread_exit (NULL); -} - -int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, - const message_info_t *messages_info) -{ - task_id_t task_id; - thread_id_t thread_id; - int ret; - - itti_desc.message_number = 1; - - ITTI_DEBUG(ITTI_DEBUG_INIT, " Init: %d tasks, %d threads, %d messages\n", task_max, thread_max, messages_id_max); - - CHECK_INIT_RETURN(signal_mask()); - - /* Saves threads and messages max values */ - itti_desc.task_max = task_max; - itti_desc.thread_max = thread_max; - itti_desc.messages_id_max = messages_id_max; - itti_desc.thread_handling_signals = FALSE; - itti_desc.tasks_info = tasks_info; - itti_desc.messages_info = messages_info; - - /* Allocates memory for tasks info */ - itti_desc.tasks = calloc (itti_desc.task_max, sizeof(task_desc_t)); - - /* Allocates memory for threads info */ - itti_desc.threads = calloc (itti_desc.thread_max, sizeof(thread_desc_t)); - - /* Initializing each queue and related stuff */ - for (task_id = TASK_FIRST; task_id < itti_desc.task_max; task_id++) { - ITTI_DEBUG(ITTI_DEBUG_INIT, " Initializing %stask %s%s%s\n", - itti_desc.tasks_info[task_id].parent_task != TASK_UNKNOWN ? "sub-" : "", - itti_desc.tasks_info[task_id].name, - itti_desc.tasks_info[task_id].parent_task != TASK_UNKNOWN ? " with parent " : "", - itti_desc.tasks_info[task_id].parent_task != TASK_UNKNOWN ? - itti_get_task_name(itti_desc.tasks_info[task_id].parent_task) : ""); - - ITTI_DEBUG(ITTI_DEBUG_INIT, " Creating queue of message of size %u\n", itti_desc.tasks_info[task_id].queue_size); - - ret = lfds611_queue_new(&itti_desc.tasks[task_id].message_queue, itti_desc.tasks_info[task_id].queue_size); - - if (0 == ret) { - AssertFatal (0, "lfds611_queue_new failed for task %s!\n", itti_get_task_name(task_id)); - } - } - - /* Initializing each thread */ - for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) { - itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED; - - itti_desc.threads[thread_id].epoll_fd = epoll_create1(0); - - if (itti_desc.threads[thread_id].epoll_fd == -1) { - /* Always assert on this condition */ - AssertFatal (0, "Failed to create new epoll fd: %s!\n", strerror(errno)); - } - - itti_desc.threads[thread_id].task_event_fd = eventfd(0, EFD_SEMAPHORE); - - if (itti_desc.threads[thread_id].task_event_fd == -1) { - /* Always assert on this condition */ - AssertFatal (0, " eventfd failed: %s!\n", strerror(errno)); - } - - itti_desc.threads[thread_id].nb_events = 1; - - itti_desc.threads[thread_id].events = calloc(1, sizeof(struct epoll_event)); - - itti_desc.threads[thread_id].events->events = EPOLLIN | EPOLLERR; - itti_desc.threads[thread_id].events->data.fd = itti_desc.threads[thread_id].task_event_fd; - - /* Add the event fd to the list of monitored events */ - if (epoll_ctl(itti_desc.threads[thread_id].epoll_fd, EPOLL_CTL_ADD, - itti_desc.threads[thread_id].task_event_fd, itti_desc.threads[thread_id].events) != 0) { - /* Always assert on this condition */ - AssertFatal (0, " epoll_ctl (EPOLL_CTL_ADD) failed: %s!\n", strerror(errno)); - } - - ITTI_DEBUG(ITTI_DEBUG_EVEN_FD, " Successfully subscribed fd %d for thread %d\n", - itti_desc.threads[thread_id].task_event_fd, thread_id); - - } - - itti_desc.running = 1; - itti_desc.wait_tasks = 0; - itti_desc.created_tasks = 0; - itti_desc.ready_tasks = 0; - CHECK_INIT_RETURN(timer_init ()); - - return 0; -} - -void itti_wait_tasks_end(void) -{ - int end = 0; - int thread_id; - task_id_t task_id; - int ready_tasks; - int result; - int retries = 10; - - itti_desc.thread_handling_signals = TRUE; - itti_desc.thread_ref=pthread_self (); - - /* Handle signals here */ - while (end == 0) { - signal_handle (&end); - } - - printf("closing all tasks\n"); - sleep(1); - - do { - ready_tasks = 0; - - task_id = TASK_FIRST; - - for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) { - /* Skip tasks which are not running */ - if (itti_desc.threads[thread_id].task_state == TASK_STATE_READY) { - while (thread_id != TASK_GET_THREAD_ID(task_id)) { - task_id++; - } - - result = pthread_tryjoin_np (itti_desc.threads[thread_id].task_thread, NULL); - - ITTI_DEBUG(ITTI_DEBUG_EXIT, " Thread %s join status %d\n", itti_get_task_name(task_id), result); - - if (result == 0) { - /* Thread has terminated */ - itti_desc.threads[thread_id].task_state = TASK_STATE_ENDED; - } else { - /* Thread is still running, count it */ - ready_tasks++; - } - } - } - - if (ready_tasks > 0) { - usleep (100 * 1000); - } - } while ((ready_tasks > 0) && (retries--)&& (!end) ); - - printf("ready_tasks %d\n",ready_tasks); - - itti_desc.running = 0; - - if (ready_tasks > 0) { - ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Some threads are still running, force exit\n"); - exit (0); - } -} - -void itti_send_terminate_message(task_id_t task_id) -{ - MessageDef *terminate_message_p; - - terminate_message_p = itti_alloc_new_message (task_id, TERMINATE_MESSAGE); - - itti_send_broadcast_message (terminate_message_p); -} diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h deleted file mode 100644 index ada34ce1b722a09722373cc5a650870364891b4e..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface.h +++ /dev/null @@ -1,235 +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 - */ - -/** @defgroup _intertask_interface_impl_ Intertask Interface Mechanisms - * Implementation - * @ingroup _ref_implementation_ - * @{ - */ - -#include <sys/epoll.h> - -#ifndef INTERTASK_INTERFACE_H_ -#define INTERTASK_INTERFACE_H_ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> - -#include "intertask_interface_conf.h" -#include "intertask_interface_types.h" - -#define ITTI_MSG_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.messageId) -#define ITTI_MSG_ORIGIN_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.originTaskId) -#define ITTI_MSG_DESTINATION_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.destinationTaskId) -#define ITTI_MSG_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.instance) -#define ITTI_MSG_NAME(mSGpTR) itti_get_message_name(ITTI_MSG_ID(mSGpTR)) -#define ITTI_MSG_ORIGIN_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_ORIGIN_ID(mSGpTR)) -#define ITTI_MSG_DESTINATION_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_DESTINATION_ID(mSGpTR)) - -/* Make the message number platform specific */ -typedef unsigned long message_number_t; -#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long)) - -typedef enum message_priorities_e { - MESSAGE_PRIORITY_MAX = 100, - MESSAGE_PRIORITY_MAX_LEAST = 85, - MESSAGE_PRIORITY_MED_PLUS = 70, - MESSAGE_PRIORITY_MED = 55, - MESSAGE_PRIORITY_MED_LEAST = 40, - MESSAGE_PRIORITY_MIN_PLUS = 25, - MESSAGE_PRIORITY_MIN = 10, -} message_priorities_t; - -typedef struct message_info_s { - task_id_t id; - message_priorities_t priority; - /* Message payload size */ - MessageHeaderSize size; - /* Printable name */ - const char * const name; -} message_info_t; - -typedef enum task_priorities_e { - TASK_PRIORITY_MAX = 100, - TASK_PRIORITY_MAX_LEAST = 85, - TASK_PRIORITY_MED_PLUS = 70, - TASK_PRIORITY_MED = 55, - TASK_PRIORITY_MED_LEAST = 40, - TASK_PRIORITY_MIN_PLUS = 25, - TASK_PRIORITY_MIN = 10, -} task_priorities_t; - -typedef struct task_info_s { - thread_id_t thread; - task_id_t parent_task; - task_priorities_t priority; - unsigned int queue_size; - /* Printable name */ - const char * const name; -} task_info_t; - -/** \brief Update the itti LTE time reference for messages - \param current reference frame - \param current reference slot - @returns < 0 on failure, 0 otherwise - **/ -void itti_update_lte_time(uint32_t frame, uint8_t slot); - -/** \brief Send a broadcast message to every task - \param message_p Pointer to the message to send - @returns < 0 on failure, 0 otherwise - **/ -int itti_send_broadcast_message(MessageDef *message_p); - -/** \brief Send a message to a task (could be itself) - \param task_id Task ID - \param instance Instance of the task used for virtualization - \param message Pointer to the message to send - @returns -1 on failure, 0 otherwise - **/ -int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); - -/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks - * the return value so it has been changed to crash the program in case - * of failure instead of returning -1 as the documentation above says. - * The RLC UM code may receive too much data when doing UDP at a higher - * throughput than the link allows and so for this specific case we need - * a version that actually returns -1 on failure. - * - * This needs to be cleaned at some point. - */ -/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ -int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); - -/** \brief Add a new fd to monitor. - * NOTE: it is up to the user to read data associated with the fd - * \param task_id Task ID of the receiving task - * \param fd The file descriptor to monitor - **/ -void itti_subscribe_event_fd(task_id_t task_id, int fd); - -/** \brief Remove a fd from the list of fd to monitor - * \param task_id Task ID of the task - * \param fd The file descriptor to remove - **/ -void itti_unsubscribe_event_fd(task_id_t task_id, int fd); - -/** \brief Return the list of events excluding the fd associated with itti - * \param task_id Task ID of the task - * \param events events list - * @returns number of events to handle - **/ -int itti_get_events(task_id_t task_id, struct epoll_event **events); - -/** \brief Retrieves a message in the queue associated to task_id. - * If the queue is empty, the thread is blocked till a new message arrives. - \param task_id Task ID of the receiving task - \param received_msg Pointer to the allocated message - **/ -void itti_receive_msg(task_id_t task_id, MessageDef **received_msg); - -/** \brief Try to retrieves a message in the queue associated to task_id. - \param task_id Task ID of the receiving task - \param received_msg Pointer to the allocated message - **/ -void itti_poll_msg(task_id_t task_id, MessageDef **received_msg); - -/** \brief Start thread associated to the task - * \param task_id task to start - * \param start_routine entry point for the task - * \param args_p Optional argument to pass to the start routine - * @returns -1 on failure, 0 otherwise - **/ -int itti_create_task(task_id_t task_id, - void *(*start_routine) (void *), - void *args_p); - -/** \brief Mark the task as a real time task - * \param task_id task to mark as real time - **/ -void itti_set_task_real_time(task_id_t task_id); - -/** \brief Indicates to ITTI if newly created tasks should wait for all tasks to be ready - * \param wait_tasks non 0 to make new created tasks to wait, 0 to let created tasks to run - **/ -void itti_wait_ready(int wait_tasks); - -/** \brief Mark the task as in ready state - * \param task_id task to mark as ready - **/ -void itti_mark_task_ready(task_id_t task_id); - -/** \brief Exit the current task. - **/ -void itti_exit_task(void); - -/** \brief Indicate that the task is completed and initiate termination of all tasks. - * \param task_id task that is completed - **/ -void itti_terminate_tasks(task_id_t task_id); - -/** \brief Return the printable string associated with the message - * \param message_id Id of the message - **/ -const char *itti_get_message_name(MessagesIds message_id); - -/** \brief Return the printable string associated with a task id - * \param thread_id Id of the task - **/ -const char *itti_get_task_name(task_id_t task_id); - -/** \brief Alloc and memset(0) a new itti message. - * \param origin_task_id Task ID of the sending task - * \param message_id Message ID - * @returns NULL in case of failure or newly allocated mesage ref - **/ -MessageDef *itti_alloc_new_message( - task_id_t origin_task_id, - MessagesIds message_id); - -/** \brief Alloc and memset(0) a new itti message. - * \param origin_task_id Task ID of the sending task - * \param message_id Message ID - * \param size size of the payload to send - * @returns NULL in case of failure or newly allocated mesage ref - **/ -MessageDef *itti_alloc_new_message_sized( - task_id_t origin_task_id, - MessagesIds message_id, - MessageHeaderSize size); - -/** \brief handle signals and wait for all threads to join when the process complete. - * This function should be called from the main thread after having created all ITTI tasks. - **/ -void itti_wait_tasks_end(void); - -/** \brief Send a termination message to all tasks. - * \param task_id task that is broadcasting the message. - **/ -void itti_send_terminate_message(task_id_t task_id); - -void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size); - -int itti_free(task_id_t task_id, void *ptr); - -#endif /* INTERTASK_INTERFACE_H_ */ -/* @} */ diff --git a/common/utils/itti/intertask_interface_init.h b/common/utils/itti/intertask_interface_init.h deleted file mode 100644 index dbd4e1b2ec061c2a0e334c9a8c5e80dae0b51964..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface_init.h +++ /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 - */ - -/** @defgroup _intertask_interface_impl_ Intertask Interface Mechanisms - * Implementation - * @ingroup _ref_implementation_ - * @{ - */ - -/******************************************************************************** - * - * !!! This header should only be included by the file that initialize - * the intertask interface module for the process !!! - * - * Other files should include "intertask_interface.h" - * - *******************************************************************************/ - -#ifndef INTERTASK_INTERFACE_INIT_H_ -#define INTERTASK_INTERFACE_INIT_H_ - -#include "intertask_interface.h" - -#ifndef CHECK_PROTOTYPE_ONLY - -/* Map task id to printable name. */ -const task_info_t tasks_info[] = { - {0, TASK_UNKNOWN, 0, 0, "TASK_UNKNOWN"}, -#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) { tHREADiD##_THREAD, TASK_UNKNOWN, pRIO, qUEUEsIZE, #tHREADiD }, -#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) { sUBtASKiD##_THREAD, tHREADiD##_THREAD, 0, qUEUEsIZE, #sUBtASKiD }, -#include <tasks_def.h> -#undef SUB_TASK_DEF -#undef TASK_DEF -}; - -/* Map message id to message information */ -const message_info_t messages_info[] = { -#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) { iD, pRIO, sizeof(sTRUCT), #iD }, -#include <messages_def.h> -#undef MESSAGE_DEF -}; - -#endif - -/** \brief Init function for the intertask interface. Init queues, Mutexes and Cond vars. - * \param thread_max Maximum number of threads - * \param messages_id_max Maximum message id - * \param threads_name Pointer on the threads name information as created by this include file - * \param messages_info Pointer on messages information as created by this include file - **/ -int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, - const message_info_t *messages_info); - -#endif /* INTERTASK_INTERFACE_INIT_H_ */ -/* @} */ diff --git a/common/utils/itti/intertask_interface_types.h b/common/utils/itti/intertask_interface_types.h deleted file mode 100644 index af1b4e9aa98931b52de2cea454f720e13748171a..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface_types.h +++ /dev/null @@ -1,143 +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 - */ - -/** @defgroup _intertask_interface_impl_ Intertask Interface Mechanisms - * Implementation - * @ingroup _ref_implementation_ - * @{ - */ - -#ifndef INTERTASK_INTERFACE_TYPES_H_ -#define INTERTASK_INTERFACE_TYPES_H_ - -#include "itti_types.h" -#include "platform_types.h" - -/* Defines to handle bit fields on unsigned long values */ -#define UL_BIT_MASK(lENGTH) ((1UL << (lENGTH)) - 1UL) -#define UL_BIT_SHIFT(vALUE, oFFSET) ((vALUE) << (oFFSET)) -#define UL_BIT_UNSHIFT(vALUE, oFFSET) ((vALUE) >> (oFFSET)) - -#define UL_FIELD_MASK(oFFSET, lENGTH) UL_BIT_SHIFT(UL_BIT_MASK(lENGTH), (oFFSET)) -#define UL_FIELD_INSERT(vALUE, fIELD, oFFSET, lENGTH) (((vALUE) & (~UL_FIELD_MASK(oFFSET, lENGTH))) | UL_BIT_SHIFT(((fIELD) & UL_BIT_MASK(lENGTH)), oFFSET)) -#define UL_FIELD_EXTRACT(vALUE, oFFSET, lENGTH) (UL_BIT_UNSHIFT((vALUE), (oFFSET)) & UL_BIT_MASK(lENGTH)) - -/* Definitions of task ID fields */ -#define TASK_THREAD_ID_OFFSET 8 -#define TASK_THREAD_ID_LENGTH 8 - -#define TASK_SUB_TASK_ID_OFFSET 0 -#define TASK_SUB_TASK_ID_LENGTH 8 - -/* Defines to extract task ID fields */ -#define TASK_GET_THREAD_ID(tASKiD) (itti_desc.tasks_info[tASKiD].thread) -#define TASK_GET_PARENT_TASK_ID(tASKiD) (itti_desc.tasks_info[tASKiD].parent_task) -/* Extract the instance from a message */ -#define ITTI_MESSAGE_GET_INSTANCE(mESSAGE) ((mESSAGE)->ittiMsgHeader.instance) - -#include <messages_types.h> - -/* This enum defines messages ids. Each one is unique. */ -typedef enum { -#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD, -#include <messages_def.h> -#undef MESSAGE_DEF - - MESSAGES_ID_MAX, -} MessagesIds; - -//! Thread id of each task -typedef enum { - THREAD_NULL = 0, - -#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) THREAD_##tHREADiD, -#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) -#include <tasks_def.h> -#undef SUB_TASK_DEF -#undef TASK_DEF - - THREAD_MAX, - THREAD_FIRST = 1, -} thread_id_t; - -//! Sub-tasks id, to defined offset form thread id -typedef enum { -#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD##_THREAD = THREAD_##tHREADiD, -#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD##_THREAD = THREAD_##tHREADiD, -#include <tasks_def.h> -#undef SUB_TASK_DEF -#undef TASK_DEF -} task_thread_id_t; - -//! Tasks id of each task -typedef enum { - TASK_UNKNOWN = 0, - -#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD, -#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD, -#include <tasks_def.h> -#undef SUB_TASK_DEF -#undef TASK_DEF - - TASK_MAX, - TASK_FIRST = 1, -} task_id_t; - -typedef union msg_s { -#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME; -#include <messages_def.h> -#undef MESSAGE_DEF -} msg_t; - -typedef uint16_t MessageHeaderSize; - -typedef struct itti_lte_time_s { - uint32_t frame; - uint8_t slot; -} itti_lte_time_t; - -/** @struct MessageHeader - * @brief Message Header structure for inter-task communication. - */ -typedef struct MessageHeader_s { - MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */ - - task_id_t originTaskId; /**< ID of the sender task */ - task_id_t destinationTaskId; /**< ID of the destination task */ - instance_t instance; /**< Task instance for virtualization */ - - MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */ - - itti_lte_time_t lte_time; /**< Reference LTE time */ -} MessageHeader; - -/** @struct MessageDef - * @brief Message structure for inter-task communication. - * \internal - * The attached attribute \c __packed__ is neccessary, because the memory allocation code expects \ref ittiMsg directly following \ref ittiMsgHeader. - */ -typedef struct __attribute__ ((__packed__)) MessageDef_s { - MessageHeader ittiMsgHeader; /**< Message header */ - msg_t ittiMsg; /**< Union of payloads as defined in x_messages_def.h headers */ -} MessageDef; - -#endif /* INTERTASK_INTERFACE_TYPES_H_ */ -/* @} */ diff --git a/common/utils/itti/intertask_messages_def.h b/common/utils/itti/intertask_messages_def.h deleted file mode 100644 index 57c344c8132b5b4f216ab4c5e05f25c48c8ea73e..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_messages_def.h +++ /dev/null @@ -1,49 +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 - */ - -/* This message asks for task initialization */ -MESSAGE_DEF(INITIALIZE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, initialize_message) - -/* This message asks for task activation */ -MESSAGE_DEF(ACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, activate_message) - -/* This message asks for task deactivation */ -MESSAGE_DEF(DEACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, deactivate_message) - -/* This message asks for task termination */ -MESSAGE_DEF(TERMINATE_MESSAGE, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, terminate_message) - -/* Test message used for debug */ -MESSAGE_DEF(MESSAGE_TEST, MESSAGE_PRIORITY_MED, IttiMsgEmpty, message_test) - -/* Error message */ -MESSAGE_DEF(ERROR_LOG, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, error_log) -/* Warning message */ -MESSAGE_DEF(WARNING_LOG, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, warning_log) -/* Notice message */ -MESSAGE_DEF(NOTICE_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, notice_log) -/* Info message */ -MESSAGE_DEF(INFO_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, info_log) -/* Debug message */ -MESSAGE_DEF(DEBUG_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, debug_log) - -/* Generic log message for text */ -MESSAGE_DEF(GENERIC_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, generic_log) diff --git a/common/utils/itti/itti_types.h b/common/utils/itti/itti_types.h deleted file mode 100644 index 2607c003b130f1d261923c6ebae21cec657d42b0..0000000000000000000000000000000000000000 --- a/common/utils/itti/itti_types.h +++ /dev/null @@ -1,82 +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 - */ - -/** @brief Intertask Interface common types - * Contains type definitions used for generating and parsing ITTI messages. - * @author Laurent Winckel <laurent.winckel@eurecom.fr> - */ - -#ifndef _ITTI_TYPES_H_ -#define _ITTI_TYPES_H_ - -/* The current file is included in the ue_ip.ko compilation. - * For it to work we need to include linux/types.h and - * not stdint.h. - * A solution to this problem is to use #ifndef __KERNEL__. - * Maybe a better solution would be to clean things up - * so that ue_ip.ko does not include the current file. - */ -#ifndef __KERNEL__ -# include <stdint.h> -#else -# include <linux/types.h> -#endif - -#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1)) - -#define MESSAGE_NUMBER_CHAR_FORMAT "%11u" - -/* Intertask message types */ -enum itti_message_types_e { - ITTI_DUMP_XML_DEFINITION = CHARS_TO_UINT32 ('\n', 'I', 'x', 'd'), - ITTI_DUMP_XML_DEFINITION_END = CHARS_TO_UINT32 ('i', 'X', 'D', '\n'), - - ITTI_DUMP_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 'm', 's'), - ITTI_DUMP_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'M', 'S', '\n'), - - ITTI_STATISTIC_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 's', 't'), - ITTI_STATISTIC_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'S', 'T', '\n'), - - /* This signal is not meant to be used by remote analyzer */ - ITTI_DUMP_EXIT_SIGNAL = CHARS_TO_UINT32 ('e', 'X', 'I', 'T'), -}; - -typedef uint32_t itti_message_types_t; - -/* Message header is the common part that should never change between - * remote process and this one. - */ -typedef struct { - /* The size of this structure */ - uint32_t message_size; - itti_message_types_t message_type; -} itti_socket_header_t; - -typedef struct { - char message_number_char[12]; /* 9 chars are needed to store an unsigned 32 bits value in decimal, but must be a multiple of 32 bits to avoid alignment issues */ -} itti_signal_header_t; - - -#define INSTANCE_DEFAULT (UINT16_MAX - 1) -#define INSTANCE_ALL (UINT16_MAX) - -#endif - diff --git a/common/utils/itti/messages_def.h b/common/utils/itti/messages_def.h deleted file mode 100644 index f312669848120a2ea022a4ac50ad172471e51ce4..0000000000000000000000000000000000000000 --- a/common/utils/itti/messages_def.h +++ /dev/null @@ -1,26 +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 - */ - -// These messages files are mandatory and must always be placed in first position -#include "intertask_messages_def.h" -#include "timer_messages_def.h" - -// Dummy file for the generic intertask interface definition. Actual definition should be in top level build directory. diff --git a/common/utils/itti/signals.c b/common/utils/itti/signals.c deleted file mode 100644 index 5dd667ae653a115e53ca18362ce1d2cec9d0ed2f..0000000000000000000000000000000000000000 --- a/common/utils/itti/signals.c +++ /dev/null @@ -1,141 +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 - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <signal.h> -#include <time.h> -#include <errno.h> - -#include "intertask_interface.h" -#include "timer.h" -#include "backtrace.h" -#include "assertions.h" - -#include "signals.h" -#include "log.h" - -#if defined (LOG_D) && defined (LOG_E) -# define SIG_DEBUG(x, args...) LOG_D(RRC, x, ##args) -# define SIG_ERROR(x, args...) LOG_E(RRC, x, ##args) -#endif - -#ifndef SIG_DEBUG -# define SIG_DEBUG(x, args...) do { fprintf(stdout, "[SIG][D]"x, ##args); } while(0) -#endif -#ifndef SIG_ERROR -# define SIG_ERROR(x, args...) do { fprintf(stdout, "[SIG][E]"x, ##args); } while(0) -#endif - -static sigset_t set; - -int signal_mask(void) -{ - /* We set the signal mask to avoid threads other than the main thread - * to receive the timer signal. Note that threads created will inherit this - * configuration. - */ - sigemptyset(&set); - - sigaddset (&set, SIGTIMER); - sigaddset (&set, SIGUSR1); - sigaddset (&set, SIGABRT); - sigaddset (&set, SIGSEGV); - sigaddset (&set, SIGINT); - - if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) { - perror ("sigprocmask"); - return -1; - } - - return 0; -} - -int signal_handle(int *end) -{ - int ret; - siginfo_t info; - - sigemptyset(&set); - - sigaddset (&set, SIGTIMER); - sigaddset (&set, SIGUSR1); - sigaddset (&set, SIGABRT); - sigaddset (&set, SIGSEGV); - sigaddset (&set, SIGINT); - - if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) { - perror ("sigprocmask"); - return -1; - } - - /* Block till a signal is received. - * NOTE: The signals defined by set are required to be blocked at the time - * of the call to sigwait() otherwise sigwait() is not successful. - */ - if ((ret = sigwaitinfo(&set, &info)) == -1) { - perror ("sigwait"); - return ret; - } - - //printf("Received signal %d\n", info.si_signo); - - /* Real-time signals are non constant and are therefore not suitable for - * use in switch. - */ - if (info.si_signo == SIGTIMER) { - timer_handle_signal(&info); - } else { - /* Dispatch the signal to sub-handlers */ - switch(info.si_signo) { - case SIGUSR1: - SIG_DEBUG("Received SIGUSR1\n"); - *end = 1; - break; - - case SIGSEGV: /* Fall through */ - case SIGABRT: - SIG_DEBUG("Received SIGABORT\n"); - backtrace_handle_signal(&info); - break; - - case SIGINT: - printf("Received SIGINT\n"); - itti_send_terminate_message(TASK_UNKNOWN); - *end = 1; - break; - - default: - SIG_ERROR("Received unknown signal %d\n", info.si_signo); - break; - } - } - - return 0; -} diff --git a/common/utils/itti/timer.c b/common/utils/itti/timer.c deleted file mode 100644 index 6327aeacfb675140bda39f76feed86ddc2541c18..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer.c +++ /dev/null @@ -1,255 +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 - */ - -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <signal.h> -#include <time.h> -#include <errno.h> - -#include "assertions.h" -#include "intertask_interface.h" -#include "timer.h" -#include "log.h" -#include "queue.h" - -#if defined (LOG_D) && defined (LOG_E) -# define TMR_DEBUG(x, args...) LOG_D(TMR, x, ##args) -# define TMR_ERROR(x, args...) LOG_E(TMR, x, ##args) -#endif - -#ifndef TMR_DEBUG -# define TMR_DEBUG(x, args...) do { fprintf(stdout, "[TMR][D]"x, ##args); } while(0) -#endif -#ifndef TMR_ERROR -# define TMR_ERROR(x, args...) do { fprintf(stdout, "[TMR][E]"x, ##args); } while(0) -#endif - -int timer_handle_signal(siginfo_t *info); - -struct timer_elm_s { - task_id_t task_id; ///< Task ID which has requested the timer - int32_t instance; ///< Instance of the task which has requested the timer - timer_t timer; ///< Unique timer id - timer_type_t type; ///< Timer type - void *timer_arg; ///< Optional argument that will be passed when timer expires - STAILQ_ENTRY(timer_elm_s) entries; ///< Pointer to next element -}; - -typedef struct timer_desc_s { - STAILQ_HEAD(timer_list_head, timer_elm_s) timer_queue; - pthread_mutex_t timer_list_mutex; - struct timespec timeout; -} timer_desc_t; - -static timer_desc_t timer_desc; - -#define TIMER_SEARCH(vAR, tIMERfIELD, tIMERvALUE, tIMERqUEUE) \ -do { \ - STAILQ_FOREACH(vAR, tIMERqUEUE, entries) { \ - if (((vAR)->tIMERfIELD == tIMERvALUE)) \ - break; \ - } \ -} while(0) - -int timer_handle_signal(siginfo_t *info) -{ - struct timer_elm_s *timer_p; - MessageDef *message_p; - timer_has_expired_t *timer_expired_p; - task_id_t task_id; - int32_t instance; - - /* Get back pointer to timer list element */ - timer_p = (struct timer_elm_s *)info->si_ptr; - - // LG: To many traces for msc timer: - TMR_DEBUG("Timer with id 0x%lx has expired\n", (long)timer_p->timer); - - task_id = timer_p->task_id; - instance = timer_p->instance; - message_p = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED); - - timer_expired_p = &message_p->ittiMsg.timer_has_expired; - - timer_expired_p->timer_id = (long)timer_p->timer; - timer_expired_p->arg = timer_p->timer_arg; - - /* Timer is a one shot timer, remove it */ - if (timer_p->type == TIMER_ONE_SHOT) { - // if (timer_delete(timer_p->timer) < 0) { - // TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer); - // } - // TMR_DEBUG("Removed timer 0x%lx\n", (long)timer_p->timer); - // pthread_mutex_lock(&timer_desc.timer_list_mutex); - // STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries); - // pthread_mutex_unlock(&timer_desc.timer_list_mutex); - // free(timer_p); - // timer_p = NULL; - if (timer_remove((long)timer_p->timer) != 0) { - TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer); - } - } - - /* Notify task of timer expiry */ - if (itti_send_msg_to_task(task_id, instance, message_p) < 0) { - TMR_DEBUG("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id); - free(message_p); - return -1; - } - -#if defined(ENB_AGENT_SB_IF) - -#endif - - return 0; -} - -int timer_setup( - uint32_t interval_sec, - uint32_t interval_us, - task_id_t task_id, - int32_t instance, - timer_type_t type, - void *timer_arg, - long *timer_id) -{ - struct sigevent se; - struct itimerspec its; - struct timer_elm_s *timer_p; - timer_t timer; - - if (timer_id == NULL) { - return -1; - } - - AssertFatal (type < TIMER_TYPE_MAX, "Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX); - - /* Allocate new timer list element */ - timer_p = malloc(sizeof(struct timer_elm_s)); - - if (timer_p == NULL) { - TMR_ERROR("Failed to create new timer element\n"); - return -1; - } - - memset(&timer, 0, sizeof(timer_t)); - memset(&se, 0, sizeof(struct sigevent)); - - timer_p->task_id = task_id; - timer_p->instance = instance; - timer_p->type = type; - timer_p->timer_arg = timer_arg; - - /* Setting up alarm */ - /* Set and enable alarm */ - se.sigev_notify = SIGEV_SIGNAL; - se.sigev_signo = SIGTIMER; - se.sigev_value.sival_ptr = timer_p; - - /* At the timer creation, the timer structure will be filled in with timer_id, - * which is unique for this process. This id is allocated by kernel and the - * value might be used to distinguish timers. - */ - if (timer_create(CLOCK_REALTIME, &se, &timer) < 0) { - TMR_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno); - free(timer_p); - return -1; - } - - /* Fill in the first expiration value. */ - its.it_value.tv_sec = interval_sec; - its.it_value.tv_nsec = interval_us * 1000; - - if (type == TIMER_PERIODIC) { - /* Asked for periodic timer. We set the interval time */ - its.it_interval.tv_sec = interval_sec; - its.it_interval.tv_nsec = interval_us * 1000; - } else { - /* Asked for one-shot timer. Do not set the interval field */ - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - } - - timer_settime(timer, 0, &its, NULL); - /* Simply set the timer_id argument. so it can be used by caller */ - *timer_id = (long)timer; - TMR_DEBUG("Requesting new %s timer with id 0x%lx that expires within " - "%d sec and %d usec\n", - type == TIMER_PERIODIC ? "periodic" : "single shot", - *timer_id, interval_sec, interval_us); - - timer_p->timer = timer; - - /* Lock the queue and insert the timer at the tail */ - pthread_mutex_lock(&timer_desc.timer_list_mutex); - STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries); - pthread_mutex_unlock(&timer_desc.timer_list_mutex); - - return 0; -} - -int timer_remove(long timer_id) -{ - int rc = 0; - struct timer_elm_s *timer_p; - - TMR_DEBUG("Removing timer 0x%lx\n", timer_id); - - pthread_mutex_lock(&timer_desc.timer_list_mutex); - TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue); - - /* We didn't find the timer in list */ - if (timer_p == NULL) { - pthread_mutex_unlock(&timer_desc.timer_list_mutex); - TMR_ERROR("Didn't find timer 0x%lx in list\n", timer_id); - return -1; - } - - STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries); - pthread_mutex_unlock(&timer_desc.timer_list_mutex); - - if (timer_delete(timer_p->timer) < 0) { - TMR_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer); - rc = -1; - } - - free(timer_p); - timer_p = NULL; - return rc; -} - -int timer_init(void) -{ - TMR_DEBUG("Initializing TIMER task interface\n"); - - memset(&timer_desc, 0, sizeof(timer_desc_t)); - - STAILQ_INIT(&timer_desc.timer_queue); - pthread_mutex_init(&timer_desc.timer_list_mutex, NULL); - - TMR_DEBUG("Initializing TIMER task interface: DONE\n"); - return 0; -} diff --git a/common/utils/itti/timer.h b/common/utils/itti/timer.h deleted file mode 100644 index 4f568a348c5755802f7fadb018d8b2790935b608..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer.h +++ /dev/null @@ -1,69 +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 - */ - -#ifndef TIMER_H_ -#define TIMER_H_ - -#include <signal.h> - -#define SIGTIMER SIGRTMIN - -typedef enum timer_type_s { - TIMER_PERIODIC, - TIMER_ONE_SHOT, - TIMER_TYPE_MAX, -} timer_type_t; - -int timer_handle_signal(siginfo_t *info); - -/** \brief Request a new timer - * \param interval_sec timer interval in seconds - * \param interval_us timer interval in micro seconds - * \param task_id task id of the task requesting the timer - * \param instance instance of the task requesting the timer - * \param type timer type - * \param timer_id unique timer identifier - * @returns -1 on failure, 0 otherwise - **/ -int timer_setup( - uint32_t interval_sec, - uint32_t interval_us, - task_id_t task_id, - int32_t instance, - timer_type_t type, - void *timer_arg, - long *timer_id); - -/** \brief Remove the timer from list - * \param timer_id unique timer id - * @returns -1 on failure, 0 otherwise - **/ - -int timer_remove(long timer_id); -#define timer_stop timer_remove - -/** \brief Initialize timer task and its API - * \param mme_config MME common configuration - * @returns -1 on failure, 0 otherwise - **/ -int timer_init(void); - -#endif diff --git a/common/utils/itti/timer_messages_types.h b/common/utils/itti/timer_messages_types.h deleted file mode 100644 index 0d06e3eebfd15c33e9fe9555b0ba7fb5c6253fb0..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer_messages_types.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 - */ - -#ifndef TIMER_MESSAGES_TYPES_H_ -#define TIMER_MESSAGES_TYPES_H_ - -//-------------------------------------------------------------------------------------------// -// Defines to access message fields. -#define TIMER_HAS_EXPIRED(mSGpTR) (mSGpTR)->ittiMsg.timer_has_expired - -//-------------------------------------------------------------------------------------------// -typedef struct { - void *arg; - long timer_id; -} timer_has_expired_t; - -#endif /* TIMER_MESSAGES_TYPES_H_ */ diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index 656f6a885224abaf3e6565368bd99d5f95225620..a4b4742c94c6041cafe35712e1e092e181e0d005 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -70,8 +70,8 @@ char *tmpstr; char *shlibpath =NULL; char *shlibversion=NULL; char *cfgprefix; -paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0}, - {"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}}; +paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0, NULL}, + {"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0, NULL}}; int ret; @@ -118,77 +118,118 @@ int ret; return tmpstr; } -int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) +int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg) { - void *lib_handle; - initfunc_t fpi; - checkverfunc_t fpc; - getfarrayfunc_t fpg; - char *shlib_path; - char *afname=NULL; - int ret=0; - - if (loader_data.shlibpath == NULL) { - loader_init(); - } + void *lib_handle = NULL; + initfunc_t fpi; + checkverfunc_t fpc; + getfarrayfunc_t fpg; + char *shlib_path = NULL; + char *afname = NULL; + int ret = 0; + int lib_idx = -1; + + if (!modname) { + fprintf(stderr, "[LOADER] load_module_shlib(): no library name given\n"); + return -1; + } - shlib_path = loader_format_shlibpath(modname); + if (!loader_data.shlibpath) { + loader_init(); + } - ret = 0; - lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); - if (!lib_handle) { - fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); + shlib_path = loader_format_shlibpath(modname); + + for (int i = 0; i < loader_data.numshlibs; i++) { + if (strcmp(loader_data.shlibs[i].name, modname) == 0) { + printf("[LOADER] library %s has been loaded previously, reloading function pointers\n", + shlib_path); + lib_idx = i; + break; + } + } + if (lib_idx < 0) { + lib_idx = loader_data.numshlibs; + ++loader_data.numshlibs; + if (loader_data.numshlibs > loader_data.maxshlibs) { + fprintf(stderr, "[LOADER] can not load more than %d shlibs\n", + loader_data.maxshlibs); ret = -1; - } else { - printf("[LOADER] library %s successfully loaded\n", shlib_path); - afname=malloc(strlen(modname)+15); - sprintf(afname,"%s_checkbuildver",modname); - fpc = dlsym(lib_handle,afname); - if (fpc != NULL ){ - int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); - if (chkver_ret < 0) { - fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); - exit_fun("[LOADER] unrecoverable error"); - } - } - sprintf(afname,"%s_autoinit",modname); - fpi = dlsym(lib_handle,afname); + goto load_module_shlib_exit; + } + loader_data.shlibs[lib_idx].name = strdup(modname); + loader_data.shlibs[lib_idx].thisshlib_path = strdup(shlib_path); + } - if (fpi != NULL ) { - fpi(); - } + lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); + if (!lib_handle) { + fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); + ret = -1; + goto load_module_shlib_exit; + } + + printf("[LOADER] library %s successfully loaded\n", shlib_path); + afname = malloc(strlen(modname)+15); + if (!afname) { + fprintf(stderr, "[LOADER] unable to allocate memory for library %s\n", shlib_path); + ret = -1; + goto load_module_shlib_exit; + } + sprintf(afname,"%s_checkbuildver",modname); + fpc = dlsym(lib_handle,afname); + if (fpc) { + int chkver_ret = fpc(loader_data.mainexec_buildversion, + &(loader_data.shlibs[lib_idx].shlib_buildversion)); + if (chkver_ret < 0) { + fprintf(stderr, "[LOADER] %s %d lib %s, version mismatch", + __FILE__, __LINE__, modname); + ret = -1; + goto load_module_shlib_exit; + } + } + sprintf(afname,"%s_autoinit",modname); + fpi = dlsym(lib_handle,afname); - if (farray != NULL) { - loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); - loader_data.shlibs[loader_data.numshlibs].numfunc=0; - for (int i=0; i<numf; i++) { - farray[i].fptr = dlsym(lib_handle,farray[i].fname); - if (farray[i].fptr == NULL ) { - fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); - ret= -1; - } else { /* farray[i].fptr == NULL */ - loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname); - loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr; - loader_data.shlibs[loader_data.numshlibs].numfunc++; - }/* farray[i].fptr != NULL */ - } /* for int i... */ - } else { /* farray ! NULL */ - sprintf(afname,"%s_getfarray",modname); - fpg = dlsym(lib_handle,afname); - if (fpg != NULL ) { - loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray)); - } - } /* farray ! NULL */ - loader_data.shlibs[loader_data.numshlibs].name=strdup(modname); - loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path); - - (loader_data.numshlibs)++; - } /* lib_handle != NULL */ - - if ( shlib_path!= NULL) free(shlib_path); - if ( afname!= NULL) free(afname); - if (lib_handle != NULL) dlclose(lib_handle); - return ret; + if (fpi) { + fpi(autoinit_arg); + } + + if (farray) { + if (!loader_data.shlibs[lib_idx].funcarray) { + loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t)); + if (!loader_data.shlibs[lib_idx].funcarray) { + fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n"); + ret = -1; + goto load_module_shlib_exit; + } + } + loader_data.shlibs[lib_idx].numfunc = 0; + for (int i = 0; i < numf; i++) { + farray[i].fptr = dlsym(lib_handle,farray[i].fname); + if (!farray[i].fptr) { + fprintf(stderr, "[LOADER] load_module_shlib(): function %s not found: %s\n", + farray[i].fname, dlerror()); + ret = -1; + goto load_module_shlib_exit; + } + loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname); + loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr; + loader_data.shlibs[lib_idx].numfunc++; + } /* for int i... */ + } else { /* farray ! NULL */ + sprintf(afname,"%s_getfarray",modname); + fpg = dlsym(lib_handle,afname); + if (fpg) { + loader_data.shlibs[lib_idx].numfunc = + fpg(&(loader_data.shlibs[lib_idx].funcarray)); + } + } /* farray ! NULL */ + +load_module_shlib_exit: + if (shlib_path) free(shlib_path); + if (afname) free(afname); + if (lib_handle) dlclose(lib_handle); + return ret; } void * get_shlibmodule_fptr(char *modname, char *fname) diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h index ffbad665708ef0ffe1f890d14e6f04039b5afb80..685b3d1b6552f298c1378dff631a8036d49e15e1 100644 --- a/common/utils/load_module_shlib.h +++ b/common/utils/load_module_shlib.h @@ -59,7 +59,8 @@ typedef struct { /* function type of functions which may be implemented by a module */ /* 1: init function, called when loading, if found in the shared lib */ -typedef int(*initfunc_t)(void); +typedef int(*initfunc_t)(void *); + /* 2: version checking function, called when loading, if it returns -1, trigger main exec abort */ typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version); /* 3: get function array function, called when loading when a module doesn't provide */ @@ -72,18 +73,18 @@ typedef int(*getfarrayfunc_t)(loader_shlibfunc_t **funcarray); #define DEFAULT_MAXSHLIBS 10 loader_data_t loader_data; -/*------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOADER parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* LOADER parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt check func*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOADER_PARAMS_DESC { \ -{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0}, \ -{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0}, \ +{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0, NULL},\ +{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0, NULL}\ } /*-------------------------------------------------------------------------------------------------------------*/ #else /* LOAD_MODULE_SHLIB_MAIN */ -extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf); +extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf, void *initfunc_arg); extern void * get_shlibmodule_fptr(char *modname, char *fname); extern loader_data_t loader_data; #endif /* LOAD_MODULE_SHLIB_MAIN */ diff --git a/common/utils/itti/memory_pools.c b/common/utils/memory_pools.c similarity index 100% rename from common/utils/itti/memory_pools.c rename to common/utils/memory_pools.c diff --git a/common/utils/itti/memory_pools.h b/common/utils/memory_pools.h similarity index 100% rename from common/utils/itti/memory_pools.h rename to common/utils/memory_pools.h diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c index bb88b9b4b6a4441eba3b65ee40b31198efb8b5b0..4c9e3827b069ee20ced71cbb6304533551c3e937 100644 --- a/common/utils/msc/msc.c +++ b/common/utils/msc/msc.c @@ -32,11 +32,14 @@ #include <stdint.h> #include <inttypes.h> +#define MSC_LIBRARY +#include "msc.h" + #include "liblfds611.h" #include "intertask_interface.h" -#include "timer.h" -#include "msc.h" + + #include "assertions.h" //------------------------------- @@ -67,8 +70,8 @@ void *msc_task(void *args_p) //------------------------------------------------------------------------------ { MessageDef *received_message_p = NULL; - const char *msg_name = NULL; - instance_t instance = 0; +// const char *msg_name = NULL; +// instance_t instance = 0; long timer_id; itti_mark_task_ready(TASK_MSC); @@ -88,9 +91,9 @@ void *msc_task(void *args_p) itti_receive_msg(TASK_MSC, &received_message_p); if (received_message_p != NULL) { - msg_name = ITTI_MSG_NAME (received_message_p); - instance = ITTI_MSG_INSTANCE (received_message_p); - +// msg_name = ITTI_MSG_NAME (received_message_p); +// instance = ITTI_MSG_INSTANCE (received_message_p); + switch (ITTI_MSG_ID(received_message_p)) { case TIMER_HAS_EXPIRED: { @@ -571,4 +574,17 @@ error_event: free(new_item_p); } - +//------------------------------------------------------------------------------ +// function called when oai loader loads the msc shared lib +int msc_autoinit(msc_interface_t *msc_interface) +//------------------------------------------------------------------------------ + { + + msc_interface->msc_init = msc_init; + msc_interface->msc_start_use = msc_start_use; + msc_interface->msc_end = msc_end; + msc_interface->msc_log_event = msc_log_event; + msc_interface->msc_log_message = msc_log_message; + msc_interface->msc_loaded = 1; + return 0; + } diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h index 4493a5239a40f2c41aa79461443c8bb51b9737d9..e8a8a4a0e82d7f65f9b9fcd80b54ddc79cff2759 100644 --- a/common/utils/msc/msc.h +++ b/common/utils/msc/msc.h @@ -63,6 +63,8 @@ typedef enum { MSC_S6A_MME, MSC_HSS, MAX_MSC_PROTOS, + MSC_X2AP_SRC_ENB, + MSC_X2AP_TARGET_ENB, } msc_proto_t; @@ -73,7 +75,23 @@ typedef enum { #define MSC_AS_TIME_ARGS(CTXT_Pp) \ (CTXT_Pp)->frame, \ (CTXT_Pp)->subframe -#if defined(MESSAGE_CHART_GENERATOR) + +typedef int(*msc_init_t)(const msc_env_t, const int ); +typedef void(*msc_start_use_t)(void ); +typedef void(*msc_end_t)(void); +typedef void(*msc_log_event_t)(const msc_proto_t,char *, ...); +typedef void(*msc_log_message_t)(const char * const, const msc_proto_t, const msc_proto_t, + const uint8_t* const, const unsigned int, char * , ...); +typedef struct msc_interface { + int msc_loaded; + msc_init_t msc_init; + msc_start_use_t msc_start_use; + msc_end_t msc_end; + msc_log_event_t msc_log_event; + msc_log_message_t msc_log_message; +} msc_interface_t; + +#ifdef MSC_LIBRARY int msc_init(const msc_env_t envP, const int max_threadsP); void msc_start_use(void); void msc_flush_messages(void); @@ -88,22 +106,17 @@ void msc_log_message( const unsigned int num_bytes, char *format, ...); -#define MSC_INIT(arg1,arg2) msc_init(arg1,arg2) -#define MSC_START_USE msc_start_use -#define MSC_END msc_end -#define MSC_LOG_EVENT(mScPaRaMs, fORMAT, aRGS...) msc_log_event(mScPaRaMs, fORMAT, ##aRGS) -#define MSC_LOG_RX_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("<-",rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, ##aRGS) -#define MSC_LOG_RX_DISCARDED_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("x-",rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, ##aRGS) -#define MSC_LOG_TX_MESSAGE(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("->",sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, ##aRGS) -#define MSC_LOG_TX_MESSAGE_FAILED(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) msc_log_message("-x",sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, ##aRGS) #else -#define MSC_INIT(arg1,arg2) -#define MSC_START_USE(mScPaRaMs) -#define MSC_END(mScPaRaMs) -#define MSC_LOG_EVENT(mScPaRaMs, fORMAT, aRGS...) -#define MSC_LOG_RX_MESSAGE(mScPaRaMs, fORMAT, aRGS...) -#define MSC_LOG_RX_DISCARDED_MESSAGE(mScPaRaMs, fORMAT, aRGS...) -#define MSC_LOG_TX_MESSAGE(mScPaRaMs, fORMAT, aRGS...) -#define MSC_LOG_TX_MESSAGE_FAILED(mScPaRaMs, fORMAT, aRGS...) -#endif + +msc_interface_t msc_interface; +#define MSC_INIT(arg1,arg2) if(msc_interface.msc_loaded) msc_interface.msc_init(arg1,arg2) +#define MSC_START_USE if(msc_interface.msc_loaded) msc_interface.msc_start_use +#define MSC_END if(msc_interface.msc_loaded) msc_interface.msc_end +#define MSC_LOG_EVENT(mScPaRaMs, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_event(mScPaRaMs, fORMAT, ##aRGS) +#define MSC_LOG_RX_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("<-",rECEIVER, sENDER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS) +#define MSC_LOG_RX_DISCARDED_MESSAGE(rECEIVER, sENDER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("x-",rECEIVER, sENDER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS) +#define MSC_LOG_TX_MESSAGE(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("->",sENDER, rECEIVER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS) +#define MSC_LOG_TX_MESSAGE_FAILED(sENDER, rECEIVER, bYTES, nUMbYTES, fORMAT, aRGS...) if(msc_interface.msc_loaded) msc_interface.msc_log_message("-x",sENDER, rECEIVER, (const uint8_t *)bYTES, nUMbYTES, fORMAT, ##aRGS) #endif + +#endif diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..f4395724009085aaffd9fa62385f321cb34b10e8 --- /dev/null +++ b/common/utils/ocp_itti/all_msg.h @@ -0,0 +1,15 @@ +#include "openair2/COMMON/phy_messages_def.h" +#include "openair2/COMMON/mac_messages_def.h" +#include "openair2/COMMON/rlc_messages_def.h" +#include "openair2/COMMON/pdcp_messages_def.h" +#include "openair2/COMMON/rrc_messages_def.h" +#include "openair2/COMMON/nas_messages_def.h" +#if ENABLE_RAL + #include "openair2/COMMON/ral_messages_def.h" +#endif +#include "openair2/COMMON/s1ap_messages_def.h" +#include "openair2/COMMON/x2ap_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" +#include "openair2/COMMON/flexran_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b8d1a430e02cef93126e71a61f69ae7e6513d94 --- /dev/null +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -0,0 +1,414 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ +#include <vector> +#include <map> +#include <sys/eventfd.h> + + +#include <intertask_interface.h> + +typedef struct timer_elm_s { + timer_type_t type; ///< Timer type + long instance; + long duration; + uint64_t timeout; + void *timer_arg; ///< Optional argument that will be passed when timer expires +} timer_elm_t ; + +typedef struct task_list_s { + task_info_t admin; + pthread_t thread; + pthread_mutex_t queue_cond_lock; + std::vector<MessageDef *> message_queue; + std::map<long,timer_elm_t> timer_map; + uint64_t next_timer=UINT64_MAX; + struct epoll_event *events =NULL; + int nb_fd_epoll=0; + int nb_events=0; + int epoll_fd=-1; + int sem_fd=-1; +} task_list_t; + +int timer_expired(int fd); +task_list_t tasks[TASK_MAX]; + +extern "C" { + void *pool_buffer_init (void) { + return 0; + } + + void *pool_buffer_clean (void *arg) { + //----------------------------------------------------------------------------- + return 0; + } + + void free_mem_block (mem_block_t *leP, const char *caller) { + AssertFatal(leP!=NULL,""); + free(leP); + } + + mem_block_t *get_free_mem_block (uint32_t sizeP, const char *caller) { + mem_block_t *ptr=(mem_block_t *)malloc(sizeP+sizeof(mem_block_t)); + ptr->next = NULL; + ptr->previous = NULL; + ptr->data=((unsigned char *)ptr)+sizeof(mem_block_t); + ptr->size=sizeP; + return ptr; + } + + void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size) { + void *ptr = NULL; + AssertFatal ((ptr=malloc (size)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n", + size, origin_task_id, destination_task_id); + return ptr; + } + + int itti_free(task_id_t task_id, void *ptr) { + AssertFatal (ptr != NULL, "Trying to free a NULL pointer (%d)!\n", task_id); + free (ptr); + return (EXIT_SUCCESS); + } + + MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size) { + MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) + size); + temp->ittiMsgHeader.messageId = message_id; + temp->ittiMsgHeader.originTaskId = origin_task_id; + temp->ittiMsgHeader.ittiMsgSize = size; + return temp; + } + + MessageDef *itti_alloc_new_message(task_id_t origin_task_id, MessagesIds message_id) { + int size=sizeof(MessageHeader) + messages_info[message_id].size; + MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, size); + temp->ittiMsgHeader.messageId = message_id; + temp->ittiMsgHeader.originTaskId = origin_task_id; + temp->ittiMsgHeader.ittiMsgSize = size; + return temp; + //return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size); + } + + static inline int itti_send_msg_to_task_locked(task_id_t destination_task_id, instance_t instance, MessageDef *message) { + task_list_t *t=tasks+destination_task_id; + message->ittiMsgHeader.destinationTaskId = destination_task_id; + message->ittiMsgHeader.instance = instance; + message->ittiMsgHeader.lte_time.frame = 0; + message->ittiMsgHeader.lte_time.slot = 0; + int message_id = message->ittiMsgHeader.messageId; + size_t s=t->message_queue.size(); + + if ( s > t->admin.queue_size ) + LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s ); + + if ( s > 50 ) + LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1); + + t->message_queue.insert(t->message_queue.begin(), message); + eventfd_t sem_counter = 1; + AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), ""); + LOG_D(TMR,"sent messages id=%d to %s\n",message_id, t->admin.name); + return 0; + } + + int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) { + task_list_t *t=&tasks[destination_task_id]; + pthread_mutex_lock (&t->queue_cond_lock); + int ret=itti_send_msg_to_task_locked(destination_task_id, instance, message); + + while ( t->message_queue.size()>0 && t->admin.func != NULL ) { + if (t->message_queue.size()>1) + LOG_W(TMR,"queue in no thread mode is %ld\n", t->message_queue.size()); + pthread_mutex_unlock (&t->queue_cond_lock); + t->admin.func(NULL); + pthread_mutex_lock (&t->queue_cond_lock); + } + pthread_mutex_unlock (&t->queue_cond_lock); + return ret; + } + + void itti_subscribe_event_fd(task_id_t task_id, int fd) { + struct epoll_event event; + task_list_t *t=&tasks[task_id]; + t->nb_fd_epoll++; + t->events = (struct epoll_event *)realloc((void *)t->events, + t->nb_fd_epoll * sizeof(struct epoll_event)); + event.events = EPOLLIN | EPOLLERR; + event.data.u64 = 0; + event.data.fd = fd; + AssertFatal(epoll_ctl(t->epoll_fd, EPOLL_CTL_ADD, fd, &event) == 0, + "epoll_ctl (EPOLL_CTL_ADD) failed for task %s, fd %d: %s!\n", + itti_get_task_name(task_id), fd, strerror(errno)); + } + + void itti_unsubscribe_event_fd(task_id_t task_id, int fd) { + task_list_t *t=&tasks[task_id]; + AssertFatal (epoll_ctl(t->epoll_fd, EPOLL_CTL_DEL, fd, NULL) == 0, + "epoll_ctl (EPOLL_CTL_DEL) failed for task %s, fd %d: %s!\n", + itti_get_task_name(task_id), fd, strerror(errno)); + t->nb_fd_epoll--; + } + + static inline int itti_get_events_locked(task_id_t task_id, struct epoll_event **events) { + task_list_t *t=&tasks[task_id]; + uint64_t current_time=0; + + do { + if ( t->next_timer != UINT64_MAX ) { + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + current_time=(uint64_t)tp.tv_sec*1000+tp.tv_nsec/(1000*1000); + + if ( t->next_timer < current_time) { + t->next_timer=UINT64_MAX; + + // Proceed expired timer + for ( auto it=t->timer_map.begin() ; it != t->timer_map.end() ; ++it ) { + if ( it->second.timeout < current_time ) { + MessageDef *message = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED); + message->ittiMsg.timer_has_expired.timer_id=it->first; + message->ittiMsg.timer_has_expired.arg=it->second.timer_arg; + + if (itti_send_msg_to_task_locked(task_id, it->second.instance, message) < 0) { + LOG_W(TMR,"Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id); + free(message); + t->timer_map.erase(it); + return -1; + } + + if ( it->second.type==TIMER_PERIODIC ) { + it->second.timeout+=it->second.duration; + + if (it->second.timeout < t->next_timer) + t->next_timer=it->second.timeout; + } else + t->timer_map.erase(it); + } else if (it->second.timeout < t->next_timer) + t->next_timer=it->second.timeout; + } + } + } + + int epoll_timeout = -1; + + if ( t->next_timer != UINT64_MAX ) + epoll_timeout = t->next_timer-current_time; + + pthread_mutex_unlock(&t->queue_cond_lock); + LOG_D(TMR,"enter blocking wait for %s\n", itti_get_task_name(task_id)); + t->nb_events = epoll_wait(t->epoll_fd,t->events,t->nb_fd_epoll, epoll_timeout); + if ( t->nb_events < 0 && (errno == EINTR || errno == EAGAIN ) ) + pthread_mutex_lock(&t->queue_cond_lock); + } while (t->nb_events < 0 && (errno == EINTR || errno == EAGAIN ) ); + + AssertFatal (t->nb_events >=0, + "epoll_wait failed for task %s, nb fds %d, timeout %lu: %s!\n", + itti_get_task_name(task_id), t->nb_fd_epoll, t->next_timer != UINT64_MAX ? t->next_timer-current_time : -1, strerror(errno)); + LOG_D(TMR,"receive on %d descriptors for %s\n", t->nb_events, itti_get_task_name(task_id)); + + if (t->nb_events == 0) + /* No data to read -> return */ + return 0; + + for (int i = 0; i < t->nb_events; i++) { + /* Check if there is an event for ITTI for the event fd */ + if ((t->events[i].events & EPOLLIN) && + (t->events[i].data.fd == t->sem_fd)) { + eventfd_t sem_counter; + /* Read will always return 1 */ + AssertFatal( sizeof(sem_counter) == read (t->sem_fd, &sem_counter, sizeof(sem_counter)), ""); + /* Mark that the event has been processed */ + t->events[i].events &= ~EPOLLIN; + } + } + + *events = t->events; + return t->nb_events; + } + + int itti_get_events(task_id_t task_id, struct epoll_event **events) { + pthread_mutex_lock(&tasks[task_id].queue_cond_lock); + return itti_get_events_locked(task_id, events); + } + + void itti_receive_msg(task_id_t task_id, MessageDef **received_msg) { + // Reception of one message, blocking caller + task_list_t *t=&tasks[task_id]; + pthread_mutex_lock(&t->queue_cond_lock); + + // Weird condition to deal with crap legacy itti interface + if ( t->nb_fd_epoll == 1 ) { + while (t->message_queue.empty()) { + itti_get_events_locked(task_id, &t->events); + pthread_mutex_lock(&t->queue_cond_lock); + } + } else { + if (t->message_queue.empty()) { + itti_get_events_locked(task_id, &t->events); + pthread_mutex_lock(&t->queue_cond_lock); + } + } + + // Legacy design: we return even if we have no message + // in this case, *received_msg is NULL + if (t->message_queue.empty()) { + *received_msg=NULL; + LOG_D(TMR,"task %s received even from other fd (total fds: %d), returning msg NULL\n",t->admin.name, t->nb_fd_epoll); + } else { + *received_msg=t->message_queue.back(); + t->message_queue.pop_back(); + LOG_D(TMR,"task %s received a message\n",t->admin.name); + } + + pthread_mutex_unlock (&t->queue_cond_lock); + } + + void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) { + //reception of one message, non-blocking + task_list_t *t=&tasks[task_id]; + pthread_mutex_lock(&t->queue_cond_lock); + + if (!t->message_queue.empty()) { + LOG_D(TMR,"task %s received a message in polling mode\n",t->admin.name); + *received_msg=t->message_queue.back(); + t->message_queue.pop_back(); + } else + *received_msg=NULL; + + pthread_mutex_unlock (&t->queue_cond_lock); + } + + int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) { + task_list_t *t=&tasks[task_id]; + AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0, + "Thread creation for task %d failed!\n", task_id); + pthread_setname_np( t->thread, itti_get_task_name(task_id) ); + LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) ); +#if 1 // BMC test RT prio + { + int policy; + struct sched_param sparam; + memset(&sparam, 0, sizeof(sparam)); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-10; + policy = SCHED_FIFO ; + if (pthread_setschedparam(t->thread, policy, &sparam) != 0) { + LOG_E(TMR,"task %s : Failed to set pthread priority\n", itti_get_task_name(task_id) ); + } + } +#endif + return 0; + } + + void itti_exit_task(void) { + pthread_exit (NULL); + } + + void itti_terminate_tasks(task_id_t task_id) { + // Sends Terminate signals to all tasks. + itti_send_terminate_message (task_id); + usleep(100*1000); // Allow the tasks to receive the message before going returning to main thread + } + + int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, + const message_info_t *messages_info) { + AssertFatal(TASK_MAX<UINT16_MAX, "Max itti tasks"); + + for(int i=0; i<task_max; ++i) { + LOG_I(TMR,"Starting itti queue: %s as task %d\n", tasks_info[i].name, i); + pthread_mutex_init(&tasks[i].queue_cond_lock, NULL); + memcpy(&tasks[i].admin, &tasks_info[i], sizeof(task_info_t)); + AssertFatal( ( tasks[i].epoll_fd = epoll_create1(0) ) >=0, ""); + AssertFatal( ( tasks[i].sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, ""); + itti_subscribe_event_fd((task_id_t)i, tasks[i].sem_fd); + + if (tasks[i].admin.threadFunc != NULL) + itti_create_task((task_id_t)i, tasks[i].admin.threadFunc, NULL); + } + + return 0; + } + + int timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + timer_type_t type, + void *timer_arg, + long *timer_id) { + task_list_t *t=&tasks[task_id]; + + do { + // set the taskid in the timer id to keep compatible with the legacy API + // timer_remove() takes only the timer id as parameter + *timer_id=(random()%UINT16_MAX) << 16 | task_id ; + } while ( t->timer_map.find(*timer_id) != t->timer_map.end()); + + /* Allocate new timer list element */ + timer_elm_t timer; + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + + if (interval_us%1000 != 0) + LOG_W(TMR, "Can't set timer precision below 1ms, rounding it\n"); + + timer.duration = interval_sec*1000+interval_us/1000; + timer.timeout= ((uint64_t)tp.tv_sec*1000+tp.tv_nsec/(1000*1000)+timer.duration); + timer.instance = instance; + timer.type = type; + timer.timer_arg = timer_arg; + pthread_mutex_lock (&t->queue_cond_lock); + t->timer_map[*timer_id]= timer; + + if (timer.timeout < t->next_timer) + t->next_timer=timer.timeout; + + eventfd_t sem_counter = 1; + AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), ""); + pthread_mutex_unlock (&t->queue_cond_lock); + return 0; + } + + int timer_remove(long timer_id) { + task_id_t task_id=(task_id_t)(timer_id&0xffff); + int ret; + pthread_mutex_lock (&tasks[task_id].queue_cond_lock); + ret=tasks[task_id].timer_map.erase(timer_id); + pthread_mutex_unlock (&tasks[task_id].queue_cond_lock); + + if (ret==1) + return 0; + else { + LOG_W(TMR, "tried to remove a non existing timer\n"); + return 1; + } + } + + const char *itti_get_message_name(MessagesIds message_id) { + return messages_info[message_id].name; + } + + const char *itti_get_task_name(task_id_t task_id) { + return tasks[task_id].admin.name; + } + + // void for compatibility + void itti_send_terminate_message(task_id_t task_id) { + } + + void itti_wait_tasks_end(void) { + while(1) + sleep(24*3600); + } + + void itti_update_lte_time(uint32_t frame, uint8_t slot) {} + void itti_set_task_real_time(task_id_t task_id) {} + void itti_mark_task_ready(task_id_t task_id) { + // Function meaning is clear, but legacy implementation is wrong + // keep it void is fine: today implementation accepts messages in the queue before task is ready + } + void itti_wait_ready(int wait_tasks) { + // Stupid function, kept for compatibility (the parameter is meaningless!!!) + } + int signal_mask(void) { return 0;} +} diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..227e9b0b3e702040f97a1477f50dd133b31209c3 --- /dev/null +++ b/common/utils/ocp_itti/intertask_interface.h @@ -0,0 +1,541 @@ +/* + Author: Laurent THOMAS, Open Cells + Copyleft: OpenAirInterface software alliance and it's licence +*/ +#ifndef INTERTASK_INTERFACE_H_ +#define INTERTASK_INTERFACE_H_ +#include <stdint.h> +#include <sys/epoll.h> + +#include <mem_block.h> +#include <assertions.h> + + +typedef enum timer_type_s { + TIMER_PERIODIC, + TIMER_ONE_SHOT, + TIMER_TYPE_MAX, +} timer_type_t; + +typedef struct { + void *arg; + long timer_id; +} timer_has_expired_t; + +typedef struct { + uint32_t interval_sec; + uint32_t interval_us; + long task_id; + int32_t instance; + timer_type_t type; + void *timer_arg; + long timer_id; +} timer_create_t; + +typedef struct { + long task_id; + long timer_id; +} timer_delete_t; + + +typedef struct itti_lte_time_s { + uint32_t frame; + uint8_t slot; +} itti_lte_time_t; + + +typedef struct IttiMsgEmpty_s { +} IttiMsgEmpty; + +typedef struct IttiMsgText_s { + uint32_t size; + char text[]; +} IttiMsgText; + +#include <openair2/COMMON/phy_messages_types.h> +#include <openair2/COMMON/mac_messages_types.h> +#include <openair2/COMMON/rlc_messages_types.h> +#include <openair2/COMMON/pdcp_messages_types.h> +#include <openair2/COMMON/networkDef.h> +#include <openair2/COMMON/as_message.h> +#include <openair2/RRC/LTE/rrc_types.h> +#include <openair2/COMMON/rrc_messages_types.h> + +#include <openair3/NAS/COMMON/UTIL/OctetString.h> +#include <openair3/NAS/COMMON/IES/AccessPointName.h> +#include <openair3/NAS/COMMON/IES/AdditionalUpdateResult.h> +#include <openair3/NAS/COMMON/IES/AdditionalUpdateType.h> +#include <openair3/NAS/COMMON/IES/ApnAggregateMaximumBitRate.h> +#include <openair3/NAS/COMMON/IES/AuthenticationFailureParameter.h> +#include <openair3/NAS/COMMON/IES/AuthenticationParameterAutn.h> +#include <openair3/NAS/COMMON/IES/AuthenticationParameterRand.h> +#include <openair3/NAS/COMMON/IES/AuthenticationResponseParameter.h> +#include <openair3/NAS/COMMON/IES/CipheringKeySequenceNumber.h> +#include <openair3/NAS/COMMON/IES/Cli.h> +#include <openair3/NAS/COMMON/IES/CsfbResponse.h> +#include <openair3/NAS/COMMON/IES/DaylightSavingTime.h> +#include <openair3/NAS/COMMON/IES/DetachType.h> +#include <openair3/NAS/COMMON/IES/DrxParameter.h> +#include <openair3/NAS/COMMON/IES/EmergencyNumberList.h> +#include <openair3/NAS/COMMON/IES/EmmCause.h> +#include <openair3/NAS/COMMON/IES/EpsAttachResult.h> +#include <openair3/NAS/COMMON/IES/EpsAttachType.h> +#include <openair3/NAS/COMMON/IES/EpsBearerContextStatus.h> +#include <openair3/NAS/COMMON/IES/EpsBearerIdentity.h> +#include <openair3/NAS/COMMON/IES/EpsMobileIdentity.h> +#include <openair3/NAS/COMMON/IES/EpsNetworkFeatureSupport.h> +#include <openair3/NAS/COMMON/IES/EpsQualityOfService.h> +#include <openair3/NAS/COMMON/IES/EpsUpdateResult.h> +#include <openair3/NAS/COMMON/IES/EpsUpdateType.h> +#include <openair3/NAS/COMMON/IES/EsmCause.h> +#include <openair3/NAS/COMMON/IES/EsmInformationTransferFlag.h> +#include <openair3/NAS/COMMON/IES/EsmMessageContainer.h> +#include <openair3/NAS/COMMON/IES/GprsTimer.h> +#include <openair3/NAS/COMMON/IES/GutiType.h> +#include <openair3/NAS/COMMON/IES/IdentityType2.h> +#include <openair3/NAS/COMMON/IES/ImeisvRequest.h> +#include <openair3/NAS/COMMON/IES/KsiAndSequenceNumber.h> +#include <openair3/NAS/COMMON/IES/LcsClientIdentity.h> +#include <openair3/NAS/COMMON/IES/LcsIndicator.h> +#include <openair3/NAS/COMMON/IES/LinkedEpsBearerIdentity.h> +#include <openair3/NAS/COMMON/IES/LlcServiceAccessPointIdentifier.h> +#include <openair3/NAS/COMMON/IES/LocationAreaIdentification.h> +#include <openair3/NAS/COMMON/IES/MessageType.h> +#include <openair3/NAS/COMMON/IES/MobileIdentity.h> +#include <openair3/NAS/COMMON/IES/MobileStationClassmark2.h> +#include <openair3/NAS/COMMON/IES/MobileStationClassmark3.h> +#include <openair3/NAS/COMMON/IES/MsNetworkCapability.h> +#include <openair3/NAS/COMMON/IES/MsNetworkFeatureSupport.h> +#include <openair3/NAS/COMMON/IES/NasKeySetIdentifier.h> +#include <openair3/NAS/COMMON/IES/NasMessageContainer.h> +#include <openair3/NAS/COMMON/IES/NasRequestType.h> +#include <openair3/NAS/COMMON/IES/NasSecurityAlgorithms.h> +#include <openair3/NAS/COMMON/IES/NetworkName.h> +#include <openair3/NAS/COMMON/IES/Nonce.h> +#include <openair3/NAS/COMMON/IES/PacketFlowIdentifier.h> +#include <openair3/NAS/COMMON/IES/PagingIdentity.h> +#include <openair3/NAS/COMMON/IES/PdnAddress.h> +#include <openair3/NAS/COMMON/IES/PdnType.h> +#include <openair3/NAS/COMMON/IES/PlmnList.h> +#include <openair3/NAS/COMMON/IES/ProcedureTransactionIdentity.h> +#include <openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.h> +#include <openair3/NAS/COMMON/IES/ProtocolDiscriminator.h> +#include <openair3/NAS/COMMON/IES/PTmsiSignature.h> +#include <openair3/NAS/COMMON/IES/QualityOfService.h> +#include <openair3/NAS/COMMON/IES/RadioPriority.h> +#include <openair3/NAS/COMMON/IES/SecurityHeaderType.h> +#include <openair3/NAS/COMMON/IES/ServiceType.h> +#include <openair3/NAS/COMMON/IES/ShortMac.h> +#include <openair3/NAS/COMMON/IES/SsCode.h> +#include <openair3/NAS/COMMON/IES/SupportedCodecList.h> +#include <openair3/NAS/COMMON/IES/TimeZoneAndTime.h> +#include <openair3/NAS/COMMON/IES/TimeZone.h> +#include <openair3/NAS/COMMON/IES/TmsiStatus.h> +#include <openair3/NAS/COMMON/IES/TrackingAreaIdentity.h> +#include <openair3/NAS/COMMON/IES/TrackingAreaIdentityList.h> +#include <openair3/NAS/COMMON/IES/TrafficFlowAggregateDescription.h> +#include <openair3/NAS/COMMON/IES/TrafficFlowTemplate.h> +#include <openair3/NAS/COMMON/IES/TransactionIdentifier.h> +#include <openair3/NAS/COMMON/IES/UeNetworkCapability.h> +#include <openair3/NAS/COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.h> +#include <openair3/NAS/COMMON/IES/UeSecurityCapability.h> +#include <openair3/NAS/COMMON/IES/VoiceDomainPreferenceAndUeUsageSetting.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceAllocationReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceAllocationRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceModificationReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceModificationRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/DeactivateEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/DeactivateEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/esm_cause.h> +#include <openair3/NAS/COMMON/ESM/MSG/EsmInformationRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/EsmInformationResponse.h> +#include <openair3/NAS/COMMON/ESM/MSG/EsmStatus.h> +#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnConnectivityReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnConnectivityRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnDisconnectReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnDisconnectRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/esm_msgDef.h> +#include <openair3/NAS/COMMON/ESM/MSG/esm_msg.h> + +#include <openair3/NAS/COMMON/EMM/MSG/AttachAccept.h> +#include <openair3/NAS/COMMON/EMM/MSG/AttachComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/AttachReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/AttachRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationFailure.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationResponse.h> +#include <openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h> +#include <openair3/NAS/COMMON/EMM/MSG/DetachAccept.h> +#include <openair3/NAS/COMMON/EMM/MSG/DetachRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/DownlinkNasTransport.h> +#include <openair3/NAS/COMMON/EMM/MSG/emm_cause.h> +#include <openair3/NAS/COMMON/EMM/MSG/EmmInformation.h> +#include <openair3/NAS/COMMON/EMM/MSG/EmmStatus.h> +#include <openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/GutiReallocationCommand.h> +#include <openair3/NAS/COMMON/EMM/MSG/GutiReallocationComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/IdentityRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/IdentityResponse.h> +#include <openair3/NAS/COMMON/EMM/MSG/NASSecurityModeCommand.h> +#include <openair3/NAS/COMMON/EMM/MSG/NASSecurityModeComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/SecurityModeReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/ServiceReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/ServiceRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateAccept.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/UplinkNasTransport.h> +#include <openair3/NAS/COMMON/EMM/MSG/emm_msgDef.h> +#include <openair3/NAS/COMMON/EMM/MSG/emm_msg.h> + +#include <openair3/NAS/COMMON/API/NETWORK/nas_message.h> +#include <openair2/COMMON/nas_messages_types.h> +#if ENABLE_RAL + #include <ral_messages_types.h> +#endif +#include <openair2/COMMON/s1ap_messages_types.h> +#include <openair2/COMMON/x2ap_messages_types.h> +#include <openair2/COMMON/sctp_messages_types.h> +#include <openair2/COMMON/udp_messages_types.h> +#include <openair2/COMMON/gtpv1_u_messages_types.h> +#include <openair3/SCTP/sctp_eNB_task.h> +#include <openair3/NAS/UE/nas_proc_defs.h> +#include <openair3/NAS/UE/ESM/esmData.h> +#include <openair3/NAS/COMMON/UTIL/nas_timer.h> +#include <openair3/NAS/UE/ESM/esm_pt_defs.h> +#include <openair3/NAS/UE/EMM/emm_proc_defs.h> +#include <openair3/NAS/UE/EMM/emmData.h> +#include <openair3/NAS/UE/EMM/IdleMode_defs.h> +#include <openair3/NAS/UE/EMM/emm_fsm_defs.h> +#include <openair3/NAS/UE/EMM/emmData.h> +#include <openair3/NAS/COMMON/securityDef.h> +#include <openair3/NAS/UE/EMM/Authentication.h> +#include <openair3/NAS/UE/EMM/SecurityModeControl.h> +#include <openair3/NAS/UE/API/USIM/usim_api.h> +#include <openair3/NAS/COMMON/userDef.h> +#include <openair3/NAS/UE/API/USER/at_command.h> +#include <openair3/NAS/UE/API/USER/at_response.h> +#include <openair3/NAS/UE/API/USER/user_api_defs.h> +#include <openair3/NAS/UE/EMM/LowerLayer_defs.h> +#include <openair3/NAS/UE/user_defs.h> +#include <openair3/NAS/UE/nas_ue_task.h> +#include <openair3/S1AP/s1ap_eNB.h> +//#include <proto.h> + +#include <openair3/GTPV1-U/gtpv1u_eNB_task.h> +void *rrc_enb_process_itti_msg(void *); +#include <openair3/SCTP/sctp_eNB_task.h> +#include <openair3/S1AP/s1ap_eNB.h> + +/* + static const char *const messages_definition_xml = { + #include <messages_xml.h> + }; +*/ + +typedef uint32_t MessageHeaderSize; +typedef uint32_t itti_message_types_t; +typedef unsigned long message_number_t; +#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long)) + +typedef enum task_priorities_e { + TASK_PRIORITY_MAX = 100, + TASK_PRIORITY_MAX_LEAST = 85, + TASK_PRIORITY_MED_PLUS = 70, + TASK_PRIORITY_MED = 55, + TASK_PRIORITY_MED_LEAST = 40, + TASK_PRIORITY_MIN_PLUS = 25, + TASK_PRIORITY_MIN = 10, +} task_priorities_t; + +typedef struct { + task_priorities_t priority; + unsigned int queue_size; + /* Printable name */ + char name[256]; + void *(*func)(void *) ; + void *(*threadFunc)(void *) ; +} task_info_t; +// +//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL) +//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) +//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL) +//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL) + +#define FOREACH_TASK(TASK_DEF) \ + TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \ + TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \ + TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX, 200, NULL, NULL) \ + TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MAC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\ + 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_SCTP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_ENB_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) \ + TASK_DEF(TASK_RLC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PDCP_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\ + TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\ + TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)\ + TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL) + +#define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc }, + +/* Map task id to printable name. */ +static const task_info_t tasks_info[] = { + FOREACH_TASK(TASK_DEF) +}; + +#define TASK_ENUM(TaskID, pRIO, qUEUEsIZE, FuNc,ThreadFunc ) TaskID, +//! Tasks id of each task +typedef enum { + FOREACH_TASK(TASK_ENUM) +} task_id_t; + + +typedef task_id_t thread_id_t; + +typedef enum message_priorities_e { + MESSAGE_PRIORITY_MAX = 100, + MESSAGE_PRIORITY_MAX_LEAST = 85, + MESSAGE_PRIORITY_MED_PLUS = 70, + MESSAGE_PRIORITY_MED = 55, + MESSAGE_PRIORITY_MED_LEAST = 40, + MESSAGE_PRIORITY_MIN_PLUS = 25, + MESSAGE_PRIORITY_MIN = 10, +} message_priorities_t; + + +#define FOREACH_MSG(INTERNAL_MSG) \ + INTERNAL_MSG(TIMER_HAS_EXPIRED, MESSAGE_PRIORITY_MED, timer_has_expired_t, timer_has_expired) \ + INTERNAL_MSG(INITIALIZE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, initialize_message) \ + INTERNAL_MSG(ACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, activate_message) \ + INTERNAL_MSG(DEACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, deactivate_message) \ + INTERNAL_MSG(TERMINATE_MESSAGE, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, terminate_message) \ + INTERNAL_MSG(MESSAGE_TEST, MESSAGE_PRIORITY_MED, IttiMsgEmpty, message_test) + +/* This enum defines messages ids. Each one is unique. */ +typedef enum { +#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD, + FOREACH_MSG(MESSAGE_DEF) +#include <all_msg.h> +#undef MESSAGE_DEF + MESSAGES_ID_MAX, +} MessagesIds; + +typedef union msg_s { +#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME; + FOREACH_MSG(MESSAGE_DEF) +#include <all_msg.h> +#undef MESSAGE_DEF +} msg_t; + +typedef struct MessageHeader_s { + MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */ + task_id_t originTaskId; /**< ID of the sender task */ + task_id_t destinationTaskId; /**< ID of the destination task */ + instance_t instance; /**< Task instance for virtualization */ + itti_lte_time_t lte_time; + MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */ +} MessageHeader; + +typedef struct message_info_s { + int id; + message_priorities_t priority; + /* Message payload size */ + MessageHeaderSize size; + /* Printable name */ + const char name[256]; +} message_info_t; + +/* Map message id to message information */ +static const message_info_t messages_info[] = { +#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) { iD, pRIO, sizeof(sTRUCT), #iD }, + FOREACH_MSG(MESSAGE_DEF) +#include <all_msg.h> +#undef MESSAGE_DEF +}; + +typedef struct __attribute__ ((__packed__)) MessageDef_s { + MessageHeader ittiMsgHeader; /**< Message header */ + msg_t ittiMsg; +} MessageDef; + + + +/* Extract the instance from a message */ +#define ITTI_MESSAGE_GET_INSTANCE(mESSAGE) ((mESSAGE)->ittiMsgHeader.instance) +#define ITTI_MSG_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.messageId) +#define ITTI_MSG_ORIGIN_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.originTaskId) +#define ITTI_MSG_DESTINATION_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.destinationTaskId) +#define ITTI_MSG_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.instance) +#define ITTI_MSG_NAME(mSGpTR) itti_get_message_name(ITTI_MSG_ID(mSGpTR)) +#define ITTI_MSG_ORIGIN_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_ORIGIN_ID(mSGpTR)) +#define ITTI_MSG_DESTINATION_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_DESTINATION_ID(mSGpTR)) +#define TIMER_HAS_EXPIRED(mSGpTR) (mSGpTR)->ittiMsg.timer_has_expired + +#define INSTANCE_DEFAULT (UINT16_MAX - 1) + +static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end) { + return (int64_t)( end.tv_sec-start.tv_sec) * (int64_t)(1000*1000*1000) + end.tv_nsec-start.tv_nsec; +} + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Send a message to a task (could be itself) + \param task_id Task ID + \param instance Instance of the task used for virtualization + \param message Pointer to the message to send + @returns -1 on failure, 0 otherwise + **/ +int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); + +/** \brief Add a new fd to monitor. + NOTE: it is up to the user to read data associated with the fd + \param task_id Task ID of the receiving task + \param fd The file descriptor to monitor + **/ +void itti_subscribe_event_fd(task_id_t task_id, int fd); + +/** \brief Remove a fd from the list of fd to monitor + \param task_id Task ID of the task + \param fd The file descriptor to remove + **/ +void itti_unsubscribe_event_fd(task_id_t task_id, int fd); + +/** \brief Return the list of events excluding the fd associated with itti + \param task_id Task ID of the task + \param events events list + @returns number of events to handle + **/ +int itti_get_events(task_id_t task_id, struct epoll_event **events); + +/** \brief Retrieves a message in the queue associated to task_id. + If the queue is empty, the thread is blocked till a new message arrives. + \param task_id Task ID of the receiving task + \param received_msg Pointer to the allocated message + **/ +void itti_receive_msg(task_id_t task_id, MessageDef **received_msg); + +/** \brief Try to retrieves a message in the queue associated to task_id. + \param task_id Task ID of the receiving task + \param received_msg Pointer to the allocated message + **/ +void itti_poll_msg(task_id_t task_id, MessageDef **received_msg); + +/** \brief Start thread associated to the task + \param task_id task to start + \param start_routine entry point for the task + \param args_p Optional argument to pass to the start routine + @returns -1 on failure, 0 otherwise + **/ +int itti_create_task(task_id_t task_id, + void *(*start_routine) (void *), + void *args_p); + +/** \brief Exit the current task. + **/ +void itti_exit_task(void); + +/** \brief Initiate termination of all tasks. + \param task_id task that is completed + **/ +void itti_terminate_tasks(task_id_t task_id); + +// Void for legacy compatibility +void itti_wait_ready(int wait_tasks); +void itti_mark_task_ready(task_id_t task_id); + +/** \brief Return the printable string associated with the message + \param message_id Id of the message + **/ +const char *itti_get_message_name(MessagesIds message_id); + +/** \brief Return the printable string associated with a task id + \param thread_id Id of the task + **/ +const char *itti_get_task_name(task_id_t task_id); + +/** \brief Alloc and memset(0) a new itti message. + \param origin_task_id Task ID of the sending task + \param message_id Message ID + @returns NULL in case of failure or newly allocated mesage ref + **/ +MessageDef *itti_alloc_new_message( + task_id_t origin_task_id, + MessagesIds message_id); + +/** \brief Alloc and memset(0) a new itti message. + \param origin_task_id Task ID of the sending task + \param message_id Message ID + \param size size of the payload to send + @returns NULL in case of failure or newly allocated mesage ref + **/ +MessageDef *itti_alloc_new_message_sized( + task_id_t origin_task_id, + MessagesIds message_id, + MessageHeaderSize size); + +/** \brief handle signals and wait for all threads to join when the process complete. + This function should be called from the main thread after having created all ITTI tasks. + **/ +void itti_wait_tasks_end(void); +#define THREAD_MAX 0 //for compatibility +void itti_set_task_real_time(task_id_t task_id); + +/** \brief Send a termination message to all tasks. + \param task_id task that is broadcasting the message. + **/ +void itti_send_terminate_message(task_id_t task_id); + +void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size); +void *calloc_or_fail(size_t size); +void *malloc_or_fail(size_t size); +int memory_read(const char *datafile, void *data, size_t size); +int itti_free(task_id_t task_id, void *ptr); + +int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, + const message_info_t *messages_info); +int timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + timer_type_t type, + void *timer_arg, + long *timer_id); + + +int timer_remove(long timer_id); +#define timer_stop timer_remove +int signal_handle(int *end); + +#ifdef __cplusplus +} +#endif +#endif /* INTERTASK_INTERFACE_H_ */ diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 519c222114bff7f06f95da8d9de8036f6fa02b29..3b423bd4655e47d15e711e972c4b5d722dbcafec 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -199,28 +199,29 @@ int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt) print_threads(buf,debug,prnt); } if (strcasestr(buf,"loglvl") != NULL) { - prnt(" component level enabled\n"); + prnt("\n component level enabled output\n"); for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { if (g_log->log_component[i].name != NULL) { - prnt("%02i %17.17s:%10.10s %s\n",i ,g_log->log_component[i].name, - map_int_to_str(log_level_names,g_log->log_component[i].level), - ((g_log->log_component[i].interval>0)?"Y":"N") ); + prnt("%02i %17.17s:%10.10s %s %s\n",i ,g_log->log_component[i].name, + map_int_to_str(log_level_names,(g_log->log_component[i].level>=0)?g_log->log_component[i].level:g_log->log_component[i].savedlevel), + ((g_log->log_component[i].level>=0)?"Y":"N"), + ((g_log->log_component[i].filelog>0)?g_log->log_component[i].filelog_name:"stdout")); } } } if (strcasestr(buf,"logopt") != NULL) { - prnt(" option enabled\n"); + prnt("\n option enabled\n"); for (int i=0; log_options[i].name != NULL; i++) { prnt("%02i %17.17s %10.10s \n",i ,log_options[i].name, ((g_log->flag & log_options[i].value)?"Y":"N") ); } } if (strcasestr(buf,"dbgopt") != NULL) { - prnt(" option debug matlab\n"); + prnt("\n module debug dumpfile\n"); for (int i=0; log_maskmap[i].name != NULL ; i++) { - prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name, + prnt("%02i %17.17s %5.5s %5.5s\n",i ,log_maskmap[i].name, ((g_log->debug_mask & log_maskmap[i].value)?"Y":"N"), - ((g_log->matlab_mask & log_maskmap[i].value)?"Y":"N") ); + ((g_log->dump_mask & log_maskmap[i].value)?"Y":"N") ); } } if (strcasestr(buf,"config") != NULL) { @@ -302,8 +303,6 @@ char sv1[64]; } int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt) { -extern void exit_fun(const char* s); - if (debug > 0) prnt("process module received %s\n",buf); @@ -337,15 +336,15 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); prnt("Available log levels: \n "); for (int i=0; log_level_names[i].name != NULL; i++) prnt("%s ",log_level_names[i].name); - prnt("\n"); + prnt("\n\n"); prnt("Available display options: \n "); for (int i=0; log_options[i].name != NULL; i++) prnt("%s ",log_options[i].name); - prnt("\n"); - prnt("Available debug or matlab options: \n "); + prnt("\n\n"); + prnt("Available debug and dump options: \n "); for (int i=0; log_maskmap[i].name != NULL; i++) prnt("%s ",log_maskmap[i].name); - prnt("\n"); + prnt("\n\n"); proccmd_show("loglvl",debug,prnt); proccmd_show("logopt",debug,prnt); proccmd_show("dbgopt",debug,prnt); @@ -377,7 +376,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); else if (l == 2 && strcmp(logparam,"debug") == 0){ optbit=map_str_to_int(log_maskmap,opt); if (optbit < 0) { - prnt("debug flag %s unknown\n",opt); + prnt("module %s unknown\n",opt); } else { if (idx1 > 0) SET_LOG_DEBUG(optbit); @@ -386,42 +385,51 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); proccmd_show("dbgopt",debug,prnt); } } - else if (l == 2 && strcmp(logparam,"matlab") == 0){ + else if (l == 2 && strcmp(logparam,"dump") == 0){ optbit=map_str_to_int(log_maskmap,opt); if (optbit < 0) { - prnt("matlab flag %s unknown\n",opt); + prnt("module %s unknown\n",opt); } else { if (idx1 > 0) - SET_LOG_MATLAB(optbit); + SET_LOG_DUMP(optbit); else - CLEAR_LOG_MATLAB(optbit); + CLEAR_LOG_DUMP(optbit); proccmd_show("dbgopt",debug,prnt); } } if (logparam != NULL) free(logparam); if (opt != NULL) free(opt); } else if ( s == 3 && logsubcmd != NULL) { - int level, interval; + int level, enable,filelog; char *tmpstr=NULL; char *logparam=NULL; int l; - level = interval = -1; + level = OAILOG_DISABLE - 1; + filelog = -1; + enable=-1; l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr); if (debug > 0) prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr)); if (l ==2 ) { if (strcmp(logparam,"level") == 0) { level=map_str_to_int(log_level_names,tmpstr); - if (level < 0) prnt("level %s unknown\n",tmpstr); + if (level < 0) { + prnt("level %s unknown\n",tmpstr); + level=OAILOG_DISABLE - 1; + } } else { prnt("%s%s unknown log sub command \n",logparam, tmpstr); } } else if (l ==1 ) { if (strcmp(logparam,"enable") == 0) { - interval = 1; + enable=1; } else if (strcmp(logparam,"disable") == 0) { - interval = 0; + level=OAILOG_DISABLE; + } else if (strcmp(logparam,"file") == 0) { + filelog = 1 ; + } else if (strcmp(logparam,"nofile") == 0) { + filelog = 0 ; } else { prnt("%s%s unknown log sub command \n",logparam, tmpstr); } @@ -431,20 +439,18 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); if (logparam != NULL) free(logparam); if (tmpstr != NULL) free(tmpstr); for (int i=idx1; i<=idx2 ; i++) { - if (level < 0) { - level=g_log->log_component[i].level; - } - if (interval < 0) { - interval=g_log->log_component[i].interval; - } - set_log(i, level, interval); - prnt("log level comp %i %s set to %s (%s)\n", - i,((g_log->log_component[i].name==NULL)?"":g_log->log_component[i].name), - map_int_to_str(log_level_names,g_log->log_component[i].level), - ((g_log->log_component[i].interval>0)?"enabled":"disabled")); - - - } + if (level >= OAILOG_DISABLE) + set_log(i, level); + else if ( enable == 1) + set_log(i,g_log->log_component[i].savedlevel); + else if ( filelog == 1 ) { + set_component_filelog(i); + } else if ( filelog == 0 ) { + close_component_filelog(i); + } + + } + proccmd_show("loglvl",debug,prnt); } else { prnt("%s: wrong log command...\n",buf); } diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h index 409484455ce9a9d5c0a7e24717f1964fc04d8947..1a0a8d25dc4006c74f5b9afe3c2b82db94db7e45 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.h +++ b/common/utils/telnetsrv/telnetsrv_proccmd.h @@ -48,13 +48,15 @@ telnetshell_vardef_t proc_vardef[] = { show: display current log configuration \n\ online, noonline: enable or disable console logs \n\ enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\ + file, nofile id1-id2: enable or disable redirecting logs to file for components index id1 to id2 \n\ + logfile name depends on component name and is printed in the show command \n\ level_<level> id1-id2: set log level to <level> for components index id1 to id2 \n\ -use the show command to get the authorized values for <level> and the list of component \ -indexes that can be used for id1 and id2 \n\ + use the show command to get the authorized values for \n\ + <level> and the list of component indexes that can be used for id1 and id2 \n\ print_<opt> <0|1> disable or enable the \"opt\" log option, use the show command to get \ -the available options\n\ - matlab_<opt> debug_<func> disable or enable the debug code or matlab file generation \ -for \"func\" function. use the show command to get the available options\n" + the available options\n\ + dump_<mod> debug_<mod > disable or enable the debug file generation or debug code\ + for \"mod\" module. use the show command to get the available modules\n" #define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\ <thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\ diff --git a/openair1/PHY/CODING/coding_load.c b/openair1/PHY/CODING/coding_load.c index a895d9648ec8530b06a1728bc401a1c7e837335c..30b876c654789db2d68584e420840d47495dfc7d 100644 --- a/openair1/PHY/CODING/coding_load.c +++ b/openair1/PHY/CODING/coding_load.c @@ -130,7 +130,7 @@ int load_codinglib(void) { shlib_fdesc[ENCODE_SSE_FPTRIDX].fname= "threegpplte_turbo_encoder_sse"; shlib_fdesc[ENCODE_C_FPTRIDX].fname= "threegpplte_turbo_encoder"; shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fname= "init_encoder_sse"; - ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR); + ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR,NULL); if (ret < 0) exit_fun("Error loading coding library"); /* execute encoder/decoder init functions */ diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index e64eda740ca0a9bd8b73335392373e5728c62da4..1bb36bd2e52f295b4f3165bb66559a1c632ad70f 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -1,23 +1,23 @@ /* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ------------------------------------------------------------------------------- + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org +*/ /*!\brief Initilization and reconfiguration routines for LTE PHY */ #include "phy_init.h" @@ -27,12 +27,11 @@ #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h" -void generate_64qam_table(void) -{ +void init_sss(void); +void generate_64qam_table(void) { int a,b,c,index; - for (a=-1; a<=1; a+=2) for (b=-1; b<=1; b+=2) for (c=-1; c<=1; c+=2) { @@ -41,9 +40,7 @@ void generate_64qam_table(void) } } -void generate_16qam_table(void) -{ - +void generate_16qam_table(void) { int a,b,index; for (a=-1; a<=1; a+=2) @@ -53,54 +50,42 @@ void generate_16qam_table(void) } } -void generate_qpsk_table(void) -{ - +void generate_qpsk_table(void) { int a,index; for (a=-1; a<=1; a+=2) { index = (1+a)/2; - qpsk_table[index] = -a*QPSK; + qpsk_table[index] = -a*QPSK; } } -void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) -{ - +void init_7_5KHz(void); +void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { ccodelte_init(); ccodelte_init_inv(); - init_dfts(); - - phy_generate_viterbi_tables_lte(); - load_codinglib(); lte_sync_time_init(frame_parms); - generate_ul_ref_sigs(); generate_ul_ref_sigs_rx(); - generate_64qam_table(); generate_16qam_table(); generate_qpsk_table(); generate_RIV_tables(); - init_unscrambling_lut(); init_scrambling_lut(); //set_taus_seed(1328); - - +// init_7_5KHz(); + init_sss(); } -void free_lte_top(void) -{ +void free_lte_top(void) { free_codinglib(); lte_sync_time_free(); - /* free_ul_ref_sigs() is called in phy_free_lte_eNB() */ } /* - * @}*/ + @}*/ diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index cbae84f56b6c1643884468f09fbc52db0df62694..bec08732769d0758332f4231fd3b7b4a2f9da721 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -450,11 +450,11 @@ void phy_config_sib2_eNB(uint8_t Mod_id, } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == 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[0]| + 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[2]<<16); + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } } diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index 1ceed40f8b6e901134d8c0dcaad9b335ee6a31aa..3a1364620ed6d18e3134dcb9534f32e4a26487e2 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -31,6 +31,8 @@ #include "assertions.h" #include <math.h> +void init_7_5KHz(void); + int phy_init_RU(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; @@ -65,6 +67,7 @@ int phy_init_RU(RU_t *ru) { } if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing + init_7_5KHz(); LOG_I(PHY,"nb_tx %d\n",ru->nb_tx); ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); for (i=0;i<ru->nb_rx;i++) { diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 62d768a50aeee992662826aff4928d8c5d1e5e08..bcdd782073f47b16e8be9050b547065d9d3f1342 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -34,6 +34,8 @@ #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/LTE_REFSIG/lte_refsig.h" +void init_7_5KHz(void); + uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10}; extern uint8_t nfapi_mode; @@ -165,11 +167,11 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == 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[0]| + 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[2]<<16); + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } } @@ -662,6 +664,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, init_frame_parms(&ue->frame_parms,1); init_lte_top(&ue->frame_parms); + init_7_5KHz(); init_ul_hopping(&ue->frame_parms); diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 0830058a8fb4bda41bb692a4e29b9aa460fb7104..dd8c2e54dba3f4229fae2c3eb9f1e24076364c33 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -169,6 +169,13 @@ void lte_param_init(PHY_VARS_eNB **eNBp, } else ru->N_TA_offset=0; +#if BASIC_SIMULATOR + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + UE->N_TA_offset = 0; +#endif + printf("Done lte_param_init\n"); diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c index 3b8a26125d43fda03bb8a86f1460277a73bd42a5..03f226c6379098a05a56f92ce286db5a83a9d0bb 100644 --- a/openair1/PHY/INIT/lte_parms.c +++ b/openair1/PHY/INIT/lte_parms.c @@ -20,7 +20,7 @@ */ #include "phy_init.h" -#include "log.h" +#include "common/utils/LOG/log.h" uint16_t dl_S_table_normal[10]={3,9,10,11,12,3,9,10,11,6}; uint16_t dl_S_table_extended[10]={3,8,9,10,3,8,9,5,0,0}; diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c index e268a5b061c0e06031681909be23cfbb4acc87cd..516cb32999b505aa08f1e36c2c23a1d08c747288 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c @@ -61,8 +61,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, temp = 0; for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)]; - Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)]; + Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)]; + Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -81,7 +81,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment max_pos_fil = max_pos; - if(subframe == 6) + if(subframe == 5) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c index 732db1fa4e533998a83ede51735111520df19042..c912c8893482c1c00c47b73128a0e7de5b73a052 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c @@ -62,8 +62,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, temp = 0; for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)]; - Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)]; + Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)]; + Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -82,7 +82,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment max_pos_fil = max_pos; - if(subframe == 6) + if(subframe == 5) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index ae33722c90dea75f86bf7bb43cd34f4d21f07c42..87abdfe19cb67567344ec6507b807290c8a2e33e 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -274,11 +274,11 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com -LOG_M_BEGIN(DEBUG_LTEESTIM); - LOG_M("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1); - LOG_M("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1); - LOG_M("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1); -LOG_M_END + if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){ + LOG_M("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1); + LOG_M("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1); + LOG_M("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1); + } return (1); } @@ -460,18 +460,18 @@ int lte_sync_time(int **rxdata, ///rx data in time domain LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2); -LOG_M_BEGIN(DEBUG_LTEESTIM) -static int debug_cnt; - if (debug_cnt == 0) { - LOG_M("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2); - LOG_M("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2); - LOG_M("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2); - LOG_M("rxdata0.m","rxd0",rxdata[0],length<<1,1,1); - // exit(-1); - } else { + if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){ + static int debug_cnt; + if (debug_cnt == 0) { + LOG_M("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2); + LOG_M("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2); + LOG_M("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2); + LOG_M("rxdata0.m","rxd0",rxdata[0],length<<1,1,1); + // exit(-1); + } else { debug_cnt++; } -LOG_M_END +} return(peak_pos); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index bf228021452834bb65f3dddf8bfa3a168b367c95..2e4f3e60361eeb564e376435a34fcd8b9443982c 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -23,7 +23,7 @@ #include "PHY/defs_UE.h" #include "PHY/phy_extern_ue.h" -#include "log.h" +#include "common/utils/LOG/log.h" #include "PHY/sse_intrin.h" //#define k1 1000 diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index e5b28ff2e3caebafc87d0003ab1cebf3cc8cc28c..a8d73cfdea4efd724d8c54a0e0923380e8a16379 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -91,7 +91,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); eNB->ulsch[UE_id]->harq_processes[harq_pid]->n_DMRS2 + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+Ns]) % 12; - Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints); + Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 34, sizeof(uint16_t), compareints); if (Msc_idx_ptr) Msc_RS_idx = Msc_idx_ptr - dftsizes; diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c b/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c index 1eabfd6c367afa38701d6d82b7f0514d0e8339a2..284a22e2e62567eb1444cca3c410dfcb8dab2251 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c @@ -25,9 +25,9 @@ #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" #include "PHY/impl_defs_top.h" - +#include "common/utils/LOG/log.h" //extern unsigned int lte_gold_table[3][20][2][14]; -//#define DEBUG_DL_CELL_SPEC + @@ -64,7 +64,7 @@ int lte_dl_cell_spec_SS(PHY_VARS_eNB *eNB, else if ((p==1) && (l>0)) nu = 0; else { - printf("lte_dl_cell_spec: p %d, l %d -> ERROR\n",p,l); + LOG_E(PHY,"lte_dl_cell_spec: p %d, l %d -> ERROR\n",p,l); return(-1); } @@ -85,19 +85,19 @@ int lte_dl_cell_spec_SS(PHY_VARS_eNB *eNB, // this is r_mprime from 3GPP 36-211 6.10.1.2 output[k] = qpsk[(eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3]; //output[k] = (lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3; -#ifdef DEBUG_DL_CELL_SPEC - printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n", - Ns,l,m,mprime_dword,mprime_qpsk_symb); - printf("index = %d (k %d)\n",(eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLCELLSPEC)) { + LOG_I(PHY,"Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n", + Ns,l,m,mprime_dword,mprime_qpsk_symb); + LOG_I(PHY,"index = %d (k %d)\n",(eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k); + } mprime++; -#ifdef DEBUG_DL_CELL_SPEC + if (LOG_DEBUGFLAG(DEBUG_DLCELLSPEC)) { if (m<4) - printf("Ns %d, l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); + LOG_I(PHY,"Ns %d, l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); -#endif + } k+=6;//b if (k >= eNB->frame_parms.ofdm_symbol_size) { @@ -105,7 +105,7 @@ int lte_dl_cell_spec_SS(PHY_VARS_eNB *eNB, k-=eNB->frame_parms.ofdm_symbol_size; } - // printf("** k %d\n",k); + // LOG_I(PHY,"** k %d\n",k); } return(0); @@ -143,7 +143,7 @@ int lte_dl_cell_spec(PHY_VARS_eNB *eNB, else if ((p==1) && (l>0)) nu = 0; else { - printf("lte_dl_cell_spec: p %d, l %d -> ERROR\n",p,l); + LOG_E(PHY,"lte_dl_cell_spec: p %d, l %d -> ERROR\n",p,l); return(-1); } @@ -168,27 +168,24 @@ int lte_dl_cell_spec(PHY_VARS_eNB *eNB, // this is r_mprime from 3GPP 36-211 6.10.1.2 output[k] = qpsk[(eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3]; //output[k] = (lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3; -#ifdef DEBUG_DL_CELL_SPEC - printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n", - Ns,l,m,mprime_dword,mprime_qpsk_symb); - printf("index = %d (k %d)\n",(eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k); -#endif - + if (LOG_DEBUGFLAG(DEBUG_DLCELLSPEC)) { + LOG_I(PHY,"Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n", + Ns,l,m,mprime_dword,mprime_qpsk_symb); + LOG_I(PHY,"index = %d (k %d)\n",(eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k); + } mprime++; -#ifdef DEBUG_DL_CELL_SPEC - - if (m<4) - printf("Ns %d, l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); + if (LOG_DEBUGFLAG(DEBUG_DLCELLSPEC)) { + if (m<4) + LOG_I(PHY,"Ns %d, l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); + } -#endif k+=6; - if (k >= eNB->frame_parms.ofdm_symbol_size) { k++; // skip DC carrier k-=eNB->frame_parms.ofdm_symbol_size; } - // printf("** k %d\n",k); + // LOG_I(PHY,"** k %d\n",k); } return(0); @@ -231,21 +228,21 @@ int lte_dl_cell_spec_rx(PHY_VARS_UE *ue, // this is r_mprime from 3GPP 36-211 6.10.1.2 output[k] = qpsk[(ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3]; -#ifdef DEBUG_DL_CELL_SPEC - printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n", - Ns,l,m,mprime_dword,mprime_qpsk_symb); - printf("index = %d (k %d)\n",(ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLCELLSPEC)) { + LOG_I(PHY,"Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n", + Ns,l,m,mprime_dword,mprime_qpsk_symb); + LOG_I(PHY,"index = %d (k %d)\n",(ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k); + } mprime++; -#ifdef DEBUG_DL_CELL_SPEC + if (LOG_DEBUGFLAG(DEBUG_DLCELLSPEC)) { - if (m<4) - printf("Ns %d l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); + if (m<4) + LOG_I(PHY,"Ns %d l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); -#endif - k++; - // printf("** k %d\n",k); + } + k++; + // LOG_I(PHY,"** k %d\n",k); } return(0); diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c index 2c5240e14329452b2c294c8e8bde8b994278531c..1b9c17133c050dceea97d78391659003db3f30d0 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c @@ -36,7 +36,7 @@ #include "lte_refsig.h" #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" -#include "log.h" +#include "common/utils/LOG/log.h" #include "PHY/impl_defs_top.h" //extern unsigned int lte_gold_table[3][20][2][14]; diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c index 14def309b7bdb11043ef66712b0828d5546898d6..69dbb705db8fd4cd85f215f50a63949f5fb88ed1 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c @@ -54,9 +54,9 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl for (l=0; l<3; l++) { if (l==0) - x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + 2 + (7*(1+(sfn>>1)))))<<9); //cinit + x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + 2 + (7*(1+(sfn<<1)))))<<9); //cinit else - x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + ((l-1)<<2) + (7*(2+(sfn>>1)))))<<9); //cinit + x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + ((l-1)<<2) + (7*(2+(sfn<<1)))))<<9); //cinit //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit //n = 0 diff --git a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c index 01b27205c21b619bc273b8ef43309073de21a7e1..ee7619c23c2bf9479b81a9d8e7b221a2e052e9a2 100644 --- a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c +++ b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c @@ -27,13 +27,13 @@ #include "lte_refsig.h" #include "PHY/defs_eNB.h" -uint16_t dftsizes[33] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,864,900,960,972,1080,1152,1200}; +uint16_t dftsizes[34] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,768,864,900,960,972,1080,1152,1200}; -uint16_t ref_primes[33] = {11,23,31,47,59,71,89,107,113,139,179,191,211,239,283,293,317,359,383,431,479,523,571,599,647,719,863,887,953,971,1069,1151,1193}; +uint16_t ref_primes[34] = {11,23,31,47,59,71,89,107,113,139,179,191,211,239,283,293,317,359,383,431,479,523,571,599,647,719,761,863,887,953,971,1069,1151,1193}; -int16_t *ul_ref_sigs[30][2][33]; -int16_t *ul_ref_sigs_rx[30][2][33]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA +int16_t *ul_ref_sigs[30][2][34]; +int16_t *ul_ref_sigs_rx[30][2][34]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA /* 36.211 table 5.5.1.2-1 */ char ref12[360] = {-1,1,3,-3,3,3,1,1,3,1,-3,3,1,1,3,3,3,-1,1,-3,-3,1,-3,3,1,1,-3,-3,-3,-1,-3,-3,1,-3,1,-1,-1,1,1,1,1,-1,-3,-3,1,-3,3,-1,-1,3,1,-1,1,-1,-3,-1,1,-1,1,3,1,-3,3,-1,-1,1,1,-1,-1,3,-3,1,-1,3,-3,-3,-3,3,1,-1,3,3,-3,1,-3,-1,-1,-1,1,-3,3,-1,1,-3,3,1,1,-3,3,1,-1,-1,-1,1,1,3,-1,1,1,-3,-1,3,3,-1,-3,1,1,1,1,1,-1,3,-1,1,1,-3,-3,-1,-3,-3,3,-1,3,1,-1,-1,3,3,-3,1,3,1,3,3,1,-3,1,1,-3,1,1,1,-3,-3,-3,1,3,3,-3,3,-3,1,1,3,-1,-3,3,3,-3,1,-1,-3,-1,3,1,3,3,3,-1,1,3,-1,1,-3,-1,-1,1,1,3,1,-1,-3,1,3,1,-1,1,3,3,3,-1,-1,3,-1,-3,1,1,3,-3,3,-3,-3,3,1,3,-1,-3,3,1,1,-3,1,-3,-3,-1,-1,1,-3,-1,3,1,3,1,-1,-1,3,-3,-1,-3,-1,-1,-3,1,1,1,1,3,1,-1,1,-3,-1,-1,3,-1,1,-3,-3,-3,-3,-3,1,-1,-3,1,1,-3,-3,-3,-3,-1,3,-3,1,-3,3,1,1,-1,-3,-1,-3,1,-1,1,3,-1,1,1,1,3,1,3,3,-1,1,-1,-3,-3,1,1,-3,3,3,1,3,3,1,-3,-1,-1,3,1,3,-3,-3,3,-3,1,-1,-1,3,-1,-3,-3,-1,-3,-1,-3,3,1,-1,1,3,-3,-3,-1,3,-3,3,-1,3,3,-3,3,3,-1,-1,3,-3,-3,-1,-1,-3,-1,3,-3,3,1,-1}; @@ -49,7 +49,7 @@ void generate_ul_ref_sigs(void) unsigned int u,v,Msc_RS,q,m,n; // These are the Zadoff-Chu sequences (for RB 3-100) - for (Msc_RS=2; Msc_RS<33; Msc_RS++) { + for (Msc_RS=2; Msc_RS<34; Msc_RS++) { for (u=0; u<30; u++) { for (v=0; v<2; v++) { qbar = ref_primes[Msc_RS] * (u+1)/(double)31; @@ -119,7 +119,7 @@ void generate_ul_ref_sigs_rx(void) unsigned int u,v,Msc_RS,q,m,n; // These are the complex conjugated Zadoff-Chu sequences quantized to QPSK stored in repeated format (for RB 3-100) - for (Msc_RS=2; Msc_RS<33; Msc_RS++) { + for (Msc_RS=2; Msc_RS<34; Msc_RS++) { for (u=0; u<30; u++) { for (v=0; v<2; v++) { qbar = ref_primes[Msc_RS] * (u+1)/(double)31; @@ -186,7 +186,7 @@ void free_ul_ref_sigs(void) unsigned int u,v,Msc_RS; - for (Msc_RS=0; Msc_RS<33; Msc_RS++) { + for (Msc_RS=0; Msc_RS<34; Msc_RS++) { for (u=0; u<30; u++) { for (v=0; v<2; v++) { if (ul_ref_sigs[u][v][Msc_RS]) { diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 1c015b1c84452beb7f0f9d0f3c3b0ec2fe43d51b..520488664d26289952564d1c1a75b15fbc8c01a0 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -346,6 +346,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, y[0] = &yseq0[0]; y[1] = &yseq1[0]; +#if BASIC_SIMULATOR + /* this should be the normal case + * but it has to be validated for all the various cases + * so let's just do it for the basic simulator + */ + memset(e, 2, DCI_BITS_MAX); +#else #if 1 // reset all bits to <NIL>, here we set <NIL> elements as 2 // memset(e, 2, DCI_BITS_MAX); @@ -358,6 +365,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, * (not sure about this, to be checked somehow) */ //memset(e, 0, DCI_BITS_MAX); +#endif /* BASIC_SIMULATOR */ e_ptr = e; diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c3a309a424f9c422e62045e400d1812323de56b3..c33d9efe63b35dba960f5c9412fac2e607bd2d4e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -220,7 +220,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a break; } - LOG_I(PHY,"%d.%d: DCI 1A: rnti %x, PDCCH order to do PRACH\n", + LOG_T(PHY,"%d.%d: DCI 1A: rnti %x, PDCCH order to do PRACH\n", proc->frame_tx, proc->subframe_tx, rel8->rnti); } @@ -1791,7 +1791,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, #ifdef T_TRACER T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), - T_INT(pdu->dci_pdu_rel8.rnti), T_INT(((frame*10+subframe+4) % 8) /* TODO: correct harq pid */), + T_INT(pdu->dci_pdu_rel8.rnti), T_INT(pdu->dci_pdu_rel8.harq_pid), T_INT(mcs), T_INT(-1 /* TODO: remove round? */), T_INT(pdu->dci_pdu_rel8.resource_block_start), T_INT(pdu->dci_pdu_rel8.number_of_resource_block), diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c index 9a1aa279b0101c428186955d3c07629c01e13215..c1b8ead8e994c75c0ee296bc6c28925f596dddd5 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c @@ -357,28 +357,36 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t break; case 50: - AssertFatal(ra_header==0,"resource type 1 not supported for N_RB_DL=50\n"); + if (ra_header==0) { - for (i=16; i>0; i--) { - if ((rb_alloc&(1<<i)) != 0) - rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32)); + for (i=16; i>0; i--) { + if ((rb_alloc&(1<<i)) != 0) + rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32)); + } + + // bit mask across + if ((rb_alloc2[0]>>31)==1) + rb_alloc2[1] |= 1; + + if ((rb_alloc&1) != 0) + rb_alloc2[1] |= (3<<16); + } + else { + LOG_W(PHY,"resource type 1 not supported for N_RB_DL=50\n"); } - - // bit mask across - if ((rb_alloc2[0]>>31)==1) - rb_alloc2[1] |= 1; - - if ((rb_alloc&1) != 0) - rb_alloc2[1] |= (3<<16); break; case 100: - AssertFatal(ra_header==0,"resource type 1 not supported for N_RB_DL=100\n"); - for (i=0; i<25; i++) { - if ((rb_alloc&(1<<(24-i))) != 0) - rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); - - // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); + if (ra_header==0) { + for (i=0; i<25; i++) { + if ((rb_alloc&(1<<(24-i))) != 0) + rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); + + // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); + } + } + else { + LOG_W(PHY,"resource type 1 not supported for N_RB_DL=100\n"); } break; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index a766bb82023df5caddfea8982a68a5812c8cca20..30c106b16bdabfff7d1671588a94c24eb6519e38 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -57,8 +57,8 @@ uint64_t runtime, uint64_t deadline, uint64_t period);*/ +extern WORKER_CONF_t get_thread_worker_conf(void); -extern int codingw; void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { @@ -363,7 +363,7 @@ void *te_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return(NULL); } - /*if(opp_enabled == 1 && te_wakeup_stats0->diff_now>50*3000){ + /*if(opp_enabled == 1 && te_wakeup_stats0->p_time>50*3000){ print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr); printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); }*/ @@ -573,7 +573,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, } stop_meas(te_wait_stats); - /*if(opp_enabled == 1 && te_wait_stats->diff_now>100*3000){ + /*if(opp_enabled == 1 && te_wait_stats->p_time>100*3000){ print_meas_now(te_wait_stats,"coding_wait",stderr); printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx); }*/ @@ -615,8 +615,10 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, } } - if(C >= 8 && get_nprocs()>=16 && codingw)//one main three worker + if(get_thread_worker_conf() == WORKER_ENABLE) { + if(C >= 8)//one main three worker + { encoding_return = dlsch_encoding_2threads(eNB, a, @@ -632,9 +634,9 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, te_wakeup_stats1, i_stats, 3); - } - else if(C >= 6 && get_nprocs()>=8 && codingw)//one main two worker - { + } + else if(C >= 6)//one main two worker + { encoding_return = dlsch_encoding_2threads(eNB, a, @@ -650,9 +652,9 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, te_wakeup_stats1, i_stats, 2); - } - else if(C >= 4 && get_nprocs()>=4 && codingw)//one main one worker - { + } + else if(C >= 4)//one main one worker + { encoding_return = dlsch_encoding_2threads(eNB, a, @@ -668,9 +670,23 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, te_wakeup_stats1, i_stats, 1); + } + else + { + encoding_return = + dlsch_encoding(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + i_stats); + } } - else - { + else + { encoding_return = dlsch_encoding(eNB, a, @@ -681,7 +697,7 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, rm_stats, te_stats, i_stats); - } + } return encoding_return; } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 6f1913ff916842402619bb8d22c9995cc5ebf609..bfdcdc1e94694f0f549e3ed885db322baef8bd2f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -165,10 +165,19 @@ int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, uint32_t tti_offset; uint8_t re; uint8_t *x0p; + uint8_t first_re,last_re; + + last_re=12; + first_re=0; + if (skip_half==1) + last_re=6; + else if (skip_half==2) + first_re=6; + re=first_re; if (skip_dc == 0) { - for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; - re<12; + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; + re<last_re; re++,x0p+=2,tti_offset++) { qpsk_table_offset_re=x0p[0]; @@ -199,8 +208,16 @@ int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; } } - *re_allocated = *re_allocated + 12; - *jj=*jj + 24; + if(skip_half!=0) + { + *re_allocated = *re_allocated + 6; + *jj=*jj + 12; + } + else + { + *re_allocated = *re_allocated + 12; + *jj=*jj + 24; + } return(0); } @@ -238,12 +255,20 @@ int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, uint32_t tti_offset; uint8_t re; uint8_t *x0p; + uint8_t first_re,last_re; + last_re=12; + first_re=0; + if (skip_half==1) + last_re=6; + else if (skip_half==2) + first_re=6; + re=first_re+P1_SHIFT[0]; if (skip_dc == 0) { // printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); - for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; - re<12; + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; + re<last_re; x0p+=2) { qpsk_table_offset_re=x0p[0]; @@ -260,8 +285,8 @@ int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, re<6; x0p+=2) { - qpsk_table_offset_re+=x0p[0]; - qpsk_table_offset_im+=x0p[1]; + qpsk_table_offset_re=x0p[0]; + qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; @@ -272,16 +297,24 @@ int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, re<12; x0p+=2) { - qpsk_table_offset_re+=x0p[0]; - qpsk_table_offset_im+=x0p[1]; + qpsk_table_offset_re=x0p[0]; + qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } - *re_allocated = *re_allocated + 10; - *jj=*jj + 20; + if(skip_half!=0) + { + *re_allocated = *re_allocated + 5; + *jj=*jj + 10; + } + else + { + *re_allocated = *re_allocated + 10; + *jj=*jj + 20; + } return(0); } @@ -317,10 +350,19 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, uint32_t tti_offset; uint8_t re; uint8_t *x0p; + uint8_t first_re,last_re; + + last_re=12; + first_re=0; + if (skip_half==1) + last_re=6; + else if (skip_half==2) + first_re=6; + re=first_re; if (skip_dc == 0) { - for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; - re<12; + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; + re<last_re; re++,x0p+=4,tti_offset++) { qam16_table_offset_re=TWO[x0p[0]]; @@ -357,8 +399,16 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; } } - *re_allocated = *re_allocated + 12; - *jj=*jj + 48; + if(skip_half!=0) + { + *re_allocated = *re_allocated + 6; + *jj=*jj + 24; + } + else + { + *re_allocated = *re_allocated + 12; + *jj=*jj + 48; + } return(0); } @@ -396,12 +446,21 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, uint32_t tti_offset; uint8_t re; uint8_t *x0p; + uint8_t first_re,last_re; + + last_re=12; + first_re=0; + if (skip_half==1) + last_re=6; + else if (skip_half==2) + first_re=6; + re=first_re+P1_SHIFT[0]; if (skip_dc == 0) { // LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); - for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; - re<12; + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; + re<last_re; x0p+=4) { qam16_table_offset_re=TWO[x0p[0]]; @@ -444,8 +503,16 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, re+=P1_SHIFT[re+1]; } } - *re_allocated = *re_allocated + 10; - *jj=*jj + 40; + if(skip_half!=0) + { + *re_allocated = *re_allocated + 5; + *jj=*jj + 20; + } + else + { + *re_allocated = *re_allocated + 10; + *jj=*jj + 40; + } return(0); } @@ -482,10 +549,16 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, uint32_t tti_offset; uint8_t re; uint8_t *x0p; + uint8_t first_re; + + first_re=0; + if (skip_half==2) + first_re=6; + re=first_re; if (skip_dc == 0) { - x0p=&x0[*jj],tti_offset=symbol_offset+re_offset; + x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; /* for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; re<12; @@ -521,36 +594,38 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, ((int16_t *)&txdataF[0][tti_offset])[10]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[11]=qam_table_s0[qam64_table_offset_im]; - qam64_table_offset_re=(x0p[36]<<2)|(x0p[38]<<1)|x0p[40]; - qam64_table_offset_im=(x0p[37]<<2)|(x0p[39]<<1)|x0p[41]; - ((int16_t *)&txdataF[0][tti_offset])[12]=qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[0][tti_offset])[13]=qam_table_s0[qam64_table_offset_im]; - - qam64_table_offset_re=(x0p[42]<<2)|(x0p[44]<<1)|x0p[46]; - qam64_table_offset_im=(x0p[43]<<2)|(x0p[45]<<1)|x0p[47]; - ((int16_t *)&txdataF[0][tti_offset])[14]=qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[0][tti_offset])[15]=qam_table_s0[qam64_table_offset_im]; - - qam64_table_offset_re=(x0p[48]<<2)|(x0p[50]<<1)|x0p[52]; - qam64_table_offset_im=(x0p[49]<<2)|(x0p[51]<<1)|x0p[53]; - ((int16_t *)&txdataF[0][tti_offset])[16]=qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[0][tti_offset])[17]=qam_table_s0[qam64_table_offset_im]; - - qam64_table_offset_re=(x0p[54]<<2)|(x0p[56]<<1)|x0p[58]; - qam64_table_offset_im=(x0p[55]<<2)|(x0p[57]<<1)|x0p[59]; - ((int16_t *)&txdataF[0][tti_offset])[18]=qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[0][tti_offset])[19]=qam_table_s0[qam64_table_offset_im]; - - qam64_table_offset_re=(x0p[60]<<2)|(x0p[62]<<1)|x0p[64]; - qam64_table_offset_im=(x0p[61]<<2)|(x0p[63]<<1)|x0p[65]; - ((int16_t *)&txdataF[0][tti_offset])[20]=qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[0][tti_offset])[21]=qam_table_s0[qam64_table_offset_im]; - - qam64_table_offset_re=(x0p[66]<<2)|(x0p[68]<<1)|x0p[70]; - qam64_table_offset_im=(x0p[67]<<2)|(x0p[69]<<1)|x0p[71]; - ((int16_t *)&txdataF[0][tti_offset])[22]=qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[0][tti_offset])[23]=qam_table_s0[qam64_table_offset_im]; - + if(skip_half==0) + { + qam64_table_offset_re=(x0p[36]<<2)|(x0p[38]<<1)|x0p[40]; + qam64_table_offset_im=(x0p[37]<<2)|(x0p[39]<<1)|x0p[41]; + ((int16_t *)&txdataF[0][tti_offset])[12]=qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[13]=qam_table_s0[qam64_table_offset_im]; + + qam64_table_offset_re=(x0p[42]<<2)|(x0p[44]<<1)|x0p[46]; + qam64_table_offset_im=(x0p[43]<<2)|(x0p[45]<<1)|x0p[47]; + ((int16_t *)&txdataF[0][tti_offset])[14]=qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[15]=qam_table_s0[qam64_table_offset_im]; + + qam64_table_offset_re=(x0p[48]<<2)|(x0p[50]<<1)|x0p[52]; + qam64_table_offset_im=(x0p[49]<<2)|(x0p[51]<<1)|x0p[53]; + ((int16_t *)&txdataF[0][tti_offset])[16]=qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[17]=qam_table_s0[qam64_table_offset_im]; + + qam64_table_offset_re=(x0p[54]<<2)|(x0p[56]<<1)|x0p[58]; + qam64_table_offset_im=(x0p[55]<<2)|(x0p[57]<<1)|x0p[59]; + ((int16_t *)&txdataF[0][tti_offset])[18]=qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[19]=qam_table_s0[qam64_table_offset_im]; + + qam64_table_offset_re=(x0p[60]<<2)|(x0p[62]<<1)|x0p[64]; + qam64_table_offset_im=(x0p[61]<<2)|(x0p[63]<<1)|x0p[65]; + ((int16_t *)&txdataF[0][tti_offset])[20]=qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[21]=qam_table_s0[qam64_table_offset_im]; + + qam64_table_offset_re=(x0p[66]<<2)|(x0p[68]<<1)|x0p[70]; + qam64_table_offset_im=(x0p[67]<<2)|(x0p[69]<<1)|x0p[71]; + ((int16_t *)&txdataF[0][tti_offset])[22]=qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[0][tti_offset])[23]=qam_table_s0[qam64_table_offset_im]; + } // } } @@ -584,8 +659,16 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, } } - *re_allocated = *re_allocated + 12; - *jj=*jj + 72; + if(skip_half!=0) + { + *re_allocated = *re_allocated + 6; + *jj=*jj + 36; + } + else + { + *re_allocated = *re_allocated + 12; + *jj=*jj + 72; + } return(0); } @@ -623,12 +706,21 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, uint32_t tti_offset; uint8_t re; uint8_t *x0p; + uint8_t first_re,last_re; + + last_re=12; + first_re=0; + if (skip_half==1) + last_re=6; + else if (skip_half==2) + first_re=6; + re=first_re+P1_SHIFT[0]; if (skip_dc == 0) { // LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); - for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; - re<12; + for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; + re<last_re; x0p+=6) { qam64_table_offset_re=FOUR[x0p[0]]; @@ -677,8 +769,16 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, re+=P1_SHIFT[re+1]; } } - *re_allocated = *re_allocated + 10; - *jj=*jj + 60; + if(skip_half!=0) + { + *re_allocated = *re_allocated + 5; + *jj=*jj + 30; + } + else + { + *re_allocated = *re_allocated + 10; + *jj=*jj + 60; + } return(0); } @@ -2423,7 +2523,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, * with above code that needs to be analyzed and fixed. In the * meantime, let's use the generic function. */ - allocate_REs = allocate_REs_in_RB; + //allocate_REs = allocate_REs_in_RB; break; } @@ -2432,7 +2532,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, * previous version. Some more work/validation is needed before * we switch to the new version. */ - allocate_REs = allocate_REs_in_RB; + //if (frame_parms->N_RB_DL==25) + //allocate_REs = allocate_REs_in_RB; switch (mod_order1) { case 2: @@ -2486,8 +2587,6 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, skip_half = check_skiphalf(rb,subframe_offset,frame_parms,l,nsymb); skip_dc = check_skip_dc(rb,frame_parms); - - if (dlsch0) { if (dlsch0_harq->Nlayers>1) { LOG_E(PHY,"Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 9f4ab3a580ad3542812d0fd989decaea6f89c4d2..77f060a4336d1bb654d3555ba8478b8737316895 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -33,10 +33,10 @@ #include "PHY/defs_eNB.h" #include "PHY/TOOLS/alaw_lut.h" -#include "time_utils.h" //#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include <intertask_interface.h> #include "common/utils/LOG/vcd_signal_dumper.h" //#define DEBUG_DL_MOBIPASS //#define DEBUG_UL_MOBIPASS diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c index 1d12c79621ea403c93c1eaa6389da0fa5065aa8c..a4821a420ff27f87731c6b737d515598e5758343 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c @@ -27,6 +27,7 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par uint32_t period; uint8_t i; + uint8_t j; // LOG_D(PHY,"is_pmch_subframe: frame %d, subframe %d, num_MBSFN_config %d\n", // frame,subframe,frame_parms->num_MBSFN_config); @@ -34,8 +35,8 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par for (i=0; i<frame_parms->num_MBSFN_config; i++) { // we have at least one MBSFN configuration period = 1<<frame_parms->MBSFN_config[i].radioframeAllocationPeriod; - if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) { - if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) { + if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) { + if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) { if (frame_parms->frame_type == FDD) { switch (subframe) { @@ -108,9 +109,96 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par break; } } + } + + } else { // handle 4 frames case + + for(j=0;j<4;j++) { + if ((frame % period) == (frame_parms->MBSFN_config[i].radioframeAllocationOffset + j)) { + if (frame_parms->frame_type == FDD) { + switch (subframe) { + case 1: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x800000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x800000>>(j*6)); + return(1); + } + + break; + + case 2: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x400000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x400000>>(j*6)); + return(1); + } + + break; + + case 3: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x200000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x200000>>(j*6)); + return(1); + } + + break; + + case 6: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x100000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x100000>>(j*6)); + return(1); + } + + break; + + case 7: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x80000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x80000>>(j*6)); + return(1); + } + + break; - } else { // handle 4 frames case + case 8: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x40000>>(j*6))) > 0) { + //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x40000>>(j*6)); + return(1); + } + break; + } + } else { + switch (subframe) { + case 3: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF3) > 0) + return(1); + + break; + + case 4: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF4) > 0) + return(1); + + break; + + case 7: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF7) > 0) + return(1); + + break; + + case 8: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF8) > 0) + return(1); + + break; + + case 9: + if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF9) > 0) + return(1); + + break; + } + } + } } } } diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index db6f04f788e6f8583da135661f24ac78d13cb463..ec0b7db4ad7d003398dfddd842f935f6639b0743 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -153,25 +153,24 @@ void rx_prach0(PHY_VARS_eNB *eNB, subframe = eNB->proc.subframe_prach_br; prachF = eNB->prach_vars_br.prachF; rxsigF = eNB->prach_vars_br.rxsigF[ce_level]; -LOG_DEBUG_BEGIN(PRACH) - if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n", - br_flag,ce_level,ru->proc.frame_prach,subframe, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level], - prach_ConfigIndex,rootSequenceIndex, - eNB->prach_vars_br.repetition_number[ce_level], - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level]); -LOG_DEBUG_END - } - else + if (LOG_DEBUGFLAG(PRACH)){ + if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n", + br_flag,ce_level,ru->proc.frame_prach,subframe, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level], + prach_ConfigIndex,rootSequenceIndex, + eNB->prach_vars_br.repetition_number[ce_level], + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level]); + } + } else #endif { prach_ifftp = eNB->prach_vars.prach_ifft[0]; subframe = eNB->proc.subframe_prach; prachF = eNB->prach_vars.prachF; rxsigF = eNB->prach_vars.rxsigF[0]; -LOG_DEBUG_BEGIN(PRACH) - if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(PRACH)){ + if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex); + } } } else { @@ -179,20 +178,19 @@ LOG_DEBUG_END if (br_flag == 1) { subframe = ru->proc.subframe_prach_br; rxsigF = ru->prach_rxsigF_br[ce_level]; -LOG_DEBUG_BEGIN(PRACH) - if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", - br_flag,ce_level,ru->proc.frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex); -LOG_DEBUG_END - } - else + if (LOG_DEBUGFLAG(PRACH)){ + if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", + br_flag,ce_level,ru->proc.frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex); + } + } else #endif { subframe = ru->proc.subframe_prach; rxsigF = ru->prach_rxsigF; -LOG_DEBUG_BEGIN(PRACH) - if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", - subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(PRACH)){ + if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", + subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex); + } } } @@ -204,27 +202,25 @@ LOG_DEBUG_END // DJP - indexing below in subframe zero takes us off the beginning of the array??? prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset]; -LOG_M_BEGIN(PRACH) - int32_t en0=signal_energy((int32_t*)prach[aa],fp->samples_per_tti); - int8_t dbEn0 = dB_fixed(en0); - int8_t rach_dBm = dbEn0 - ru->rx_total_gain_dB; - char buffer[80]; - if (dbEn0>32 && prach[0]!= NULL) - { - static int counter=0; - sprintf(buffer, "%s%d", "/tmp/prach_rx",counter); - LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,13); - } - if (dB_fixed(en0)>32) - { - sprintf(buffer, "rach_dBm:%d",rach_dBm); - if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1); - LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n", - ru->idx,br_flag,ce_level,ru->proc.frame_prach,subframe,fp->samples_per_tti, - prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa], - (subframe*fp->samples_per_tti)-ru->N_TA_offset); + if (LOG_DUMPFLAG(PRACH)){ + int32_t en0=signal_energy((int32_t*)prach[aa],fp->samples_per_tti); + int8_t dbEn0 = dB_fixed(en0); + int8_t rach_dBm = dbEn0 - ru->rx_total_gain_dB; + char buffer[80]; + if (dbEn0>32 && prach[0]!= NULL) { + static int counter=0; + sprintf(buffer, "%s%d", "/tmp/prach_rx",counter); + LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,13); + } + if (dB_fixed(en0)>32) { + sprintf(buffer, "rach_dBm:%d",rach_dBm); + if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1); + LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n", + ru->idx,br_flag,ce_level,ru->proc.frame_prach,subframe,fp->samples_per_tti, + prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa], + (subframe*fp->samples_per_tti)-ru->N_TA_offset); } -LOG_M_END + } } } @@ -306,9 +302,9 @@ LOG_M_END if (((eNB!=NULL) && (ru->function != NGFI_RAU_IF4p5))|| ((eNB==NULL) && (ru->function == NGFI_RRU_IF4p5))) { // compute the DFTs of the PRACH temporal resources // Do forward transform -LOG_DEBUG_BEGIN(PRACH) - LOG_D(PHY,"rx_prach: Doing FFT for N_RB_UL %d nb_rx:%d Ncp:%d\n",fp->N_RB_UL, nb_rx, Ncp); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(PRACH)) { + LOG_D(PHY,"rx_prach: Doing FFT for N_RB_UL %d nb_rx:%d Ncp:%d\n",fp->N_RB_UL, nb_rx, Ncp); + } for (aa=0; aa<nb_rx; aa++) { AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa); prach2 = prach[aa] + (Ncp<<1); @@ -439,10 +435,10 @@ LOG_DEBUG_END return; } else if (eNB!=NULL) { -LOG_DEBUG_BEGIN(PRACH) - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,eNB->proc.frame_rx,eNB->proc.subframe_rx,en); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(PRACH)) { + int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); + if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,eNB->proc.frame_rx,eNB->proc.subframe_rx,en); + } } // in case of RAU and prach received rx_thread wakes up prach @@ -477,10 +473,10 @@ LOG_DEBUG_END *max_preamble_energy=0; for (preamble_index=0 ; preamble_index<64 ; preamble_index++) { -LOG_DEBUG_BEGIN(PRACH) - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",ru->proc.frame_prach,subframe,preamble_index,br_flag); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(PRACH)){ + int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); + if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",ru->proc.frame_prach,subframe,preamble_index,br_flag); + } if (restricted_set == 0) { // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); @@ -563,11 +559,11 @@ LOG_DEBUG_END } // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex -LOG_DEBUG_BEGIN(PRACH) - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n", - ru->proc.frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(PRACH)) { + int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); + if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n", + ru->proc.frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en); + } log2_ifft_size = 10; fft_size = 6144; @@ -589,13 +585,13 @@ LOG_DEBUG_END } memset(prachF, 0, sizeof(int16_t)*2*1024 ); -LOG_M_BEGIN(PRACH) - if (prach[0]!= NULL) LOG_M("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1); - LOG_M("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1); - LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],24576,1,1); - LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); -LOG_M_END - + if (LOG_DUMPFLAG(PRACH)) { + if (prach[0]!= NULL) LOG_M("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1); + LOG_M("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1); + LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],24576,1,1); + LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); + } + for (aa=0;aa<nb_rx; aa++) { // Do componentwise product with Xu* on each antenna @@ -623,10 +619,10 @@ LOG_M_END prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[(i<<1)] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10; } -LOG_M_BEGIN(PRACH) - if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); - if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1); -LOG_M_END + if (LOG_DUMPFLAG(PRACH)) { + if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); + if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1); + } }// antennas_rx } // new dft @@ -637,10 +633,10 @@ LOG_M_END eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) #endif { -LOG_DEBUG_BEGIN(PRACH) + if (LOG_DEBUGFLAG(PRACH)){ int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",ru->proc.frame_prach,subframe,br_flag,en); -LOG_DEBUG_END + } preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC)); @@ -652,44 +648,48 @@ LOG_DEBUG_END *max_preamble_energy = levdB; *max_preamble_delay = ((i*fft_size)>>log2_ifft_size)*update_TA/update_TA2; *max_preamble = preamble_index; -LOG_DEBUG_BEGIN(PRACH) - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if ((en>60) && (br_flag==1)) LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",ru->proc.frame_prach,subframe,*max_preamble_energy,*max_preamble_delay,*max_preamble,br_flag,ce_level,levdB,lev); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(PRACH)){ + int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); + if ((en>60) && (br_flag==1)) + LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n", + ru->proc.frame_prach,subframe, + *max_preamble_energy,*max_preamble_delay, + *max_preamble,br_flag,ce_level,levdB,lev); + } } } } }// preamble_index -LOG_M_BEGIN(PRACH) - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if (en>60) { - k = (12*n_ra_prb) - 6*fp->N_RB_UL; - - if (k<0) k+=fp->ofdm_symbol_size; - - k*=12; - k+=13; - k*=2; - - if (br_flag == 0) { - LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1); - LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); - LOG_M("Xu.m","xu",Xu,N_ZC,1,1); - LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); - } - else { - LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb); - LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1); - LOG_M("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1); - LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1); - LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1); - exit(-1); - } + if (LOG_DUMPFLAG(PRACH)) { + int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); + if (en>60) { + k = (12*n_ra_prb) - 6*fp->N_RB_UL; + + if (k<0) k+=fp->ofdm_symbol_size; + + k*=12; + k+=13; + k*=2; + + if (br_flag == 0) { + LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1); + LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); + LOG_M("Xu.m","xu",Xu,N_ZC,1,1); + LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); + } + else { + LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb); + LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1); + LOG_M("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1); + LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1); + LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1); + exit(-1); + } - } -LOG_M_END + } + } /* LOG_DUMPFLAG(PRACH) */ if (eNB) stop_meas(&eNB->rx_prach); } diff --git a/openair1/PHY/LTE_TRANSPORT/sss.h b/openair1/PHY/LTE_TRANSPORT/sss.h deleted file mode 100644 index 6d42acaefc1e45450300e0af347f77dba52c01f5..0000000000000000000000000000000000000000 --- a/openair1/PHY/LTE_TRANSPORT/sss.h +++ /dev/null @@ -1,25 +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 - */ - -int16_t d0_sss[504*62] = {1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1}; - -int16_t d5_sss[504*62] = {1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,1,1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,-1,1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,-1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,1,-1,-1,1,1,1,1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,-1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,1,1,-1,-1,-1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,1,1,1,1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,1,1,1,-1,-1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,-1,1,1,-1,1,-1,1,1,1,1,1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,1,-1,1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,1,-1,1,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,-1,-1,1,1,1,1,-1,1,-1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,-1,-1,-1,-1,1,1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,-1,1,1,1,-1,1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,1,1,1,1,-1,1,1,1,1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,1,-1,1,-1,1,-1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,-1}; - diff --git a/openair1/PHY/LTE_TRANSPORT/sss_gen.c b/openair1/PHY/LTE_TRANSPORT/sss_gen.c new file mode 100644 index 0000000000000000000000000000000000000000..b0b71d4f6b6a08e651051a0ee7139e415487e203 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/sss_gen.c @@ -0,0 +1,68 @@ +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <malloc.h> +#include <stdlib.h> +#include <math.h> + +int16_t *d0_sss; +int16_t *d5_sss; + +#define MyAssert(x) { if(!(x)) { printf("Error in table intialization: %s:%d\n",__FILE__,__LINE__); exit(1);}} +#define gen(table, formula) { \ + int x[31]= {0}; \ + x[4]=1; \ + for(int i=0; i<26; i++) \ + x[i+5]=formula; \ + for (int i=0; i<31; i++) \ + table[i]=1-2*x[i]; \ + } + +#define mod31(a) (a)%31 +#define mod2(a) (a)%2 +#define mod8(a) (a)%8 +void init_sss(void) { + MyAssert(0==posix_memalign((void **)&d0_sss, 16,504*31*2*sizeof(*d0_sss))); + MyAssert(0==posix_memalign((void **)&d5_sss, 16,504*31*2*sizeof(*d5_sss))); + int s[31]; + gen(s, mod2(x[i+2]+x[i])); + int z[31]; + gen(z, mod2(x[i+4]+x[i+2]+x[i+1]+x[i])); + int c[31]; + gen(c, mod2(x[i+3]+x[i])); + + for (int Nid2=0; Nid2<3; Nid2++) { + for (int Nid1=0; Nid1<168; Nid1++) { + int qprime = Nid1/30; + int q = (Nid1+(qprime*(qprime+1))/2)/30; + int mprime = Nid1 + q*(q+1)/2; + int m0 = mprime%31; + int m1 = (m0+mprime/31+1)%31; + int rowIndex=(Nid2+3*Nid1)*31*2; + + for (int i=0; i<31; i++) { + d0_sss[rowIndex+i*2]= s[mod31(i+m0)] * c[mod31(i+Nid2)]; + d5_sss[rowIndex+i*2]= s[mod31(i+m1)] * c[mod31(i+Nid2)]; + d0_sss[rowIndex+i*2+1]= s[mod31(i+m1)] * c[mod31(i+Nid2+3)] * z[mod31(i+mod8(m0))]; + d5_sss[rowIndex+i*2+1]= s[mod31(i+m0)] * c[mod31(i+Nid2+3)] * z[mod31(i+mod8(m1))]; + } + } + } +} + +#ifdef SSS_TABLES_TEST +void main () { + printf("int16_t d0_sss[504*62] = {"); + + for (int i=0; i<504*62; i++) + printf("%d,\n",d0_sss[i]); + + printf("};\n\n"); + printf("int16_t d5_sss[504*62] = {"); + + for (int i=0; i<504*62; i++) + printf("%d,\n",d5_sss[i]); + + printf("};\n\n"); +} +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/sss_gen.m b/openair1/PHY/LTE_TRANSPORT/sss_gen.m deleted file mode 100644 index 65e5a5a0a104fc8a5513727fe8e1af571b7fdc16..0000000000000000000000000000000000000000 --- a/openair1/PHY/LTE_TRANSPORT/sss_gen.m +++ /dev/null @@ -1,53 +0,0 @@ -% generate s -x = zeros(1,30); -x(1:5) = [0 0 0 0 1]; -for i=1:26 - x(i+5) = rem(x(i+2) + x(i),2); -end -s = 1 - 2*x; - -% generate z -x = zeros(1,30); -x(1:5) = [0 0 0 0 1]; -for i=1:26 - x(i+5) = rem(x(i+4)+ x(i+2) + x(i+1) + x(i),2); -end -z = 1 - 2*x; -% generate c -x = zeros(1,30); -x(1:5) = [0 0 0 0 1]; -for i=1:26 - x(i+5) = rem(x(i+3) + x(i),2); -end -c = 1 - 2*x; -d0 = zeros(504,62); -d5 = zeros(504,62); -for Nid2=0:2, - c0 = [c((1+Nid2) : end) c(1:Nid2)]; - c1 = [c((4+Nid2) : end) c(1:(3+Nid2))]; - for Nid1=0:167, - qprime = floor(Nid1/30); - q = floor((Nid1+qprime*(qprime+1)/2)/30); - mprime = Nid1 + q*(q+1)/2; - m0 = rem(mprime,31); - m1 = rem(m0+floor(mprime/31)+1,31); - sm0 = [s((1+m0) : end) s(1:m0)]; - sm1 = [s((1+m1) : end) s(1:m1)]; - m0mod8 = rem(m0,8); - m1mod8 = rem(m1,8); - zm0 = [z((1+m0mod8) : end) z(1:m0mod8)]; - zm1 = [z((1+m1mod8) : end) z(1:m1mod8)]; - d0(1+Nid2+(3*Nid1),1:2:62) = sm0.*c0; - d5(1+Nid2+(3*Nid1),1:2:62) = sm1.*c0; - d0(1+Nid2+(3*Nid1),2:2:62) = sm1.*c1.*zm0; - d5(1+Nid2+(3*Nid1),2:2:62) = sm0.*c1.*zm1; - end -end -fd = fopen("sss.h","w"); -fprintf(fd,"s16 d0_sss[504*62] = {"); -fprintf(fd,"%d,",d0); -fprintf(fd,"};\n\n"); -fprintf(fd,"s16 d5_sss[504*62] = {"); -fprintf(fd,"%d,",d5); -fprintf(fd,"};\n\n"); -fclose(fd); \ No newline at end of file diff --git a/openair1/PHY/LTE_TRANSPORT/transport_extern.h b/openair1/PHY/LTE_TRANSPORT/transport_extern.h index 6a9fa49405a9bb3d8d3161aedc4ab4b1159b44c7..357d31ca1076099d14ac7cc7795192ba63420ce8 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_extern.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_extern.h @@ -25,10 +25,10 @@ extern char lte_cqi_snr_dB[15]; extern short conjugate[8],conjugate2[8]; extern short minus_one[8]; extern short minus_one[8]; -extern short *ul_ref_sigs[30][2][33]; -extern short *ul_ref_sigs_rx[30][2][33]; -extern unsigned short dftsizes[33]; -extern unsigned short ref_primes[33]; +extern short *ul_ref_sigs[30][2][34]; +extern short *ul_ref_sigs_rx[30][2][34]; +extern unsigned short dftsizes[34]; +extern unsigned short ref_primes[34]; extern int qam64_table[8],qam16_table[4],qpsk_table[2]; @@ -44,7 +44,7 @@ extern unsigned short scfdma_amps[26]; extern char dci_format_strings[15][13]; -extern int16_t d0_sss[504*62],d5_sss[504*62]; +extern int16_t *d0_sss,*d5_sss; extern uint8_t wACK[5][4]; extern int8_t wACK_RX[5][4]; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_vars.h b/openair1/PHY/LTE_TRANSPORT/transport_vars.h index 611028e1e9805d748de9c9c4f77ba0b8856b2170..02dfbc6a5edcf17e6bf384a79f8adabf5ecdbbf9 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_vars.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_vars.h @@ -21,7 +21,6 @@ #include "dlsch_tbs.h" //#include "dlsch_tbs_full.h" -#include "sss.h" unsigned short lte_cqi_eff1024[16] = {156, //-6, .15234 240, //-4 .234 diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 851bcfff5a88582da16401f394b45c106529b45c..046e456916a104bf5afc892142a9317807ac4e80 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -45,7 +45,7 @@ #include "targets/RT/USER/rt_wrapper.h" #include "transport_proto.h" -extern int codingw; +extern WORKER_CONF_t get_thread_worker_conf(void); void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) { @@ -723,7 +723,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { int ret = 0; - /*if(codingw) + /*if(get_thread_worker_conf() == WORKER_ENABLE) { ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 619d84cee203f174a661b8a88377ff22e41d81c3..61076f2aae48fdfd6af03fafcda9d5c9b0bfdb06 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -33,7 +33,6 @@ #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" #include "transport_eNB.h" -//#define DEBUG_ULSCH #include "PHY/sse_intrin.h" #include "transport_common_proto.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" @@ -67,7 +66,7 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) - // printf("Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); + LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); if (frame_parms->Ncp == 0) { // Normal prefix z0 = z; @@ -336,6 +335,12 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) dft720((int16_t*)idft_in2,(int16_t*)idft_out2,1); break; + case 768: + dft768((int16_t*)idft_in0,(int16_t*)idft_out0,1); + dft768((int16_t*)idft_in1,(int16_t*)idft_out1,1); + dft768((int16_t*)idft_in2,(int16_t*)idft_out2,1); + break; + case 864: dft864((int16_t*)idft_in0,(int16_t*)idft_out0,1); dft864((int16_t*)idft_in1,(int16_t*)idft_out1,1); @@ -388,13 +393,13 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) { z0[i] = ((uint32_t*)idft_out0)[ip]; - /* - printf("out0 (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", - ((int16_t*)&idft_out0[ip])[0],((int16_t*)&idft_out0[ip])[1], - ((int16_t*)&idft_out0[ip+1])[0],((int16_t*)&idft_out0[ip+1])[1], - ((int16_t*)&idft_out0[ip+2])[0],((int16_t*)&idft_out0[ip+2])[1], - ((int16_t*)&idft_out0[ip+3])[0],((int16_t*)&idft_out0[ip+3])[1]); - */ + if(LOG_DEBUGFLAG(DEBUG_ULSCH)) { + LOG_I(PHY,"out0 (%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", + ((int16_t*)&idft_out0[ip])[0],((int16_t*)&idft_out0[ip])[1], + ((int16_t*)&idft_out0[ip+1])[0],((int16_t*)&idft_out0[ip+1])[1], + ((int16_t*)&idft_out0[ip+2])[0],((int16_t*)&idft_out0[ip+2])[1], + ((int16_t*)&idft_out0[ip+3])[0],((int16_t*)&idft_out0[ip+3])[1]); + } z1[i] = ((uint32_t*)idft_out0)[ip+1]; z2[i] = ((uint32_t*)idft_out0)[ip+2]; z3[i] = ((uint32_t*)idft_out0)[ip+3]; @@ -479,10 +484,7 @@ int32_t ulsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int i; - // printf("qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),llr128U-(__m128i*)ulsch_llr); - for (i=0; i<(nb_rb*3); i++) { - //printf("%d,%d,%d,%d,%d,%d,%d,%d\n",((int16_t *)rxF)[0],((int16_t *)rxF)[1],((int16_t *)rxF)[2],((int16_t *)rxF)[3],((int16_t *)rxF)[4],((int16_t *)rxF)[5],((int16_t *)rxF)[6],((int16_t *)rxF)[7]); *(*llrp128) = *rxF; rxF++; (*llrp128)++; @@ -593,7 +595,9 @@ void ulsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, ch_mag =(int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; ch_magb =(int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; #endif - // printf("symbol %d: mag %d, magb %d\n",symbol,_mm_extract_epi16(ch_mag[0],0),_mm_extract_epi16(ch_magb[0],0)); + if(LOG_DEBUGFLAG(DEBUG_ULSCH)) { + LOG_UI(PHY,"symbol %d: mag %d, magb %d\n",symbol,_mm_extract_epi16(ch_mag[0],0),_mm_extract_epi16(ch_magb[0],0)); + } for (i=0; i<(nb_rb*3); i++) { @@ -736,9 +740,9 @@ void ulsch_extract_rbs_single(int32_t **rxdataF, nb_rb1 = cmin(cmax((int)(frame_parms->N_RB_UL) - (int)(2*first_rb),(int)0),(int)(2*nb_rb)); // 2 times no. RBs before the DC nb_rb2 = 2*nb_rb - nb_rb1; // 2 times no. RBs after the DC -#ifdef DEBUG_ULSCH - printf("ulsch_extract_rbs_single: 2*nb_rb1 = %d, 2*nb_rb2 = %d\n",nb_rb1,nb_rb2); -#endif + if(LOG_DEBUGFLAG(DEBUG_ULSCH)) { + LOG_UI(PHY,"ulsch_extract_rbs_single: 2*nb_rb1 = %d, 2*nb_rb2 = %d\n",nb_rb1,nb_rb2); + } rxF_ext = &rxdataF_ext[aarx][(symbol*frame_parms->N_RB_UL*12)]; @@ -838,7 +842,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, #endif for (rb=0; rb<nb_rb; rb++) { - // printf("comp: symbol %d rb %d\n",symbol,rb); + LOG_D(PHY,"comp: symbol %d rb %d\n",symbol,rb); // just compute channel magnitude without scaling, this is done after equalization for SC-FDMA @@ -861,7 +865,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0); ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1); - // printf("comp: symbol %d rb %d => %d,%d,%d (output_shift %d)\n",symbol,rb,*((int16_t*)&ul_ch_mag128[0]),*((int16_t*)&ul_ch_mag128[1]),*((int16_t*)&ul_ch_mag128[2]),output_shift); + LOG_D(PHY,"comp: symbol %d rb %d => %d,%d,%d (output_shift %d)\n",symbol,rb,*((int16_t*)&ul_ch_mag128[0]),*((int16_t*)&ul_ch_mag128[1]),*((int16_t*)&ul_ch_mag128[2]),output_shift); #elif defined(__arm__) @@ -1125,10 +1129,9 @@ void rx_ulsch(PHY_VARS_eNB *eNB, harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); Qm = ulsch[UE_id]->harq_processes[harq_pid]->Qm; -#ifdef DEBUG_ULSCH - printf("rx_ulsch: harq_pid %d, nb_rb %d first_rb %d\n",harq_pid,ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,ulsch[UE_id]->harq_processes[harq_pid]->first_rb); - -#endif //DEBUG_ULSCH + if(LOG_DEBUGFLAG(DEBUG_ULSCH)) { + LOG_I(PHY,"rx_ulsch: harq_pid %d, nb_rb %d first_rb %d\n",harq_pid,ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,ulsch[UE_id]->harq_processes[harq_pid]->first_rb); + } if (ulsch[UE_id]->harq_processes[harq_pid]->nb_rb == 0) { LOG_E(PHY,"PUSCH (%d/%x) nb_rb=0!\n", harq_pid,ulsch[UE_id]->rnti); @@ -1137,13 +1140,13 @@ void rx_ulsch(PHY_VARS_eNB *eNB, for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active); l++) { -#ifdef DEBUG_ULSCH - printf("rx_ulsch : symbol %d (first_rb %d,nb_rb %d), rxdataF %p, rxdataF_ext %p\n",l, + if(LOG_DEBUGFLAG(DEBUG_ULSCH)) { + LOG_I(PHY,"rx_ulsch : symbol %d (first_rb %d,nb_rb %d), rxdataF %p, rxdataF_ext %p\n",l, ulsch[UE_id]->harq_processes[harq_pid]->first_rb, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, common_vars->rxdataF, pusch_vars->rxdataF_ext); -#endif //DEBUG_ULSCH + } ulsch_extract_rbs_single(common_vars->rxdataF, pusch_vars->rxdataF_ext, @@ -1179,21 +1182,16 @@ void rx_ulsch(PHY_VARS_eNB *eNB, pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[i], ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)/correction_factor; - /* printf("%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_times10(pusch_vars->ulsch_power[i])); - */ + LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_times10(pusch_vars->ulsch_power[i])); + } - - //LOG_M("rxdataF_ext.m","rxF_ext",pusch_vars->rxdataF_ext[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1); - //LOG_M("ulsch_chest.m","drs_est",pusch_vars->drs_ch_estimates[eNB_id][0],300*(frame_parms->symbols_per_tti-ulsch[UE_id]->srs_active),1,1); - - ulsch_channel_level(pusch_vars->drs_ch_estimates, frame_parms, avgU, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb); - // printf("[ULSCH] avg[0] %d\n",avgU[0]); + LOG_D(PHY,"[ULSCH] avg[0] %d\n",avgU[0]); avgs = 0; @@ -1205,9 +1203,9 @@ void rx_ulsch(PHY_VARS_eNB *eNB, log2_maxh = (log2_approx(avgs)/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+4; -#ifdef DEBUG_ULSCH - printf("[ULSCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgU[0],avgs); -#endif + + LOG_D(PHY,"[ULSCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgU[0],avgs); + for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active); l++) { @@ -1229,9 +1227,6 @@ void rx_ulsch(PHY_VARS_eNB *eNB, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, log2_maxh); // log2_maxh+I0_shift - - - if (frame_parms->nb_antennas_rx > 1) ulsch_detection_mrc(frame_parms, pusch_vars->rxdataF_comp, @@ -1240,9 +1235,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, l, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb); - - - // if ((eNB->measurements.n0_power_dB[0]+3)<pusch_vars->ulsch_power[0]) { + // if ((eNB->measurements.n0_power_dB[0]+3)<pusch_vars->ulsch_power[0]) if (23<pusch_vars->ulsch_power[0]) { freq_equalization(frame_parms, pusch_vars->rxdataF_comp, @@ -1254,22 +1247,9 @@ void rx_ulsch(PHY_VARS_eNB *eNB, } } - - - - - //#ifdef DEBUG_ULSCH - // Inverse-Transform equalized outputs - // printf("Doing IDFTs\n"); lte_idft(frame_parms, (uint32_t*)pusch_vars->rxdataF_comp[0], ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12); - // printf("Done\n"); - //#endif //DEBUG_ULSCH - - - - llrp = (int16_t*)&pusch_vars->llr[0]; @@ -1316,9 +1296,8 @@ void rx_ulsch(PHY_VARS_eNB *eNB, break; default: -#ifdef DEBUG_ULSCH - printf("ulsch_demodulation.c (rx_ulsch): Unknown Qm!!!!\n"); -#endif //DEBUG_ULSCH + LOG_E(PHY,"ulsch_demodulation.c (rx_ulsch): Unknown Qm!!!!\n"); + break; } } @@ -1329,7 +1308,7 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint8_t UE_index) { - printf("[PHY] EMUL eNB %d rx_ulsch_emul : subframe %d, UE_index %d\n",eNB->Mod_id,proc->subframe_rx,UE_index); + LOG_I(PHY,"[PHY] EMUL eNB %d rx_ulsch_emul : subframe %d, UE_index %d\n",eNB->Mod_id,proc->subframe_rx,UE_index); eNB->pusch_vars[UE_index]->ulsch_power[0] = 31622; //=45dB; eNB->pusch_vars[UE_index]->ulsch_power[1] = 31622; //=45dB; @@ -1344,7 +1323,7 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe); - printf("Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", + LOG_UI(PHY,"Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", subframe,harq_pid,round,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm, eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index b9fbcad9c9349cbec14cd23f4c75e4ddbab6b6e4..e0ea796a826fb6b05357f5624942a954706cb389 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -179,29 +179,29 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_ uint32_t rballoc=0; uint8_t mcs=0; + uint8_t Ngap=0; switch (N_RB_DL) { case 6: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); - + mcs = ((DCI1C_1_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_1_5MHz_t *)dci_pdu)->rballoc, 6); break; case 25: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); - + mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc, 25); break; case 50: - mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6); - + mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc, 50); + Ngap = ((DCI1C_10MHz_t *)dci_pdu)->Ngap; break; case 100: - mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6); + mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc, 100); + Ngap = ((DCI1C_20MHz_t *)dci_pdu)->Ngap; break; default: @@ -211,6 +211,7 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_ pdci_info_extarcted->mcs1 = mcs; pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->Ngap = Ngap; } void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 50b09102d88857b2b1a2cabf439e2e81a28f2d70..e8f20c85de6a682ce3cf947ee23aa4447c0eb776 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -782,7 +782,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #if DISABLE_LOG_X printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif // MRC diff --git a/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c index 96ff82ba162d2cd6278c54a77a4129a65f7c186a..1c49cde394623bb7e26438e7ffdc7dba5ffc01ba 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/drs_modulation.c @@ -83,7 +83,7 @@ int generate_drs_pusch(PHY_VARS_UE *ue, // cyclic_shift1 = 0; Msc_RS = 12*nb_rb; - Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints); + Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 34, sizeof(uint16_t), compareints); if (Msc_idx_ptr) Msc_RS_idx = Msc_idx_ptr - dftsizes; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c index 8bb2299b7cc82569b5af4e2d429356316c1a527b..e6960273c7300a707c44437f14bf4b146c2725fd 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c @@ -181,7 +181,7 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms, return(-1); } - Msc_idx_ptr = (uint16_t*) bsearch((uint16_t*) &Msc_RS, (uint16_t*) dftsizes, 33, sizeof(uint16_t), compareints); + Msc_idx_ptr = (uint16_t*) bsearch((uint16_t*) &Msc_RS, (uint16_t*) dftsizes, 34, sizeof(uint16_t), compareints); if (Msc_idx_ptr) Msc_RS_idx = Msc_idx_ptr - dftsizes; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c index 1281f815f854043279c767ac41bdadab620cb3f3..a9878b4eae49019a7a4d17063d60561f4bc16a3f 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c @@ -287,6 +287,12 @@ void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb) dft720((int16_t*)dft_in2,(int16_t*)dft_out2,1); break; + case 768: + dft768((int16_t*)dft_in0,(int16_t*)dft_out0,1); + dft768((int16_t*)dft_in1,(int16_t*)dft_out1,1); + dft768((int16_t*)dft_in2,(int16_t*)dft_out2,1); + break; + case 864: dft864((int16_t*)dft_in0,(int16_t*)dft_out0,1); dft864((int16_t*)dft_in1,(int16_t*)dft_out1,1); diff --git a/openair1/PHY/MODULATION/gen_75KHz.cpp b/openair1/PHY/MODULATION/gen_75KHz.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6efa3ddf2f5b713caf362f11fa9ed31ab2bb6a2c --- /dev/null +++ b/openair1/PHY/MODULATION/gen_75KHz.cpp @@ -0,0 +1,84 @@ +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <malloc.h> +#include <assert.h> +#include <complex> +#include <cmath> +#include <map> +#include <PHY/MODULATION/modulation_extern.h> +using namespace std; +extern "C" { + void gen_sig(int RB, int len, double ratio, int16_t *table_n, int16_t *table_e ) { + double samplerate = 30.72e6*ratio; + double ofdm_size = 2048*ratio; + double PI = std::acos(-1); + std::complex<int> tt; + complex<double> t[len]; + int index=0; + double cp0 = 160*ratio; + double cp = 144*ratio; + + for (int i=-cp0; i<ofdm_size; i++) + t[index++] = polar( 32767.0, -2*PI*i*7.5e3/samplerate); + + for(int x=0 ; x <6 ; x++) + for (int i=-cp; i<ofdm_size; i++) + t[index++] = polar( 32767.0, -2*PI*i*7.5e3/samplerate); + + for (int i=0; i < len ; i++) { + table_n[i*2] = floor(real(t[i])); + table_n[i*2+1] = floor(imag(t[i])); + } + + index=0; + double cpe = 512*ratio; + + for(int x=0 ; x <6 ; x++) + for (int i=-cpe; i<ofdm_size; i++) + t[index++] = polar( 32767.0, -2*PI*i*7.5e3/samplerate); + + for (int i=0; i < len ; i++) { + table_e[i*2] = floor(real(t[i])); + table_e[i*2+1] = floor(imag(t[i])); + } + } + + int16_t *s6n_kHz_7_5; + int16_t *s6e_kHz_7_5; + int16_t *s15n_kHz_7_5; + int16_t *s15e_kHz_7_5; + int16_t *s25n_kHz_7_5; + int16_t *s25e_kHz_7_5; + int16_t *s50n_kHz_7_5; + int16_t *s50e_kHz_7_5; + int16_t *s75n_kHz_7_5; + int16_t *s75e_kHz_7_5; + int16_t *s100n_kHz_7_5; + int16_t *s100e_kHz_7_5; + int16_t **tables[12]= {&s6n_kHz_7_5,&s6e_kHz_7_5, + &s15n_kHz_7_5,&s15e_kHz_7_5, + &s25n_kHz_7_5,&s25e_kHz_7_5, + &s50n_kHz_7_5,&s50e_kHz_7_5, + &s75n_kHz_7_5,&s75e_kHz_7_5, + &s100n_kHz_7_5,&s100e_kHz_7_5, + }; + int tables_size_bytes[12]; +#define MyAssert(x) { if(!(x)) { printf("Error in table intialization: %s:%d\n",__FILE__,__LINE__); exit(1);}} + void init_7_5KHz(void) { + const map<int,double> tables_7_5KHz= {{6,1.0/16},{15,1.0/8},{25,1.0/4},{50,1.0/2},{75,3.0/4},{100,1.0}}; + int tables_idx=0; + + for (auto it=tables_7_5KHz.begin(); it!=tables_7_5KHz.end(); ++it) { + int len=15360*it->second; + tables_size_bytes[tables_idx]=sizeof(int16_t)*2*len; + tables_size_bytes[tables_idx+1]=sizeof(int16_t)*2*len; + MyAssert(0==posix_memalign((void **)tables[tables_idx], + 16,tables_size_bytes[tables_idx])); + MyAssert(0==posix_memalign((void **)tables[tables_idx+1], + 16,tables_size_bytes[tables_idx+1])); + gen_sig(it->first, len, it->second, *tables[tables_idx], *tables[tables_idx+1]); + tables_idx+=2; + } + } +} diff --git a/openair1/PHY/MODULATION/gen_7_5_kHz.m b/openair1/PHY/MODULATION/gen_7_5_kHz.m deleted file mode 100644 index 39bc600336cbb7d0e035ebdef43bcc94a9aa9302..0000000000000000000000000000000000000000 --- a/openair1/PHY/MODULATION/gen_7_5_kHz.m +++ /dev/null @@ -1,107 +0,0 @@ - -function [] = gen_7_5_kHz() -[s6_n2, s6_e2] = gen_sig(6); -[s15_n2, s15_e2] = gen_sig(15); -[s25_n2, s25_e2] = gen_sig(25); -[s50_n2, s50_e2] = gen_sig(50); -[s75_n2, s75_e2] = gen_sig(75); -[s100_n2, s100_e2] = gen_sig(100); - - -fd=fopen("kHz_7_5.h","w"); -fprintf(fd,"s16 s6n_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s6_n2)); -fprintf(fd,"%d,",s6_n2(1:(end-1))); -fprintf(fd,"%d};\n\n",s6_n2(end)); - -fprintf(fd,"s16 s6e_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s6_e2)); -fprintf(fd,"%d,",s6_e2(1:(end-1))); -fprintf(fd,"%d};\n\n",s6_e2(end)); - -fprintf(fd,"s16 s15n_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s15_n2)); -fprintf(fd,"%d,",s15_n2(1:(end-1))); -fprintf(fd,"%d};\n\n",s15_n2(end)); - -fprintf(fd,"s16 s15e_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s15_e2)); -fprintf(fd,"%d,",s15_e2(1:(end-1))); -fprintf(fd,"%d};\n\n",s15_e2(end)); - -fprintf(fd,"s16 s25n_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s25_n2)); -fprintf(fd,"%d,",s25_n2(1:(end-1))); -fprintf(fd,"%d};\n\n",s25_n2(end)); - -fprintf(fd,"s16 s25e_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s25_e2)); -fprintf(fd,"%d,",s25_e2(1:(end-1))); -fprintf(fd,"%d};\n\n",s25_e2(end)); - -fprintf(fd,"s16 s50n_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s50_n2)); -fprintf(fd,"%d,",s50_n2(1:(end-1))); -fprintf(fd,"%d};\n\n",s50_n2(end)); - -fprintf(fd,"s16 s50e_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s50_e2)); -fprintf(fd,"%d,",s50_e2(1:(end-1))); -fprintf(fd,"%d};\n\n",s50_e2(end)); - -fprintf(fd,"s16 s75n_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s75_n2)); -fprintf(fd,"%d,",s75_n2(1:(end-1))); -fprintf(fd,"%d};\n\n",s75_n2(end)); - -fprintf(fd,"s16 s75e_kHz_7_5[%d]__attribute__((aligned(16))) = {",length(s75_e2)); -fprintf(fd,"%d,",s75_e2(1:(end-1))); -fprintf(fd,"%d};\n\n",s75_e2(end)); - -fprintf(fd,"s16 s100n_kHz_7_5[%d]__attribute__((aligned(16)))= {",length(s100_n2)); -fprintf(fd,"%d,",s100_n2(1:(end-1))); -fprintf(fd,"%d};\n\n",s100_n2(end)); - -fprintf(fd,"s16 s100e_kHz_7_5[%d]__attribute__((aligned(16)))= {",length(s100_n2)); -fprintf(fd,"%d,",s100_e2(1:(end-1))); -fprintf(fd,"%d};\n\n",s100_e2(end)); - -fclose(fd); -end - - -function [s_n2, s_e2] = gen_sig(RB) - % 20MHz BW - cp0 = 160; - cp = 144; - cpe = 512; - samplerate = 30.72e6; - ofdm_size = 2048; - len = 15360; - switch(RB) - case 6 - ratio = 1/16; - case 15 - ratio = 1/8; - case 25 - ratio = 1/4; - case 50 - ratio = 1/2; - case 75 - ratio = 3/4; - case 100 - ratio = 1; - otherwise - disp("Wrong Number of RB"); - end - cp0 = cp0*ratio; - cp = cp*ratio; - cpe = cpe*ratio; - samplerate = samplerate*ratio; - ofdm_size = ofdm_size*ratio; - len = len*ratio; - - s_n0 = floor(32767*exp(-sqrt(-1)*2*pi*(-cp0:ofdm_size-1)*7.5e3/samplerate)); - s_n1 = floor(32767*exp(-sqrt(-1)*2*pi*(-cp:ofdm_size-1)*7.5e3/samplerate)); - s_n = [s_n0 s_n1 s_n1 s_n1 s_n1 s_n1 s_n1]; - s_n2 = zeros(1, 2*len); - s_n2(1:2:end) = real(s_n); - s_n2(2:2:end) = imag(s_n); - s_e = floor(32767*exp(-sqrt(-1)*2*pi*(-cpe:ofdm_size-1)*7.5e3/samplerate)); - s_e = [s_e s_e s_e s_e s_e s_e]; - s_e2 = zeros(1, 2*len); - s_e2(1:2:end) = real(s_e); - s_e2(2:2:end) = imag(s_e); -end - diff --git a/openair1/PHY/MODULATION/kHz_7_5.h b/openair1/PHY/MODULATION/kHz_7_5.h deleted file mode 100644 index ce2f0d5f2c11a3c06a93baf368a99f8cee01308b..0000000000000000000000000000000000000000 --- a/openair1/PHY/MODULATION/kHz_7_5.h +++ /dev/null @@ -1,45 +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 - */ - -int16_t s6n_kHz_7_5[1920]__attribute__((aligned(16))) = {31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805}; - -int16_t s6e_kHz_7_5[1920]__attribute__((aligned(16))) = {23169,23169,23731,22594,24278,22004,24811,21402,25329,20787,25831,20159,26318,19519,26789,18867,27244,18204,27683,17530,28105,16845,28510,16150,28897,15446,29268,14732,29621,14009,29955,13278,30272,12539,30571,11792,30851,11038,31113,10278,31356,9511,31580,8739,31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,23169,23169,23731,22594,24278,22004,24811,21402,25329,20787,25831,20159,26318,19519,26789,18867,27244,18204,27683,17530,28105,16845,28510,16150,28897,15446,29268,14732,29621,14009,29955,13278,30272,12539,30571,11792,30851,11038,31113,10278,31356,9511,31580,8739,31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,23169,23169,23731,22594,24278,22004,24811,21402,25329,20787,25831,20159,26318,19519,26789,18867,27244,18204,27683,17530,28105,16845,28510,16150,28897,15446,29268,14732,29621,14009,29955,13278,30272,12539,30571,11792,30851,11038,31113,10278,31356,9511,31580,8739,31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,23169,23169,23731,22594,24278,22004,24811,21402,25329,20787,25831,20159,26318,19519,26789,18867,27244,18204,27683,17530,28105,16845,28510,16150,28897,15446,29268,14732,29621,14009,29955,13278,30272,12539,30571,11792,30851,11038,31113,10278,31356,9511,31580,8739,31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,23169,23169,23731,22594,24278,22004,24811,21402,25329,20787,25831,20159,26318,19519,26789,18867,27244,18204,27683,17530,28105,16845,28510,16150,28897,15446,29268,14732,29621,14009,29955,13278,30272,12539,30571,11792,30851,11038,31113,10278,31356,9511,31580,8739,31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805,23169,23169,23731,22594,24278,22004,24811,21402,25329,20787,25831,20159,26318,19519,26789,18867,27244,18204,27683,17530,28105,16845,28510,16150,28897,15446,29268,14732,29621,14009,29955,13278,30272,12539,30571,11792,30851,11038,31113,10278,31356,9511,31580,8739,31785,7961,31970,7179,32137,6392,32284,5601,32412,4807,32520,4011,32609,3211,32678,2410,32727,1607,32757,804,32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,0,-32767,-805,-32758,-1608,-32728,-2411,-32679,-3212,-32610,-4012,-32521,-4808,-32413,-5602,-32285,-6393,-32138,-7180,-31971,-7962,-31786,-8740,-31581,-9512,-31357,-10279,-31114,-11039,-30852,-11793,-30572,-12540,-30273,-13279,-29956,-14010,-29622,-14733,-29269,-15447,-28898,-16151,-28511,-16846,-28106,-17531,-27684,-18205,-27245,-18868,-26790,-19520,-26319,-20160,-25832,-20788,-25330,-21403,-24812,-22005,-24279,-22595,-23732,-23170,-23170,-23732,-22595,-24279,-22005,-24812,-21403,-25330,-20788,-25832,-20160,-26319,-19520,-26790,-18868,-27245,-18205,-27684,-17531,-28106,-16846,-28511,-16151,-28898,-15447,-29269,-14733,-29622,-14010,-29956,-13279,-30273,-12540,-30572,-11793,-30852,-11039,-31114,-10279,-31357,-9512,-31581,-8740,-31786,-7962,-31971,-7180,-32138,-6393,-32285,-5602,-32413,-4808,-32521,-4012,-32610,-3212,-32679,-2411,-32728,-1608,-32758,-805}; - -int16_t s15n_kHz_7_5[3840]__attribute__((aligned(16))) = {31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403}; - -int16_t s15e_kHz_7_5[3840]__attribute__((aligned(16))) = {23169,23169,23452,22883,23731,22594,24006,22301,24278,22004,24546,21705,24811,21402,25072,21096,25329,20787,25582,20474,25831,20159,26077,19840,26318,19519,26556,19194,26789,18867,27019,18537,27244,18204,27466,17868,27683,17530,27896,17189,28105,16845,28309,16499,28510,16150,28706,15799,28897,15446,29085,15090,29268,14732,29446,14372,29621,14009,29790,13645,29955,13278,30116,12909,30272,12539,30424,12166,30571,11792,30713,11416,30851,11038,30984,10659,31113,10278,31236,9895,31356,9511,31470,9126,31580,8739,31684,8351,31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,23169,23169,23452,22883,23731,22594,24006,22301,24278,22004,24546,21705,24811,21402,25072,21096,25329,20787,25582,20474,25831,20159,26077,19840,26318,19519,26556,19194,26789,18867,27019,18537,27244,18204,27466,17868,27683,17530,27896,17189,28105,16845,28309,16499,28510,16150,28706,15799,28897,15446,29085,15090,29268,14732,29446,14372,29621,14009,29790,13645,29955,13278,30116,12909,30272,12539,30424,12166,30571,11792,30713,11416,30851,11038,30984,10659,31113,10278,31236,9895,31356,9511,31470,9126,31580,8739,31684,8351,31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,23169,23169,23452,22883,23731,22594,24006,22301,24278,22004,24546,21705,24811,21402,25072,21096,25329,20787,25582,20474,25831,20159,26077,19840,26318,19519,26556,19194,26789,18867,27019,18537,27244,18204,27466,17868,27683,17530,27896,17189,28105,16845,28309,16499,28510,16150,28706,15799,28897,15446,29085,15090,29268,14732,29446,14372,29621,14009,29790,13645,29955,13278,30116,12909,30272,12539,30424,12166,30571,11792,30713,11416,30851,11038,30984,10659,31113,10278,31236,9895,31356,9511,31470,9126,31580,8739,31684,8351,31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,23169,23169,23452,22883,23731,22594,24006,22301,24278,22004,24546,21705,24811,21402,25072,21096,25329,20787,25582,20474,25831,20159,26077,19840,26318,19519,26556,19194,26789,18867,27019,18537,27244,18204,27466,17868,27683,17530,27896,17189,28105,16845,28309,16499,28510,16150,28706,15799,28897,15446,29085,15090,29268,14732,29446,14372,29621,14009,29790,13645,29955,13278,30116,12909,30272,12539,30424,12166,30571,11792,30713,11416,30851,11038,30984,10659,31113,10278,31236,9895,31356,9511,31470,9126,31580,8739,31684,8351,31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,23169,23169,23452,22883,23731,22594,24006,22301,24278,22004,24546,21705,24811,21402,25072,21096,25329,20787,25582,20474,25831,20159,26077,19840,26318,19519,26556,19194,26789,18867,27019,18537,27244,18204,27466,17868,27683,17530,27896,17189,28105,16845,28309,16499,28510,16150,28706,15799,28897,15446,29085,15090,29268,14732,29446,14372,29621,14009,29790,13645,29955,13278,30116,12909,30272,12539,30424,12166,30571,11792,30713,11416,30851,11038,30984,10659,31113,10278,31236,9895,31356,9511,31470,9126,31580,8739,31684,8351,31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403,23169,23169,23452,22883,23731,22594,24006,22301,24278,22004,24546,21705,24811,21402,25072,21096,25329,20787,25582,20474,25831,20159,26077,19840,26318,19519,26556,19194,26789,18867,27019,18537,27244,18204,27466,17868,27683,17530,27896,17189,28105,16845,28309,16499,28510,16150,28706,15799,28897,15446,29085,15090,29268,14732,29446,14372,29621,14009,29790,13645,29955,13278,30116,12909,30272,12539,30424,12166,30571,11792,30713,11416,30851,11038,30984,10659,31113,10278,31236,9895,31356,9511,31470,9126,31580,8739,31684,8351,31785,7961,31880,7571,31970,7179,32056,6786,32137,6392,32213,5997,32284,5601,32350,5205,32412,4807,32468,4409,32520,4011,32567,3611,32609,3211,32646,2811,32678,2410,32705,2009,32727,1607,32744,1206,32757,804,32764,402,32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403}; - -int16_t s25n_kHz_7_5[7680]__attribute__((aligned(16))) = {31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202}; - -int16_t s25e_kHz_7_5[7680]__attribute__((aligned(16))) = {23169,23169,23311,23027,23452,22883,23592,22739,23731,22594,23869,22448,24006,22301,24143,22153,24278,22004,24413,21855,24546,21705,24679,21554,24811,21402,24942,21249,25072,21096,25201,20942,25329,20787,25456,20631,25582,20474,25707,20317,25831,20159,25954,20000,26077,19840,26198,19680,26318,19519,26437,19357,26556,19194,26673,19031,26789,18867,26905,18702,27019,18537,27132,18371,27244,18204,27355,18036,27466,17868,27575,17699,27683,17530,27790,17360,27896,17189,28001,17017,28105,16845,28208,16672,28309,16499,28410,16325,28510,16150,28608,15975,28706,15799,28802,15623,28897,15446,28992,15268,29085,15090,29177,14911,29268,14732,29358,14552,29446,14372,29534,14191,29621,14009,29706,13827,29790,13645,29873,13462,29955,13278,30036,13094,30116,12909,30195,12724,30272,12539,30349,12353,30424,12166,30498,11980,30571,11792,30643,11604,30713,11416,30783,11227,30851,11038,30918,10849,30984,10659,31049,10469,31113,10278,31175,10087,31236,9895,31297,9703,31356,9511,31413,9319,31470,9126,31525,8932,31580,8739,31633,8545,31684,8351,31735,8156,31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,23169,23169,23311,23027,23452,22883,23592,22739,23731,22594,23869,22448,24006,22301,24143,22153,24278,22004,24413,21855,24546,21705,24679,21554,24811,21402,24942,21249,25072,21096,25201,20942,25329,20787,25456,20631,25582,20474,25707,20317,25831,20159,25954,20000,26077,19840,26198,19680,26318,19519,26437,19357,26556,19194,26673,19031,26789,18867,26905,18702,27019,18537,27132,18371,27244,18204,27355,18036,27466,17868,27575,17699,27683,17530,27790,17360,27896,17189,28001,17017,28105,16845,28208,16672,28309,16499,28410,16325,28510,16150,28608,15975,28706,15799,28802,15623,28897,15446,28992,15268,29085,15090,29177,14911,29268,14732,29358,14552,29446,14372,29534,14191,29621,14009,29706,13827,29790,13645,29873,13462,29955,13278,30036,13094,30116,12909,30195,12724,30272,12539,30349,12353,30424,12166,30498,11980,30571,11792,30643,11604,30713,11416,30783,11227,30851,11038,30918,10849,30984,10659,31049,10469,31113,10278,31175,10087,31236,9895,31297,9703,31356,9511,31413,9319,31470,9126,31525,8932,31580,8739,31633,8545,31684,8351,31735,8156,31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,23169,23169,23311,23027,23452,22883,23592,22739,23731,22594,23869,22448,24006,22301,24143,22153,24278,22004,24413,21855,24546,21705,24679,21554,24811,21402,24942,21249,25072,21096,25201,20942,25329,20787,25456,20631,25582,20474,25707,20317,25831,20159,25954,20000,26077,19840,26198,19680,26318,19519,26437,19357,26556,19194,26673,19031,26789,18867,26905,18702,27019,18537,27132,18371,27244,18204,27355,18036,27466,17868,27575,17699,27683,17530,27790,17360,27896,17189,28001,17017,28105,16845,28208,16672,28309,16499,28410,16325,28510,16150,28608,15975,28706,15799,28802,15623,28897,15446,28992,15268,29085,15090,29177,14911,29268,14732,29358,14552,29446,14372,29534,14191,29621,14009,29706,13827,29790,13645,29873,13462,29955,13278,30036,13094,30116,12909,30195,12724,30272,12539,30349,12353,30424,12166,30498,11980,30571,11792,30643,11604,30713,11416,30783,11227,30851,11038,30918,10849,30984,10659,31049,10469,31113,10278,31175,10087,31236,9895,31297,9703,31356,9511,31413,9319,31470,9126,31525,8932,31580,8739,31633,8545,31684,8351,31735,8156,31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,23169,23169,23311,23027,23452,22883,23592,22739,23731,22594,23869,22448,24006,22301,24143,22153,24278,22004,24413,21855,24546,21705,24679,21554,24811,21402,24942,21249,25072,21096,25201,20942,25329,20787,25456,20631,25582,20474,25707,20317,25831,20159,25954,20000,26077,19840,26198,19680,26318,19519,26437,19357,26556,19194,26673,19031,26789,18867,26905,18702,27019,18537,27132,18371,27244,18204,27355,18036,27466,17868,27575,17699,27683,17530,27790,17360,27896,17189,28001,17017,28105,16845,28208,16672,28309,16499,28410,16325,28510,16150,28608,15975,28706,15799,28802,15623,28897,15446,28992,15268,29085,15090,29177,14911,29268,14732,29358,14552,29446,14372,29534,14191,29621,14009,29706,13827,29790,13645,29873,13462,29955,13278,30036,13094,30116,12909,30195,12724,30272,12539,30349,12353,30424,12166,30498,11980,30571,11792,30643,11604,30713,11416,30783,11227,30851,11038,30918,10849,30984,10659,31049,10469,31113,10278,31175,10087,31236,9895,31297,9703,31356,9511,31413,9319,31470,9126,31525,8932,31580,8739,31633,8545,31684,8351,31735,8156,31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,23169,23169,23311,23027,23452,22883,23592,22739,23731,22594,23869,22448,24006,22301,24143,22153,24278,22004,24413,21855,24546,21705,24679,21554,24811,21402,24942,21249,25072,21096,25201,20942,25329,20787,25456,20631,25582,20474,25707,20317,25831,20159,25954,20000,26077,19840,26198,19680,26318,19519,26437,19357,26556,19194,26673,19031,26789,18867,26905,18702,27019,18537,27132,18371,27244,18204,27355,18036,27466,17868,27575,17699,27683,17530,27790,17360,27896,17189,28001,17017,28105,16845,28208,16672,28309,16499,28410,16325,28510,16150,28608,15975,28706,15799,28802,15623,28897,15446,28992,15268,29085,15090,29177,14911,29268,14732,29358,14552,29446,14372,29534,14191,29621,14009,29706,13827,29790,13645,29873,13462,29955,13278,30036,13094,30116,12909,30195,12724,30272,12539,30349,12353,30424,12166,30498,11980,30571,11792,30643,11604,30713,11416,30783,11227,30851,11038,30918,10849,30984,10659,31049,10469,31113,10278,31175,10087,31236,9895,31297,9703,31356,9511,31413,9319,31470,9126,31525,8932,31580,8739,31633,8545,31684,8351,31735,8156,31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202,23169,23169,23311,23027,23452,22883,23592,22739,23731,22594,23869,22448,24006,22301,24143,22153,24278,22004,24413,21855,24546,21705,24679,21554,24811,21402,24942,21249,25072,21096,25201,20942,25329,20787,25456,20631,25582,20474,25707,20317,25831,20159,25954,20000,26077,19840,26198,19680,26318,19519,26437,19357,26556,19194,26673,19031,26789,18867,26905,18702,27019,18537,27132,18371,27244,18204,27355,18036,27466,17868,27575,17699,27683,17530,27790,17360,27896,17189,28001,17017,28105,16845,28208,16672,28309,16499,28410,16325,28510,16150,28608,15975,28706,15799,28802,15623,28897,15446,28992,15268,29085,15090,29177,14911,29268,14732,29358,14552,29446,14372,29534,14191,29621,14009,29706,13827,29790,13645,29873,13462,29955,13278,30036,13094,30116,12909,30195,12724,30272,12539,30349,12353,30424,12166,30498,11980,30571,11792,30643,11604,30713,11416,30783,11227,30851,11038,30918,10849,30984,10659,31049,10469,31113,10278,31175,10087,31236,9895,31297,9703,31356,9511,31413,9319,31470,9126,31525,8932,31580,8739,31633,8545,31684,8351,31735,8156,31785,7961,31833,7766,31880,7571,31926,7375,31970,7179,32014,6982,32056,6786,32097,6589,32137,6392,32176,6195,32213,5997,32249,5799,32284,5601,32318,5403,32350,5205,32382,5006,32412,4807,32441,4608,32468,4409,32495,4210,32520,4011,32544,3811,32567,3611,32588,3411,32609,3211,32628,3011,32646,2811,32662,2610,32678,2410,32692,2209,32705,2009,32717,1808,32727,1607,32736,1406,32744,1206,32751,1005,32757,804,32761,603,32764,402,32766,201,32767,0,32766,-202,32764,-403,32761,-604,32757,-805,32751,-1006,32744,-1207,32736,-1407,32727,-1608,32717,-1809,32705,-2010,32692,-2210,32678,-2411,32662,-2611,32646,-2812,32628,-3012,32609,-3212,32588,-3412,32567,-3612,32544,-3812,32520,-4012,32495,-4211,32468,-4410,32441,-4609,32412,-4808,32382,-5007,32350,-5206,32318,-5404,32284,-5602,32249,-5800,32213,-5998,32176,-6196,32137,-6393,32097,-6590,32056,-6787,32014,-6983,31970,-7180,31926,-7376,31880,-7572,31833,-7767,31785,-7962,31735,-8157,31684,-8352,31633,-8546,31580,-8740,31525,-8933,31470,-9127,31413,-9320,31356,-9512,31297,-9704,31236,-9896,31175,-10088,31113,-10279,31049,-10470,30984,-10660,30918,-10850,30851,-11039,30783,-11228,30713,-11417,30643,-11605,30571,-11793,30498,-11981,30424,-12167,30349,-12354,30272,-12540,30195,-12725,30116,-12910,30036,-13095,29955,-13279,29873,-13463,29790,-13646,29706,-13828,29621,-14010,29534,-14192,29446,-14373,29358,-14553,29268,-14733,29177,-14912,29085,-15091,28992,-15269,28897,-15447,28802,-15624,28706,-15800,28608,-15976,28510,-16151,28410,-16326,28309,-16500,28208,-16673,28105,-16846,28001,-17018,27896,-17190,27790,-17361,27683,-17531,27575,-17700,27466,-17869,27355,-18037,27244,-18205,27132,-18372,27019,-18538,26905,-18703,26789,-18868,26673,-19032,26556,-19195,26437,-19358,26318,-19520,26198,-19681,26077,-19841,25954,-20001,25831,-20160,25707,-20318,25582,-20475,25456,-20632,25329,-20788,25201,-20943,25072,-21097,24942,-21250,24811,-21403,24679,-21555,24546,-21706,24413,-21856,24278,-22005,24143,-22154,24006,-22302,23869,-22449,23731,-22595,23592,-22740,23452,-22884,23311,-23028,23169,-23170,23027,-23312,22883,-23453,22739,-23593,22594,-23732,22448,-23870,22301,-24007,22153,-24144,22004,-24279,21855,-24414,21705,-24547,21554,-24680,21402,-24812,21249,-24943,21096,-25073,20942,-25202,20787,-25330,20631,-25457,20474,-25583,20317,-25708,20159,-25832,20000,-25955,19840,-26078,19680,-26199,19519,-26319,19357,-26438,19194,-26557,19031,-26674,18867,-26790,18702,-26906,18537,-27020,18371,-27133,18204,-27245,18036,-27356,17868,-27467,17699,-27576,17530,-27684,17360,-27791,17189,-27897,17017,-28002,16845,-28106,16672,-28209,16499,-28310,16325,-28411,16150,-28511,15975,-28609,15799,-28707,15623,-28803,15446,-28898,15268,-28993,15090,-29086,14911,-29178,14732,-29269,14552,-29359,14372,-29447,14191,-29535,14009,-29622,13827,-29707,13645,-29791,13462,-29874,13278,-29956,13094,-30037,12909,-30117,12724,-30196,12539,-30273,12353,-30350,12166,-30425,11980,-30499,11792,-30572,11604,-30644,11416,-30714,11227,-30784,11038,-30852,10849,-30919,10659,-30985,10469,-31050,10278,-31114,10087,-31176,9895,-31237,9703,-31298,9511,-31357,9319,-31414,9126,-31471,8932,-31526,8739,-31581,8545,-31634,8351,-31685,8156,-31736,7961,-31786,7766,-31834,7571,-31881,7375,-31927,7179,-31971,6982,-32015,6786,-32057,6589,-32098,6392,-32138,6195,-32177,5997,-32214,5799,-32250,5601,-32285,5403,-32319,5205,-32351,5006,-32383,4807,-32413,4608,-32442,4409,-32469,4210,-32496,4011,-32521,3811,-32545,3611,-32568,3411,-32589,3211,-32610,3011,-32629,2811,-32647,2610,-32663,2410,-32679,2209,-32693,2009,-32706,1808,-32718,1607,-32728,1406,-32737,1206,-32745,1005,-32752,804,-32758,603,-32762,402,-32765,201,-32767,0,-32767,-202,-32767,-403,-32765,-604,-32762,-805,-32758,-1006,-32752,-1207,-32745,-1407,-32737,-1608,-32728,-1809,-32718,-2010,-32706,-2210,-32693,-2411,-32679,-2611,-32663,-2812,-32647,-3012,-32629,-3212,-32610,-3412,-32589,-3612,-32568,-3812,-32545,-4012,-32521,-4211,-32496,-4410,-32469,-4609,-32442,-4808,-32413,-5007,-32383,-5206,-32351,-5404,-32319,-5602,-32285,-5800,-32250,-5998,-32214,-6196,-32177,-6393,-32138,-6590,-32098,-6787,-32057,-6983,-32015,-7180,-31971,-7376,-31927,-7572,-31881,-7767,-31834,-7962,-31786,-8157,-31736,-8352,-31685,-8546,-31634,-8740,-31581,-8933,-31526,-9127,-31471,-9320,-31414,-9512,-31357,-9704,-31298,-9896,-31237,-10088,-31176,-10279,-31114,-10470,-31050,-10660,-30985,-10850,-30919,-11039,-30852,-11228,-30784,-11417,-30714,-11605,-30644,-11793,-30572,-11981,-30499,-12167,-30425,-12354,-30350,-12540,-30273,-12725,-30196,-12910,-30117,-13095,-30037,-13279,-29956,-13463,-29874,-13646,-29791,-13828,-29707,-14010,-29622,-14192,-29535,-14373,-29447,-14553,-29359,-14733,-29269,-14912,-29178,-15091,-29086,-15269,-28993,-15447,-28898,-15624,-28803,-15800,-28707,-15976,-28609,-16151,-28511,-16326,-28411,-16500,-28310,-16673,-28209,-16846,-28106,-17018,-28002,-17190,-27897,-17361,-27791,-17531,-27684,-17700,-27576,-17869,-27467,-18037,-27356,-18205,-27245,-18372,-27133,-18538,-27020,-18703,-26906,-18868,-26790,-19032,-26674,-19195,-26557,-19358,-26438,-19520,-26319,-19681,-26199,-19841,-26078,-20001,-25955,-20160,-25832,-20318,-25708,-20475,-25583,-20632,-25457,-20788,-25330,-20943,-25202,-21097,-25073,-21250,-24943,-21403,-24812,-21555,-24680,-21706,-24547,-21856,-24414,-22005,-24279,-22154,-24144,-22302,-24007,-22449,-23870,-22595,-23732,-22740,-23593,-22884,-23453,-23028,-23312,-23170,-23170,-23312,-23028,-23453,-22884,-23593,-22740,-23732,-22595,-23870,-22449,-24007,-22302,-24144,-22154,-24279,-22005,-24414,-21856,-24547,-21706,-24680,-21555,-24812,-21403,-24943,-21250,-25073,-21097,-25202,-20943,-25330,-20788,-25457,-20632,-25583,-20475,-25708,-20318,-25832,-20160,-25955,-20001,-26078,-19841,-26199,-19681,-26319,-19520,-26438,-19358,-26557,-19195,-26674,-19032,-26790,-18868,-26906,-18703,-27020,-18538,-27133,-18372,-27245,-18205,-27356,-18037,-27467,-17869,-27576,-17700,-27684,-17531,-27791,-17361,-27897,-17190,-28002,-17018,-28106,-16846,-28209,-16673,-28310,-16500,-28411,-16326,-28511,-16151,-28609,-15976,-28707,-15800,-28803,-15624,-28898,-15447,-28993,-15269,-29086,-15091,-29178,-14912,-29269,-14733,-29359,-14553,-29447,-14373,-29535,-14192,-29622,-14010,-29707,-13828,-29791,-13646,-29874,-13463,-29956,-13279,-30037,-13095,-30117,-12910,-30196,-12725,-30273,-12540,-30350,-12354,-30425,-12167,-30499,-11981,-30572,-11793,-30644,-11605,-30714,-11417,-30784,-11228,-30852,-11039,-30919,-10850,-30985,-10660,-31050,-10470,-31114,-10279,-31176,-10088,-31237,-9896,-31298,-9704,-31357,-9512,-31414,-9320,-31471,-9127,-31526,-8933,-31581,-8740,-31634,-8546,-31685,-8352,-31736,-8157,-31786,-7962,-31834,-7767,-31881,-7572,-31927,-7376,-31971,-7180,-32015,-6983,-32057,-6787,-32098,-6590,-32138,-6393,-32177,-6196,-32214,-5998,-32250,-5800,-32285,-5602,-32319,-5404,-32351,-5206,-32383,-5007,-32413,-4808,-32442,-4609,-32469,-4410,-32496,-4211,-32521,-4012,-32545,-3812,-32568,-3612,-32589,-3412,-32610,-3212,-32629,-3012,-32647,-2812,-32663,-2611,-32679,-2411,-32693,-2210,-32706,-2010,-32718,-1809,-32728,-1608,-32737,-1407,-32745,-1207,-32752,-1006,-32758,-805,-32762,-604,-32765,-403,-32767,-202}; - -int16_t s50n_kHz_7_5[15360]__attribute__((aligned(16))) = {31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101}; - -int16_t s50e_kHz_7_5[15360]__attribute__((aligned(16))) = {23169,23169,23240,23098,23311,23027,23382,22955,23452,22883,23522,22811,23592,22739,23661,22666,23731,22594,23800,22521,23869,22448,23938,22374,24006,22301,24075,22227,24143,22153,24211,22079,24278,22004,24346,21930,24413,21855,24480,21780,24546,21705,24613,21629,24679,21554,24745,21478,24811,21402,24877,21326,24942,21249,25007,21173,25072,21096,25136,21019,25201,20942,25265,20864,25329,20787,25392,20709,25456,20631,25519,20553,25582,20474,25645,20396,25707,20317,25769,20238,25831,20159,25893,20079,25954,20000,26016,19920,26077,19840,26137,19760,26198,19680,26258,19599,26318,19519,26378,19438,26437,19357,26497,19276,26556,19194,26615,19113,26673,19031,26731,18949,26789,18867,26847,18785,26905,18702,26962,18620,27019,18537,27076,18454,27132,18371,27188,18287,27244,18204,27300,18120,27355,18036,27411,17952,27466,17868,27520,17784,27575,17699,27629,17615,27683,17530,27736,17445,27790,17360,27843,17274,27896,17189,27948,17103,28001,17017,28053,16931,28105,16845,28156,16759,28208,16672,28259,16586,28309,16499,28360,16412,28410,16325,28460,16238,28510,16150,28559,16063,28608,15975,28657,15887,28706,15799,28754,15711,28802,15623,28850,15534,28897,15446,28945,15357,28992,15268,29038,15179,29085,15090,29131,15001,29177,14911,29222,14822,29268,14732,29313,14642,29358,14552,29402,14462,29446,14372,29490,14281,29534,14191,29577,14100,29621,14009,29663,13918,29706,13827,29748,13736,29790,13645,29832,13553,29873,13462,29915,13370,29955,13278,29996,13186,30036,13094,30076,13002,30116,12909,30156,12817,30195,12724,30234,12632,30272,12539,30311,12446,30349,12353,30386,12260,30424,12166,30461,12073,30498,11980,30535,11886,30571,11792,30607,11698,30643,11604,30678,11510,30713,11416,30748,11322,30783,11227,30817,11133,30851,11038,30885,10944,30918,10849,30951,10754,30984,10659,31017,10564,31049,10469,31081,10373,31113,10278,31144,10182,31175,10087,31206,9991,31236,9895,31267,9799,31297,9703,31326,9607,31356,9511,31385,9415,31413,9319,31442,9222,31470,9126,31498,9029,31525,8932,31553,8836,31580,8739,31606,8642,31633,8545,31659,8448,31684,8351,31710,8253,31735,8156,31760,8059,31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,23169,23169,23240,23098,23311,23027,23382,22955,23452,22883,23522,22811,23592,22739,23661,22666,23731,22594,23800,22521,23869,22448,23938,22374,24006,22301,24075,22227,24143,22153,24211,22079,24278,22004,24346,21930,24413,21855,24480,21780,24546,21705,24613,21629,24679,21554,24745,21478,24811,21402,24877,21326,24942,21249,25007,21173,25072,21096,25136,21019,25201,20942,25265,20864,25329,20787,25392,20709,25456,20631,25519,20553,25582,20474,25645,20396,25707,20317,25769,20238,25831,20159,25893,20079,25954,20000,26016,19920,26077,19840,26137,19760,26198,19680,26258,19599,26318,19519,26378,19438,26437,19357,26497,19276,26556,19194,26615,19113,26673,19031,26731,18949,26789,18867,26847,18785,26905,18702,26962,18620,27019,18537,27076,18454,27132,18371,27188,18287,27244,18204,27300,18120,27355,18036,27411,17952,27466,17868,27520,17784,27575,17699,27629,17615,27683,17530,27736,17445,27790,17360,27843,17274,27896,17189,27948,17103,28001,17017,28053,16931,28105,16845,28156,16759,28208,16672,28259,16586,28309,16499,28360,16412,28410,16325,28460,16238,28510,16150,28559,16063,28608,15975,28657,15887,28706,15799,28754,15711,28802,15623,28850,15534,28897,15446,28945,15357,28992,15268,29038,15179,29085,15090,29131,15001,29177,14911,29222,14822,29268,14732,29313,14642,29358,14552,29402,14462,29446,14372,29490,14281,29534,14191,29577,14100,29621,14009,29663,13918,29706,13827,29748,13736,29790,13645,29832,13553,29873,13462,29915,13370,29955,13278,29996,13186,30036,13094,30076,13002,30116,12909,30156,12817,30195,12724,30234,12632,30272,12539,30311,12446,30349,12353,30386,12260,30424,12166,30461,12073,30498,11980,30535,11886,30571,11792,30607,11698,30643,11604,30678,11510,30713,11416,30748,11322,30783,11227,30817,11133,30851,11038,30885,10944,30918,10849,30951,10754,30984,10659,31017,10564,31049,10469,31081,10373,31113,10278,31144,10182,31175,10087,31206,9991,31236,9895,31267,9799,31297,9703,31326,9607,31356,9511,31385,9415,31413,9319,31442,9222,31470,9126,31498,9029,31525,8932,31553,8836,31580,8739,31606,8642,31633,8545,31659,8448,31684,8351,31710,8253,31735,8156,31760,8059,31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,23169,23169,23240,23098,23311,23027,23382,22955,23452,22883,23522,22811,23592,22739,23661,22666,23731,22594,23800,22521,23869,22448,23938,22374,24006,22301,24075,22227,24143,22153,24211,22079,24278,22004,24346,21930,24413,21855,24480,21780,24546,21705,24613,21629,24679,21554,24745,21478,24811,21402,24877,21326,24942,21249,25007,21173,25072,21096,25136,21019,25201,20942,25265,20864,25329,20787,25392,20709,25456,20631,25519,20553,25582,20474,25645,20396,25707,20317,25769,20238,25831,20159,25893,20079,25954,20000,26016,19920,26077,19840,26137,19760,26198,19680,26258,19599,26318,19519,26378,19438,26437,19357,26497,19276,26556,19194,26615,19113,26673,19031,26731,18949,26789,18867,26847,18785,26905,18702,26962,18620,27019,18537,27076,18454,27132,18371,27188,18287,27244,18204,27300,18120,27355,18036,27411,17952,27466,17868,27520,17784,27575,17699,27629,17615,27683,17530,27736,17445,27790,17360,27843,17274,27896,17189,27948,17103,28001,17017,28053,16931,28105,16845,28156,16759,28208,16672,28259,16586,28309,16499,28360,16412,28410,16325,28460,16238,28510,16150,28559,16063,28608,15975,28657,15887,28706,15799,28754,15711,28802,15623,28850,15534,28897,15446,28945,15357,28992,15268,29038,15179,29085,15090,29131,15001,29177,14911,29222,14822,29268,14732,29313,14642,29358,14552,29402,14462,29446,14372,29490,14281,29534,14191,29577,14100,29621,14009,29663,13918,29706,13827,29748,13736,29790,13645,29832,13553,29873,13462,29915,13370,29955,13278,29996,13186,30036,13094,30076,13002,30116,12909,30156,12817,30195,12724,30234,12632,30272,12539,30311,12446,30349,12353,30386,12260,30424,12166,30461,12073,30498,11980,30535,11886,30571,11792,30607,11698,30643,11604,30678,11510,30713,11416,30748,11322,30783,11227,30817,11133,30851,11038,30885,10944,30918,10849,30951,10754,30984,10659,31017,10564,31049,10469,31081,10373,31113,10278,31144,10182,31175,10087,31206,9991,31236,9895,31267,9799,31297,9703,31326,9607,31356,9511,31385,9415,31413,9319,31442,9222,31470,9126,31498,9029,31525,8932,31553,8836,31580,8739,31606,8642,31633,8545,31659,8448,31684,8351,31710,8253,31735,8156,31760,8059,31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,23169,23169,23240,23098,23311,23027,23382,22955,23452,22883,23522,22811,23592,22739,23661,22666,23731,22594,23800,22521,23869,22448,23938,22374,24006,22301,24075,22227,24143,22153,24211,22079,24278,22004,24346,21930,24413,21855,24480,21780,24546,21705,24613,21629,24679,21554,24745,21478,24811,21402,24877,21326,24942,21249,25007,21173,25072,21096,25136,21019,25201,20942,25265,20864,25329,20787,25392,20709,25456,20631,25519,20553,25582,20474,25645,20396,25707,20317,25769,20238,25831,20159,25893,20079,25954,20000,26016,19920,26077,19840,26137,19760,26198,19680,26258,19599,26318,19519,26378,19438,26437,19357,26497,19276,26556,19194,26615,19113,26673,19031,26731,18949,26789,18867,26847,18785,26905,18702,26962,18620,27019,18537,27076,18454,27132,18371,27188,18287,27244,18204,27300,18120,27355,18036,27411,17952,27466,17868,27520,17784,27575,17699,27629,17615,27683,17530,27736,17445,27790,17360,27843,17274,27896,17189,27948,17103,28001,17017,28053,16931,28105,16845,28156,16759,28208,16672,28259,16586,28309,16499,28360,16412,28410,16325,28460,16238,28510,16150,28559,16063,28608,15975,28657,15887,28706,15799,28754,15711,28802,15623,28850,15534,28897,15446,28945,15357,28992,15268,29038,15179,29085,15090,29131,15001,29177,14911,29222,14822,29268,14732,29313,14642,29358,14552,29402,14462,29446,14372,29490,14281,29534,14191,29577,14100,29621,14009,29663,13918,29706,13827,29748,13736,29790,13645,29832,13553,29873,13462,29915,13370,29955,13278,29996,13186,30036,13094,30076,13002,30116,12909,30156,12817,30195,12724,30234,12632,30272,12539,30311,12446,30349,12353,30386,12260,30424,12166,30461,12073,30498,11980,30535,11886,30571,11792,30607,11698,30643,11604,30678,11510,30713,11416,30748,11322,30783,11227,30817,11133,30851,11038,30885,10944,30918,10849,30951,10754,30984,10659,31017,10564,31049,10469,31081,10373,31113,10278,31144,10182,31175,10087,31206,9991,31236,9895,31267,9799,31297,9703,31326,9607,31356,9511,31385,9415,31413,9319,31442,9222,31470,9126,31498,9029,31525,8932,31553,8836,31580,8739,31606,8642,31633,8545,31659,8448,31684,8351,31710,8253,31735,8156,31760,8059,31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,23169,23169,23240,23098,23311,23027,23382,22955,23452,22883,23522,22811,23592,22739,23661,22666,23731,22594,23800,22521,23869,22448,23938,22374,24006,22301,24075,22227,24143,22153,24211,22079,24278,22004,24346,21930,24413,21855,24480,21780,24546,21705,24613,21629,24679,21554,24745,21478,24811,21402,24877,21326,24942,21249,25007,21173,25072,21096,25136,21019,25201,20942,25265,20864,25329,20787,25392,20709,25456,20631,25519,20553,25582,20474,25645,20396,25707,20317,25769,20238,25831,20159,25893,20079,25954,20000,26016,19920,26077,19840,26137,19760,26198,19680,26258,19599,26318,19519,26378,19438,26437,19357,26497,19276,26556,19194,26615,19113,26673,19031,26731,18949,26789,18867,26847,18785,26905,18702,26962,18620,27019,18537,27076,18454,27132,18371,27188,18287,27244,18204,27300,18120,27355,18036,27411,17952,27466,17868,27520,17784,27575,17699,27629,17615,27683,17530,27736,17445,27790,17360,27843,17274,27896,17189,27948,17103,28001,17017,28053,16931,28105,16845,28156,16759,28208,16672,28259,16586,28309,16499,28360,16412,28410,16325,28460,16238,28510,16150,28559,16063,28608,15975,28657,15887,28706,15799,28754,15711,28802,15623,28850,15534,28897,15446,28945,15357,28992,15268,29038,15179,29085,15090,29131,15001,29177,14911,29222,14822,29268,14732,29313,14642,29358,14552,29402,14462,29446,14372,29490,14281,29534,14191,29577,14100,29621,14009,29663,13918,29706,13827,29748,13736,29790,13645,29832,13553,29873,13462,29915,13370,29955,13278,29996,13186,30036,13094,30076,13002,30116,12909,30156,12817,30195,12724,30234,12632,30272,12539,30311,12446,30349,12353,30386,12260,30424,12166,30461,12073,30498,11980,30535,11886,30571,11792,30607,11698,30643,11604,30678,11510,30713,11416,30748,11322,30783,11227,30817,11133,30851,11038,30885,10944,30918,10849,30951,10754,30984,10659,31017,10564,31049,10469,31081,10373,31113,10278,31144,10182,31175,10087,31206,9991,31236,9895,31267,9799,31297,9703,31326,9607,31356,9511,31385,9415,31413,9319,31442,9222,31470,9126,31498,9029,31525,8932,31553,8836,31580,8739,31606,8642,31633,8545,31659,8448,31684,8351,31710,8253,31735,8156,31760,8059,31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101,23169,23169,23240,23098,23311,23027,23382,22955,23452,22883,23522,22811,23592,22739,23661,22666,23731,22594,23800,22521,23869,22448,23938,22374,24006,22301,24075,22227,24143,22153,24211,22079,24278,22004,24346,21930,24413,21855,24480,21780,24546,21705,24613,21629,24679,21554,24745,21478,24811,21402,24877,21326,24942,21249,25007,21173,25072,21096,25136,21019,25201,20942,25265,20864,25329,20787,25392,20709,25456,20631,25519,20553,25582,20474,25645,20396,25707,20317,25769,20238,25831,20159,25893,20079,25954,20000,26016,19920,26077,19840,26137,19760,26198,19680,26258,19599,26318,19519,26378,19438,26437,19357,26497,19276,26556,19194,26615,19113,26673,19031,26731,18949,26789,18867,26847,18785,26905,18702,26962,18620,27019,18537,27076,18454,27132,18371,27188,18287,27244,18204,27300,18120,27355,18036,27411,17952,27466,17868,27520,17784,27575,17699,27629,17615,27683,17530,27736,17445,27790,17360,27843,17274,27896,17189,27948,17103,28001,17017,28053,16931,28105,16845,28156,16759,28208,16672,28259,16586,28309,16499,28360,16412,28410,16325,28460,16238,28510,16150,28559,16063,28608,15975,28657,15887,28706,15799,28754,15711,28802,15623,28850,15534,28897,15446,28945,15357,28992,15268,29038,15179,29085,15090,29131,15001,29177,14911,29222,14822,29268,14732,29313,14642,29358,14552,29402,14462,29446,14372,29490,14281,29534,14191,29577,14100,29621,14009,29663,13918,29706,13827,29748,13736,29790,13645,29832,13553,29873,13462,29915,13370,29955,13278,29996,13186,30036,13094,30076,13002,30116,12909,30156,12817,30195,12724,30234,12632,30272,12539,30311,12446,30349,12353,30386,12260,30424,12166,30461,12073,30498,11980,30535,11886,30571,11792,30607,11698,30643,11604,30678,11510,30713,11416,30748,11322,30783,11227,30817,11133,30851,11038,30885,10944,30918,10849,30951,10754,30984,10659,31017,10564,31049,10469,31081,10373,31113,10278,31144,10182,31175,10087,31206,9991,31236,9895,31267,9799,31297,9703,31326,9607,31356,9511,31385,9415,31413,9319,31442,9222,31470,9126,31498,9029,31525,8932,31553,8836,31580,8739,31606,8642,31633,8545,31659,8448,31684,8351,31710,8253,31735,8156,31760,8059,31785,7961,31809,7864,31833,7766,31856,7668,31880,7571,31903,7473,31926,7375,31948,7277,31970,7179,31992,7081,32014,6982,32035,6884,32056,6786,32077,6688,32097,6589,32117,6491,32137,6392,32156,6293,32176,6195,32194,6096,32213,5997,32231,5898,32249,5799,32267,5700,32284,5601,32301,5502,32318,5403,32334,5304,32350,5205,32366,5106,32382,5006,32397,4907,32412,4807,32426,4708,32441,4608,32455,4509,32468,4409,32482,4310,32495,4210,32508,4110,32520,4011,32532,3911,32544,3811,32556,3711,32567,3611,32578,3511,32588,3411,32599,3311,32609,3211,32618,3111,32628,3011,32637,2911,32646,2811,32654,2711,32662,2610,32670,2510,32678,2410,32685,2310,32692,2209,32699,2109,32705,2009,32711,1908,32717,1808,32722,1708,32727,1607,32732,1507,32736,1406,32740,1306,32744,1206,32748,1105,32751,1005,32754,904,32757,804,32759,703,32761,603,32763,502,32764,402,32765,301,32766,201,32766,100,32767,0,32766,-101,32766,-202,32765,-302,32764,-403,32763,-503,32761,-604,32759,-704,32757,-805,32754,-905,32751,-1006,32748,-1106,32744,-1207,32740,-1307,32736,-1407,32732,-1508,32727,-1608,32722,-1709,32717,-1809,32711,-1909,32705,-2010,32699,-2110,32692,-2210,32685,-2311,32678,-2411,32670,-2511,32662,-2611,32654,-2712,32646,-2812,32637,-2912,32628,-3012,32618,-3112,32609,-3212,32599,-3312,32588,-3412,32578,-3512,32567,-3612,32556,-3712,32544,-3812,32532,-3912,32520,-4012,32508,-4111,32495,-4211,32482,-4311,32468,-4410,32455,-4510,32441,-4609,32426,-4709,32412,-4808,32397,-4908,32382,-5007,32366,-5107,32350,-5206,32334,-5305,32318,-5404,32301,-5503,32284,-5602,32267,-5701,32249,-5800,32231,-5899,32213,-5998,32194,-6097,32176,-6196,32156,-6294,32137,-6393,32117,-6492,32097,-6590,32077,-6689,32056,-6787,32035,-6885,32014,-6983,31992,-7082,31970,-7180,31948,-7278,31926,-7376,31903,-7474,31880,-7572,31856,-7669,31833,-7767,31809,-7865,31785,-7962,31760,-8060,31735,-8157,31710,-8254,31684,-8352,31659,-8449,31633,-8546,31606,-8643,31580,-8740,31553,-8837,31525,-8933,31498,-9030,31470,-9127,31442,-9223,31413,-9320,31385,-9416,31356,-9512,31326,-9608,31297,-9704,31267,-9800,31236,-9896,31206,-9992,31175,-10088,31144,-10183,31113,-10279,31081,-10374,31049,-10470,31017,-10565,30984,-10660,30951,-10755,30918,-10850,30885,-10945,30851,-11039,30817,-11134,30783,-11228,30748,-11323,30713,-11417,30678,-11511,30643,-11605,30607,-11699,30571,-11793,30535,-11887,30498,-11981,30461,-12074,30424,-12167,30386,-12261,30349,-12354,30311,-12447,30272,-12540,30234,-12633,30195,-12725,30156,-12818,30116,-12910,30076,-13003,30036,-13095,29996,-13187,29955,-13279,29915,-13371,29873,-13463,29832,-13554,29790,-13646,29748,-13737,29706,-13828,29663,-13919,29621,-14010,29577,-14101,29534,-14192,29490,-14282,29446,-14373,29402,-14463,29358,-14553,29313,-14643,29268,-14733,29222,-14823,29177,-14912,29131,-15002,29085,-15091,29038,-15180,28992,-15269,28945,-15358,28897,-15447,28850,-15535,28802,-15624,28754,-15712,28706,-15800,28657,-15888,28608,-15976,28559,-16064,28510,-16151,28460,-16239,28410,-16326,28360,-16413,28309,-16500,28259,-16587,28208,-16673,28156,-16760,28105,-16846,28053,-16932,28001,-17018,27948,-17104,27896,-17190,27843,-17275,27790,-17361,27736,-17446,27683,-17531,27629,-17616,27575,-17700,27520,-17785,27466,-17869,27411,-17953,27355,-18037,27300,-18121,27244,-18205,27188,-18288,27132,-18372,27076,-18455,27019,-18538,26962,-18621,26905,-18703,26847,-18786,26789,-18868,26731,-18950,26673,-19032,26615,-19114,26556,-19195,26497,-19277,26437,-19358,26378,-19439,26318,-19520,26258,-19600,26198,-19681,26137,-19761,26077,-19841,26016,-19921,25954,-20001,25893,-20080,25831,-20160,25769,-20239,25707,-20318,25645,-20397,25582,-20475,25519,-20554,25456,-20632,25392,-20710,25329,-20788,25265,-20865,25201,-20943,25136,-21020,25072,-21097,25007,-21174,24942,-21250,24877,-21327,24811,-21403,24745,-21479,24679,-21555,24613,-21630,24546,-21706,24480,-21781,24413,-21856,24346,-21931,24278,-22005,24211,-22080,24143,-22154,24075,-22228,24006,-22302,23938,-22375,23869,-22449,23800,-22522,23731,-22595,23661,-22667,23592,-22740,23522,-22812,23452,-22884,23382,-22956,23311,-23028,23240,-23099,23169,-23170,23098,-23241,23027,-23312,22955,-23383,22883,-23453,22811,-23523,22739,-23593,22666,-23662,22594,-23732,22521,-23801,22448,-23870,22374,-23939,22301,-24007,22227,-24076,22153,-24144,22079,-24212,22004,-24279,21930,-24347,21855,-24414,21780,-24481,21705,-24547,21629,-24614,21554,-24680,21478,-24746,21402,-24812,21326,-24878,21249,-24943,21173,-25008,21096,-25073,21019,-25137,20942,-25202,20864,-25266,20787,-25330,20709,-25393,20631,-25457,20553,-25520,20474,-25583,20396,-25646,20317,-25708,20238,-25770,20159,-25832,20079,-25894,20000,-25955,19920,-26017,19840,-26078,19760,-26138,19680,-26199,19599,-26259,19519,-26319,19438,-26379,19357,-26438,19276,-26498,19194,-26557,19113,-26616,19031,-26674,18949,-26732,18867,-26790,18785,-26848,18702,-26906,18620,-26963,18537,-27020,18454,-27077,18371,-27133,18287,-27189,18204,-27245,18120,-27301,18036,-27356,17952,-27412,17868,-27467,17784,-27521,17699,-27576,17615,-27630,17530,-27684,17445,-27737,17360,-27791,17274,-27844,17189,-27897,17103,-27949,17017,-28002,16931,-28054,16845,-28106,16759,-28157,16672,-28209,16586,-28260,16499,-28310,16412,-28361,16325,-28411,16238,-28461,16150,-28511,16063,-28560,15975,-28609,15887,-28658,15799,-28707,15711,-28755,15623,-28803,15534,-28851,15446,-28898,15357,-28946,15268,-28993,15179,-29039,15090,-29086,15001,-29132,14911,-29178,14822,-29223,14732,-29269,14642,-29314,14552,-29359,14462,-29403,14372,-29447,14281,-29491,14191,-29535,14100,-29578,14009,-29622,13918,-29664,13827,-29707,13736,-29749,13645,-29791,13553,-29833,13462,-29874,13370,-29916,13278,-29956,13186,-29997,13094,-30037,13002,-30077,12909,-30117,12817,-30157,12724,-30196,12632,-30235,12539,-30273,12446,-30312,12353,-30350,12260,-30387,12166,-30425,12073,-30462,11980,-30499,11886,-30536,11792,-30572,11698,-30608,11604,-30644,11510,-30679,11416,-30714,11322,-30749,11227,-30784,11133,-30818,11038,-30852,10944,-30886,10849,-30919,10754,-30952,10659,-30985,10564,-31018,10469,-31050,10373,-31082,10278,-31114,10182,-31145,10087,-31176,9991,-31207,9895,-31237,9799,-31268,9703,-31298,9607,-31327,9511,-31357,9415,-31386,9319,-31414,9222,-31443,9126,-31471,9029,-31499,8932,-31526,8836,-31554,8739,-31581,8642,-31607,8545,-31634,8448,-31660,8351,-31685,8253,-31711,8156,-31736,8059,-31761,7961,-31786,7864,-31810,7766,-31834,7668,-31857,7571,-31881,7473,-31904,7375,-31927,7277,-31949,7179,-31971,7081,-31993,6982,-32015,6884,-32036,6786,-32057,6688,-32078,6589,-32098,6491,-32118,6392,-32138,6293,-32157,6195,-32177,6096,-32195,5997,-32214,5898,-32232,5799,-32250,5700,-32268,5601,-32285,5502,-32302,5403,-32319,5304,-32335,5205,-32351,5106,-32367,5006,-32383,4907,-32398,4807,-32413,4708,-32427,4608,-32442,4509,-32456,4409,-32469,4310,-32483,4210,-32496,4110,-32509,4011,-32521,3911,-32533,3811,-32545,3711,-32557,3611,-32568,3511,-32579,3411,-32589,3311,-32600,3211,-32610,3111,-32619,3011,-32629,2911,-32638,2811,-32647,2711,-32655,2610,-32663,2510,-32671,2410,-32679,2310,-32686,2209,-32693,2109,-32700,2009,-32706,1908,-32712,1808,-32718,1708,-32723,1607,-32728,1507,-32733,1406,-32737,1306,-32741,1206,-32745,1105,-32749,1005,-32752,904,-32755,804,-32758,703,-32760,603,-32762,502,-32764,402,-32765,301,-32766,201,-32767,100,-32767,0,-32767,-101,-32767,-202,-32767,-302,-32766,-403,-32765,-503,-32764,-604,-32762,-704,-32760,-805,-32758,-905,-32755,-1006,-32752,-1106,-32749,-1207,-32745,-1307,-32741,-1407,-32737,-1508,-32733,-1608,-32728,-1709,-32723,-1809,-32718,-1909,-32712,-2010,-32706,-2110,-32700,-2210,-32693,-2311,-32686,-2411,-32679,-2511,-32671,-2611,-32663,-2712,-32655,-2812,-32647,-2912,-32638,-3012,-32629,-3112,-32619,-3212,-32610,-3312,-32600,-3412,-32589,-3512,-32579,-3612,-32568,-3712,-32557,-3812,-32545,-3912,-32533,-4012,-32521,-4111,-32509,-4211,-32496,-4311,-32483,-4410,-32469,-4510,-32456,-4609,-32442,-4709,-32427,-4808,-32413,-4908,-32398,-5007,-32383,-5107,-32367,-5206,-32351,-5305,-32335,-5404,-32319,-5503,-32302,-5602,-32285,-5701,-32268,-5800,-32250,-5899,-32232,-5998,-32214,-6097,-32195,-6196,-32177,-6294,-32157,-6393,-32138,-6492,-32118,-6590,-32098,-6689,-32078,-6787,-32057,-6885,-32036,-6983,-32015,-7082,-31993,-7180,-31971,-7278,-31949,-7376,-31927,-7474,-31904,-7572,-31881,-7669,-31857,-7767,-31834,-7865,-31810,-7962,-31786,-8060,-31761,-8157,-31736,-8254,-31711,-8352,-31685,-8449,-31660,-8546,-31634,-8643,-31607,-8740,-31581,-8837,-31554,-8933,-31526,-9030,-31499,-9127,-31471,-9223,-31443,-9320,-31414,-9416,-31386,-9512,-31357,-9608,-31327,-9704,-31298,-9800,-31268,-9896,-31237,-9992,-31207,-10088,-31176,-10183,-31145,-10279,-31114,-10374,-31082,-10470,-31050,-10565,-31018,-10660,-30985,-10755,-30952,-10850,-30919,-10945,-30886,-11039,-30852,-11134,-30818,-11228,-30784,-11323,-30749,-11417,-30714,-11511,-30679,-11605,-30644,-11699,-30608,-11793,-30572,-11887,-30536,-11981,-30499,-12074,-30462,-12167,-30425,-12261,-30387,-12354,-30350,-12447,-30312,-12540,-30273,-12633,-30235,-12725,-30196,-12818,-30157,-12910,-30117,-13003,-30077,-13095,-30037,-13187,-29997,-13279,-29956,-13371,-29916,-13463,-29874,-13554,-29833,-13646,-29791,-13737,-29749,-13828,-29707,-13919,-29664,-14010,-29622,-14101,-29578,-14192,-29535,-14282,-29491,-14373,-29447,-14463,-29403,-14553,-29359,-14643,-29314,-14733,-29269,-14823,-29223,-14912,-29178,-15002,-29132,-15091,-29086,-15180,-29039,-15269,-28993,-15358,-28946,-15447,-28898,-15535,-28851,-15624,-28803,-15712,-28755,-15800,-28707,-15888,-28658,-15976,-28609,-16064,-28560,-16151,-28511,-16239,-28461,-16326,-28411,-16413,-28361,-16500,-28310,-16587,-28260,-16673,-28209,-16760,-28157,-16846,-28106,-16932,-28054,-17018,-28002,-17104,-27949,-17190,-27897,-17275,-27844,-17361,-27791,-17446,-27737,-17531,-27684,-17616,-27630,-17700,-27576,-17785,-27521,-17869,-27467,-17953,-27412,-18037,-27356,-18121,-27301,-18205,-27245,-18288,-27189,-18372,-27133,-18455,-27077,-18538,-27020,-18621,-26963,-18703,-26906,-18786,-26848,-18868,-26790,-18950,-26732,-19032,-26674,-19114,-26616,-19195,-26557,-19277,-26498,-19358,-26438,-19439,-26379,-19520,-26319,-19600,-26259,-19681,-26199,-19761,-26138,-19841,-26078,-19921,-26017,-20001,-25955,-20080,-25894,-20160,-25832,-20239,-25770,-20318,-25708,-20397,-25646,-20475,-25583,-20554,-25520,-20632,-25457,-20710,-25393,-20788,-25330,-20865,-25266,-20943,-25202,-21020,-25137,-21097,-25073,-21174,-25008,-21250,-24943,-21327,-24878,-21403,-24812,-21479,-24746,-21555,-24680,-21630,-24614,-21706,-24547,-21781,-24481,-21856,-24414,-21931,-24347,-22005,-24279,-22080,-24212,-22154,-24144,-22228,-24076,-22302,-24007,-22375,-23939,-22449,-23870,-22522,-23801,-22595,-23732,-22667,-23662,-22740,-23593,-22812,-23523,-22884,-23453,-22956,-23383,-23028,-23312,-23099,-23241,-23170,-23170,-23241,-23099,-23312,-23028,-23383,-22956,-23453,-22884,-23523,-22812,-23593,-22740,-23662,-22667,-23732,-22595,-23801,-22522,-23870,-22449,-23939,-22375,-24007,-22302,-24076,-22228,-24144,-22154,-24212,-22080,-24279,-22005,-24347,-21931,-24414,-21856,-24481,-21781,-24547,-21706,-24614,-21630,-24680,-21555,-24746,-21479,-24812,-21403,-24878,-21327,-24943,-21250,-25008,-21174,-25073,-21097,-25137,-21020,-25202,-20943,-25266,-20865,-25330,-20788,-25393,-20710,-25457,-20632,-25520,-20554,-25583,-20475,-25646,-20397,-25708,-20318,-25770,-20239,-25832,-20160,-25894,-20080,-25955,-20001,-26017,-19921,-26078,-19841,-26138,-19761,-26199,-19681,-26259,-19600,-26319,-19520,-26379,-19439,-26438,-19358,-26498,-19277,-26557,-19195,-26616,-19114,-26674,-19032,-26732,-18950,-26790,-18868,-26848,-18786,-26906,-18703,-26963,-18621,-27020,-18538,-27077,-18455,-27133,-18372,-27189,-18288,-27245,-18205,-27301,-18121,-27356,-18037,-27412,-17953,-27467,-17869,-27521,-17785,-27576,-17700,-27630,-17616,-27684,-17531,-27737,-17446,-27791,-17361,-27844,-17275,-27897,-17190,-27949,-17104,-28002,-17018,-28054,-16932,-28106,-16846,-28157,-16760,-28209,-16673,-28260,-16587,-28310,-16500,-28361,-16413,-28411,-16326,-28461,-16239,-28511,-16151,-28560,-16064,-28609,-15976,-28658,-15888,-28707,-15800,-28755,-15712,-28803,-15624,-28851,-15535,-28898,-15447,-28946,-15358,-28993,-15269,-29039,-15180,-29086,-15091,-29132,-15002,-29178,-14912,-29223,-14823,-29269,-14733,-29314,-14643,-29359,-14553,-29403,-14463,-29447,-14373,-29491,-14282,-29535,-14192,-29578,-14101,-29622,-14010,-29664,-13919,-29707,-13828,-29749,-13737,-29791,-13646,-29833,-13554,-29874,-13463,-29916,-13371,-29956,-13279,-29997,-13187,-30037,-13095,-30077,-13003,-30117,-12910,-30157,-12818,-30196,-12725,-30235,-12633,-30273,-12540,-30312,-12447,-30350,-12354,-30387,-12261,-30425,-12167,-30462,-12074,-30499,-11981,-30536,-11887,-30572,-11793,-30608,-11699,-30644,-11605,-30679,-11511,-30714,-11417,-30749,-11323,-30784,-11228,-30818,-11134,-30852,-11039,-30886,-10945,-30919,-10850,-30952,-10755,-30985,-10660,-31018,-10565,-31050,-10470,-31082,-10374,-31114,-10279,-31145,-10183,-31176,-10088,-31207,-9992,-31237,-9896,-31268,-9800,-31298,-9704,-31327,-9608,-31357,-9512,-31386,-9416,-31414,-9320,-31443,-9223,-31471,-9127,-31499,-9030,-31526,-8933,-31554,-8837,-31581,-8740,-31607,-8643,-31634,-8546,-31660,-8449,-31685,-8352,-31711,-8254,-31736,-8157,-31761,-8060,-31786,-7962,-31810,-7865,-31834,-7767,-31857,-7669,-31881,-7572,-31904,-7474,-31927,-7376,-31949,-7278,-31971,-7180,-31993,-7082,-32015,-6983,-32036,-6885,-32057,-6787,-32078,-6689,-32098,-6590,-32118,-6492,-32138,-6393,-32157,-6294,-32177,-6196,-32195,-6097,-32214,-5998,-32232,-5899,-32250,-5800,-32268,-5701,-32285,-5602,-32302,-5503,-32319,-5404,-32335,-5305,-32351,-5206,-32367,-5107,-32383,-5007,-32398,-4908,-32413,-4808,-32427,-4709,-32442,-4609,-32456,-4510,-32469,-4410,-32483,-4311,-32496,-4211,-32509,-4111,-32521,-4012,-32533,-3912,-32545,-3812,-32557,-3712,-32568,-3612,-32579,-3512,-32589,-3412,-32600,-3312,-32610,-3212,-32619,-3112,-32629,-3012,-32638,-2912,-32647,-2812,-32655,-2712,-32663,-2611,-32671,-2511,-32679,-2411,-32686,-2311,-32693,-2210,-32700,-2110,-32706,-2010,-32712,-1909,-32718,-1809,-32723,-1709,-32728,-1608,-32733,-1508,-32737,-1407,-32741,-1307,-32745,-1207,-32749,-1106,-32752,-1006,-32755,-905,-32758,-805,-32760,-704,-32762,-604,-32764,-503,-32765,-403,-32766,-302,-32767,-202,-32767,-101}; - -int16_t s75n_kHz_7_5[23040]__attribute__((aligned(16))) = {31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68}; - -int16_t s75e_kHz_7_5[23040]__attribute__((aligned(16))) = {23169,23169,23217,23122,23264,23074,23311,23027,23358,22979,23405,22931,23452,22883,23499,22835,23545,22787,23592,22739,23638,22691,23685,22642,23731,22594,23777,22545,23823,22496,23869,22448,23915,22399,23961,22350,24006,22301,24052,22252,24097,22202,24143,22153,24188,22104,24233,22054,24278,22004,24323,21955,24368,21905,24413,21855,24457,21805,24502,21755,24546,21705,24591,21655,24635,21604,24679,21554,24723,21503,24767,21453,24811,21402,24855,21351,24898,21300,24942,21249,24985,21198,25029,21147,25072,21096,25115,21045,25158,20993,25201,20942,25243,20890,25286,20838,25329,20787,25371,20735,25414,20683,25456,20631,25498,20579,25540,20527,25582,20474,25624,20422,25665,20369,25707,20317,25749,20264,25790,20212,25831,20159,25872,20106,25913,20053,25954,20000,25995,19947,26036,19894,26077,19840,26117,19787,26158,19733,26198,19680,26238,19626,26278,19573,26318,19519,26358,19465,26398,19411,26437,19357,26477,19303,26516,19249,26556,19194,26595,19140,26634,19086,26673,19031,26712,18976,26751,18922,26789,18867,26828,18812,26866,18757,26905,18702,26943,18647,26981,18592,27019,18537,27057,18482,27094,18426,27132,18371,27170,18315,27207,18260,27244,18204,27281,18148,27319,18092,27355,18036,27392,17980,27429,17924,27466,17868,27502,17812,27538,17756,27575,17699,27611,17643,27647,17586,27683,17530,27719,17473,27754,17416,27790,17360,27825,17303,27861,17246,27896,17189,27931,17132,27966,17074,28001,17017,28036,16960,28070,16903,28105,16845,28139,16788,28173,16730,28208,16672,28242,16615,28275,16557,28309,16499,28343,16441,28377,16383,28410,16325,28443,16267,28477,16209,28510,16150,28543,16092,28575,16034,28608,15975,28641,15917,28673,15858,28706,15799,28738,15740,28770,15682,28802,15623,28834,15564,28866,15505,28897,15446,28929,15387,28960,15327,28992,15268,29023,15209,29054,15149,29085,15090,29116,15030,29146,14971,29177,14911,29207,14852,29238,14792,29268,14732,29298,14672,29328,14612,29358,14552,29387,14492,29417,14432,29446,14372,29476,14311,29505,14251,29534,14191,29563,14130,29592,14070,29621,14009,29649,13949,29678,13888,29706,13827,29734,13766,29762,13706,29790,13645,29818,13584,29846,13523,29873,13462,29901,13400,29928,13339,29955,13278,29983,13217,30009,13155,30036,13094,30063,13033,30090,12971,30116,12909,30142,12848,30169,12786,30195,12724,30221,12663,30247,12601,30272,12539,30298,12477,30323,12415,30349,12353,30374,12291,30399,12229,30424,12166,30449,12104,30473,12042,30498,11980,30522,11917,30547,11855,30571,11792,30595,11730,30619,11667,30643,11604,30666,11542,30690,11479,30713,11416,30737,11353,30760,11290,30783,11227,30806,11164,30828,11101,30851,11038,30874,10975,30896,10912,30918,10849,30940,10786,30962,10722,30984,10659,31006,10596,31028,10532,31049,10469,31070,10405,31092,10342,31113,10278,31134,10214,31154,10151,31175,10087,31196,10023,31216,9959,31236,9895,31257,9831,31277,9767,31297,9703,31316,9639,31336,9575,31356,9511,31375,9447,31394,9383,31413,9319,31432,9254,31451,9190,31470,9126,31489,9061,31507,8997,31525,8932,31544,8868,31562,8803,31580,8739,31597,8674,31615,8610,31633,8545,31650,8480,31667,8415,31684,8351,31701,8286,31718,8221,31735,8156,31752,8091,31768,8026,31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,23169,23169,23217,23122,23264,23074,23311,23027,23358,22979,23405,22931,23452,22883,23499,22835,23545,22787,23592,22739,23638,22691,23685,22642,23731,22594,23777,22545,23823,22496,23869,22448,23915,22399,23961,22350,24006,22301,24052,22252,24097,22202,24143,22153,24188,22104,24233,22054,24278,22004,24323,21955,24368,21905,24413,21855,24457,21805,24502,21755,24546,21705,24591,21655,24635,21604,24679,21554,24723,21503,24767,21453,24811,21402,24855,21351,24898,21300,24942,21249,24985,21198,25029,21147,25072,21096,25115,21045,25158,20993,25201,20942,25243,20890,25286,20838,25329,20787,25371,20735,25414,20683,25456,20631,25498,20579,25540,20527,25582,20474,25624,20422,25665,20369,25707,20317,25749,20264,25790,20212,25831,20159,25872,20106,25913,20053,25954,20000,25995,19947,26036,19894,26077,19840,26117,19787,26158,19733,26198,19680,26238,19626,26278,19573,26318,19519,26358,19465,26398,19411,26437,19357,26477,19303,26516,19249,26556,19194,26595,19140,26634,19086,26673,19031,26712,18976,26751,18922,26789,18867,26828,18812,26866,18757,26905,18702,26943,18647,26981,18592,27019,18537,27057,18482,27094,18426,27132,18371,27170,18315,27207,18260,27244,18204,27281,18148,27319,18092,27355,18036,27392,17980,27429,17924,27466,17868,27502,17812,27538,17756,27575,17699,27611,17643,27647,17586,27683,17530,27719,17473,27754,17416,27790,17360,27825,17303,27861,17246,27896,17189,27931,17132,27966,17074,28001,17017,28036,16960,28070,16903,28105,16845,28139,16788,28173,16730,28208,16672,28242,16615,28275,16557,28309,16499,28343,16441,28377,16383,28410,16325,28443,16267,28477,16209,28510,16150,28543,16092,28575,16034,28608,15975,28641,15917,28673,15858,28706,15799,28738,15740,28770,15682,28802,15623,28834,15564,28866,15505,28897,15446,28929,15387,28960,15327,28992,15268,29023,15209,29054,15149,29085,15090,29116,15030,29146,14971,29177,14911,29207,14852,29238,14792,29268,14732,29298,14672,29328,14612,29358,14552,29387,14492,29417,14432,29446,14372,29476,14311,29505,14251,29534,14191,29563,14130,29592,14070,29621,14009,29649,13949,29678,13888,29706,13827,29734,13766,29762,13706,29790,13645,29818,13584,29846,13523,29873,13462,29901,13400,29928,13339,29955,13278,29983,13217,30009,13155,30036,13094,30063,13033,30090,12971,30116,12909,30142,12848,30169,12786,30195,12724,30221,12663,30247,12601,30272,12539,30298,12477,30323,12415,30349,12353,30374,12291,30399,12229,30424,12166,30449,12104,30473,12042,30498,11980,30522,11917,30547,11855,30571,11792,30595,11730,30619,11667,30643,11604,30666,11542,30690,11479,30713,11416,30737,11353,30760,11290,30783,11227,30806,11164,30828,11101,30851,11038,30874,10975,30896,10912,30918,10849,30940,10786,30962,10722,30984,10659,31006,10596,31028,10532,31049,10469,31070,10405,31092,10342,31113,10278,31134,10214,31154,10151,31175,10087,31196,10023,31216,9959,31236,9895,31257,9831,31277,9767,31297,9703,31316,9639,31336,9575,31356,9511,31375,9447,31394,9383,31413,9319,31432,9254,31451,9190,31470,9126,31489,9061,31507,8997,31525,8932,31544,8868,31562,8803,31580,8739,31597,8674,31615,8610,31633,8545,31650,8480,31667,8415,31684,8351,31701,8286,31718,8221,31735,8156,31752,8091,31768,8026,31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,23169,23169,23217,23122,23264,23074,23311,23027,23358,22979,23405,22931,23452,22883,23499,22835,23545,22787,23592,22739,23638,22691,23685,22642,23731,22594,23777,22545,23823,22496,23869,22448,23915,22399,23961,22350,24006,22301,24052,22252,24097,22202,24143,22153,24188,22104,24233,22054,24278,22004,24323,21955,24368,21905,24413,21855,24457,21805,24502,21755,24546,21705,24591,21655,24635,21604,24679,21554,24723,21503,24767,21453,24811,21402,24855,21351,24898,21300,24942,21249,24985,21198,25029,21147,25072,21096,25115,21045,25158,20993,25201,20942,25243,20890,25286,20838,25329,20787,25371,20735,25414,20683,25456,20631,25498,20579,25540,20527,25582,20474,25624,20422,25665,20369,25707,20317,25749,20264,25790,20212,25831,20159,25872,20106,25913,20053,25954,20000,25995,19947,26036,19894,26077,19840,26117,19787,26158,19733,26198,19680,26238,19626,26278,19573,26318,19519,26358,19465,26398,19411,26437,19357,26477,19303,26516,19249,26556,19194,26595,19140,26634,19086,26673,19031,26712,18976,26751,18922,26789,18867,26828,18812,26866,18757,26905,18702,26943,18647,26981,18592,27019,18537,27057,18482,27094,18426,27132,18371,27170,18315,27207,18260,27244,18204,27281,18148,27319,18092,27355,18036,27392,17980,27429,17924,27466,17868,27502,17812,27538,17756,27575,17699,27611,17643,27647,17586,27683,17530,27719,17473,27754,17416,27790,17360,27825,17303,27861,17246,27896,17189,27931,17132,27966,17074,28001,17017,28036,16960,28070,16903,28105,16845,28139,16788,28173,16730,28208,16672,28242,16615,28275,16557,28309,16499,28343,16441,28377,16383,28410,16325,28443,16267,28477,16209,28510,16150,28543,16092,28575,16034,28608,15975,28641,15917,28673,15858,28706,15799,28738,15740,28770,15682,28802,15623,28834,15564,28866,15505,28897,15446,28929,15387,28960,15327,28992,15268,29023,15209,29054,15149,29085,15090,29116,15030,29146,14971,29177,14911,29207,14852,29238,14792,29268,14732,29298,14672,29328,14612,29358,14552,29387,14492,29417,14432,29446,14372,29476,14311,29505,14251,29534,14191,29563,14130,29592,14070,29621,14009,29649,13949,29678,13888,29706,13827,29734,13766,29762,13706,29790,13645,29818,13584,29846,13523,29873,13462,29901,13400,29928,13339,29955,13278,29983,13217,30009,13155,30036,13094,30063,13033,30090,12971,30116,12909,30142,12848,30169,12786,30195,12724,30221,12663,30247,12601,30272,12539,30298,12477,30323,12415,30349,12353,30374,12291,30399,12229,30424,12166,30449,12104,30473,12042,30498,11980,30522,11917,30547,11855,30571,11792,30595,11730,30619,11667,30643,11604,30666,11542,30690,11479,30713,11416,30737,11353,30760,11290,30783,11227,30806,11164,30828,11101,30851,11038,30874,10975,30896,10912,30918,10849,30940,10786,30962,10722,30984,10659,31006,10596,31028,10532,31049,10469,31070,10405,31092,10342,31113,10278,31134,10214,31154,10151,31175,10087,31196,10023,31216,9959,31236,9895,31257,9831,31277,9767,31297,9703,31316,9639,31336,9575,31356,9511,31375,9447,31394,9383,31413,9319,31432,9254,31451,9190,31470,9126,31489,9061,31507,8997,31525,8932,31544,8868,31562,8803,31580,8739,31597,8674,31615,8610,31633,8545,31650,8480,31667,8415,31684,8351,31701,8286,31718,8221,31735,8156,31752,8091,31768,8026,31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,23169,23169,23217,23122,23264,23074,23311,23027,23358,22979,23405,22931,23452,22883,23499,22835,23545,22787,23592,22739,23638,22691,23685,22642,23731,22594,23777,22545,23823,22496,23869,22448,23915,22399,23961,22350,24006,22301,24052,22252,24097,22202,24143,22153,24188,22104,24233,22054,24278,22004,24323,21955,24368,21905,24413,21855,24457,21805,24502,21755,24546,21705,24591,21655,24635,21604,24679,21554,24723,21503,24767,21453,24811,21402,24855,21351,24898,21300,24942,21249,24985,21198,25029,21147,25072,21096,25115,21045,25158,20993,25201,20942,25243,20890,25286,20838,25329,20787,25371,20735,25414,20683,25456,20631,25498,20579,25540,20527,25582,20474,25624,20422,25665,20369,25707,20317,25749,20264,25790,20212,25831,20159,25872,20106,25913,20053,25954,20000,25995,19947,26036,19894,26077,19840,26117,19787,26158,19733,26198,19680,26238,19626,26278,19573,26318,19519,26358,19465,26398,19411,26437,19357,26477,19303,26516,19249,26556,19194,26595,19140,26634,19086,26673,19031,26712,18976,26751,18922,26789,18867,26828,18812,26866,18757,26905,18702,26943,18647,26981,18592,27019,18537,27057,18482,27094,18426,27132,18371,27170,18315,27207,18260,27244,18204,27281,18148,27319,18092,27355,18036,27392,17980,27429,17924,27466,17868,27502,17812,27538,17756,27575,17699,27611,17643,27647,17586,27683,17530,27719,17473,27754,17416,27790,17360,27825,17303,27861,17246,27896,17189,27931,17132,27966,17074,28001,17017,28036,16960,28070,16903,28105,16845,28139,16788,28173,16730,28208,16672,28242,16615,28275,16557,28309,16499,28343,16441,28377,16383,28410,16325,28443,16267,28477,16209,28510,16150,28543,16092,28575,16034,28608,15975,28641,15917,28673,15858,28706,15799,28738,15740,28770,15682,28802,15623,28834,15564,28866,15505,28897,15446,28929,15387,28960,15327,28992,15268,29023,15209,29054,15149,29085,15090,29116,15030,29146,14971,29177,14911,29207,14852,29238,14792,29268,14732,29298,14672,29328,14612,29358,14552,29387,14492,29417,14432,29446,14372,29476,14311,29505,14251,29534,14191,29563,14130,29592,14070,29621,14009,29649,13949,29678,13888,29706,13827,29734,13766,29762,13706,29790,13645,29818,13584,29846,13523,29873,13462,29901,13400,29928,13339,29955,13278,29983,13217,30009,13155,30036,13094,30063,13033,30090,12971,30116,12909,30142,12848,30169,12786,30195,12724,30221,12663,30247,12601,30272,12539,30298,12477,30323,12415,30349,12353,30374,12291,30399,12229,30424,12166,30449,12104,30473,12042,30498,11980,30522,11917,30547,11855,30571,11792,30595,11730,30619,11667,30643,11604,30666,11542,30690,11479,30713,11416,30737,11353,30760,11290,30783,11227,30806,11164,30828,11101,30851,11038,30874,10975,30896,10912,30918,10849,30940,10786,30962,10722,30984,10659,31006,10596,31028,10532,31049,10469,31070,10405,31092,10342,31113,10278,31134,10214,31154,10151,31175,10087,31196,10023,31216,9959,31236,9895,31257,9831,31277,9767,31297,9703,31316,9639,31336,9575,31356,9511,31375,9447,31394,9383,31413,9319,31432,9254,31451,9190,31470,9126,31489,9061,31507,8997,31525,8932,31544,8868,31562,8803,31580,8739,31597,8674,31615,8610,31633,8545,31650,8480,31667,8415,31684,8351,31701,8286,31718,8221,31735,8156,31752,8091,31768,8026,31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,23169,23169,23217,23122,23264,23074,23311,23027,23358,22979,23405,22931,23452,22883,23499,22835,23545,22787,23592,22739,23638,22691,23685,22642,23731,22594,23777,22545,23823,22496,23869,22448,23915,22399,23961,22350,24006,22301,24052,22252,24097,22202,24143,22153,24188,22104,24233,22054,24278,22004,24323,21955,24368,21905,24413,21855,24457,21805,24502,21755,24546,21705,24591,21655,24635,21604,24679,21554,24723,21503,24767,21453,24811,21402,24855,21351,24898,21300,24942,21249,24985,21198,25029,21147,25072,21096,25115,21045,25158,20993,25201,20942,25243,20890,25286,20838,25329,20787,25371,20735,25414,20683,25456,20631,25498,20579,25540,20527,25582,20474,25624,20422,25665,20369,25707,20317,25749,20264,25790,20212,25831,20159,25872,20106,25913,20053,25954,20000,25995,19947,26036,19894,26077,19840,26117,19787,26158,19733,26198,19680,26238,19626,26278,19573,26318,19519,26358,19465,26398,19411,26437,19357,26477,19303,26516,19249,26556,19194,26595,19140,26634,19086,26673,19031,26712,18976,26751,18922,26789,18867,26828,18812,26866,18757,26905,18702,26943,18647,26981,18592,27019,18537,27057,18482,27094,18426,27132,18371,27170,18315,27207,18260,27244,18204,27281,18148,27319,18092,27355,18036,27392,17980,27429,17924,27466,17868,27502,17812,27538,17756,27575,17699,27611,17643,27647,17586,27683,17530,27719,17473,27754,17416,27790,17360,27825,17303,27861,17246,27896,17189,27931,17132,27966,17074,28001,17017,28036,16960,28070,16903,28105,16845,28139,16788,28173,16730,28208,16672,28242,16615,28275,16557,28309,16499,28343,16441,28377,16383,28410,16325,28443,16267,28477,16209,28510,16150,28543,16092,28575,16034,28608,15975,28641,15917,28673,15858,28706,15799,28738,15740,28770,15682,28802,15623,28834,15564,28866,15505,28897,15446,28929,15387,28960,15327,28992,15268,29023,15209,29054,15149,29085,15090,29116,15030,29146,14971,29177,14911,29207,14852,29238,14792,29268,14732,29298,14672,29328,14612,29358,14552,29387,14492,29417,14432,29446,14372,29476,14311,29505,14251,29534,14191,29563,14130,29592,14070,29621,14009,29649,13949,29678,13888,29706,13827,29734,13766,29762,13706,29790,13645,29818,13584,29846,13523,29873,13462,29901,13400,29928,13339,29955,13278,29983,13217,30009,13155,30036,13094,30063,13033,30090,12971,30116,12909,30142,12848,30169,12786,30195,12724,30221,12663,30247,12601,30272,12539,30298,12477,30323,12415,30349,12353,30374,12291,30399,12229,30424,12166,30449,12104,30473,12042,30498,11980,30522,11917,30547,11855,30571,11792,30595,11730,30619,11667,30643,11604,30666,11542,30690,11479,30713,11416,30737,11353,30760,11290,30783,11227,30806,11164,30828,11101,30851,11038,30874,10975,30896,10912,30918,10849,30940,10786,30962,10722,30984,10659,31006,10596,31028,10532,31049,10469,31070,10405,31092,10342,31113,10278,31134,10214,31154,10151,31175,10087,31196,10023,31216,9959,31236,9895,31257,9831,31277,9767,31297,9703,31316,9639,31336,9575,31356,9511,31375,9447,31394,9383,31413,9319,31432,9254,31451,9190,31470,9126,31489,9061,31507,8997,31525,8932,31544,8868,31562,8803,31580,8739,31597,8674,31615,8610,31633,8545,31650,8480,31667,8415,31684,8351,31701,8286,31718,8221,31735,8156,31752,8091,31768,8026,31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68,23169,23169,23217,23122,23264,23074,23311,23027,23358,22979,23405,22931,23452,22883,23499,22835,23545,22787,23592,22739,23638,22691,23685,22642,23731,22594,23777,22545,23823,22496,23869,22448,23915,22399,23961,22350,24006,22301,24052,22252,24097,22202,24143,22153,24188,22104,24233,22054,24278,22004,24323,21955,24368,21905,24413,21855,24457,21805,24502,21755,24546,21705,24591,21655,24635,21604,24679,21554,24723,21503,24767,21453,24811,21402,24855,21351,24898,21300,24942,21249,24985,21198,25029,21147,25072,21096,25115,21045,25158,20993,25201,20942,25243,20890,25286,20838,25329,20787,25371,20735,25414,20683,25456,20631,25498,20579,25540,20527,25582,20474,25624,20422,25665,20369,25707,20317,25749,20264,25790,20212,25831,20159,25872,20106,25913,20053,25954,20000,25995,19947,26036,19894,26077,19840,26117,19787,26158,19733,26198,19680,26238,19626,26278,19573,26318,19519,26358,19465,26398,19411,26437,19357,26477,19303,26516,19249,26556,19194,26595,19140,26634,19086,26673,19031,26712,18976,26751,18922,26789,18867,26828,18812,26866,18757,26905,18702,26943,18647,26981,18592,27019,18537,27057,18482,27094,18426,27132,18371,27170,18315,27207,18260,27244,18204,27281,18148,27319,18092,27355,18036,27392,17980,27429,17924,27466,17868,27502,17812,27538,17756,27575,17699,27611,17643,27647,17586,27683,17530,27719,17473,27754,17416,27790,17360,27825,17303,27861,17246,27896,17189,27931,17132,27966,17074,28001,17017,28036,16960,28070,16903,28105,16845,28139,16788,28173,16730,28208,16672,28242,16615,28275,16557,28309,16499,28343,16441,28377,16383,28410,16325,28443,16267,28477,16209,28510,16150,28543,16092,28575,16034,28608,15975,28641,15917,28673,15858,28706,15799,28738,15740,28770,15682,28802,15623,28834,15564,28866,15505,28897,15446,28929,15387,28960,15327,28992,15268,29023,15209,29054,15149,29085,15090,29116,15030,29146,14971,29177,14911,29207,14852,29238,14792,29268,14732,29298,14672,29328,14612,29358,14552,29387,14492,29417,14432,29446,14372,29476,14311,29505,14251,29534,14191,29563,14130,29592,14070,29621,14009,29649,13949,29678,13888,29706,13827,29734,13766,29762,13706,29790,13645,29818,13584,29846,13523,29873,13462,29901,13400,29928,13339,29955,13278,29983,13217,30009,13155,30036,13094,30063,13033,30090,12971,30116,12909,30142,12848,30169,12786,30195,12724,30221,12663,30247,12601,30272,12539,30298,12477,30323,12415,30349,12353,30374,12291,30399,12229,30424,12166,30449,12104,30473,12042,30498,11980,30522,11917,30547,11855,30571,11792,30595,11730,30619,11667,30643,11604,30666,11542,30690,11479,30713,11416,30737,11353,30760,11290,30783,11227,30806,11164,30828,11101,30851,11038,30874,10975,30896,10912,30918,10849,30940,10786,30962,10722,30984,10659,31006,10596,31028,10532,31049,10469,31070,10405,31092,10342,31113,10278,31134,10214,31154,10151,31175,10087,31196,10023,31216,9959,31236,9895,31257,9831,31277,9767,31297,9703,31316,9639,31336,9575,31356,9511,31375,9447,31394,9383,31413,9319,31432,9254,31451,9190,31470,9126,31489,9061,31507,8997,31525,8932,31544,8868,31562,8803,31580,8739,31597,8674,31615,8610,31633,8545,31650,8480,31667,8415,31684,8351,31701,8286,31718,8221,31735,8156,31752,8091,31768,8026,31785,7961,31801,7896,31817,7831,31833,7766,31849,7701,31864,7636,31880,7571,31895,7505,31911,7440,31926,7375,31941,7310,31956,7244,31970,7179,31985,7113,31999,7048,32014,6982,32028,6917,32042,6851,32056,6786,32070,6720,32084,6655,32097,6589,32110,6523,32124,6458,32137,6392,32150,6326,32163,6261,32176,6195,32188,6129,32201,6063,32213,5997,32225,5931,32237,5865,32249,5799,32261,5733,32273,5667,32284,5601,32295,5535,32307,5469,32318,5403,32329,5337,32340,5271,32350,5205,32361,5139,32371,5072,32382,5006,32392,4940,32402,4874,32412,4807,32422,4741,32431,4675,32441,4608,32450,4542,32459,4476,32468,4409,32477,4343,32486,4276,32495,4210,32503,4144,32512,4077,32520,4011,32528,3944,32536,3877,32544,3811,32552,3744,32559,3678,32567,3611,32574,3545,32581,3478,32588,3411,32595,3345,32602,3278,32609,3211,32615,3145,32622,3078,32628,3011,32634,2944,32640,2878,32646,2811,32651,2744,32657,2677,32662,2610,32668,2544,32673,2477,32678,2410,32683,2343,32687,2276,32692,2209,32696,2143,32701,2076,32705,2009,32709,1942,32713,1875,32717,1808,32720,1741,32724,1674,32727,1607,32730,1540,32733,1473,32736,1406,32739,1339,32742,1273,32744,1206,32747,1139,32749,1072,32751,1005,32753,938,32755,871,32757,804,32758,737,32760,670,32761,603,32762,536,32763,469,32764,402,32765,335,32765,268,32766,201,32766,134,32766,67,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,-1,-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,-16384,-28378,-16442,-28344,-16500,-28310,-16558,-28276,-16616,-28243,-16673,-28209,-16731,-28174,-16789,-28140,-16846,-28106,-16904,-28071,-16961,-28037,-17018,-28002,-17075,-27967,-17133,-27932,-17190,-27897,-17247,-27862,-17304,-27826,-17361,-27791,-17417,-27755,-17474,-27720,-17531,-27684,-17587,-27648,-17644,-27612,-17700,-27576,-17757,-27539,-17813,-27503,-17869,-27467,-17925,-27430,-17981,-27393,-18037,-27356,-18093,-27320,-18149,-27282,-18205,-27245,-18261,-27208,-18316,-27171,-18372,-27133,-18427,-27095,-18483,-27058,-18538,-27020,-18593,-26982,-18648,-26944,-18703,-26906,-18758,-26867,-18813,-26829,-18868,-26790,-18923,-26752,-18977,-26713,-19032,-26674,-19087,-26635,-19141,-26596,-19195,-26557,-19250,-26517,-19304,-26478,-19358,-26438,-19412,-26399,-19466,-26359,-19520,-26319,-19574,-26279,-19627,-26239,-19681,-26199,-19734,-26159,-19788,-26118,-19841,-26078,-19895,-26037,-19948,-25996,-20001,-25955,-20054,-25914,-20107,-25873,-20160,-25832,-20213,-25791,-20265,-25750,-20318,-25708,-20370,-25666,-20423,-25625,-20475,-25583,-20528,-25541,-20580,-25499,-20632,-25457,-20684,-25415,-20736,-25372,-20788,-25330,-20839,-25287,-20891,-25244,-20943,-25202,-20994,-25159,-21046,-25116,-21097,-25073,-21148,-25030,-21199,-24986,-21250,-24943,-21301,-24899,-21352,-24856,-21403,-24812,-21454,-24768,-21504,-24724,-21555,-24680,-21605,-24636,-21656,-24592,-21706,-24547,-21756,-24503,-21806,-24458,-21856,-24414,-21906,-24369,-21956,-24324,-22005,-24279,-22055,-24234,-22105,-24189,-22154,-24144,-22203,-24098,-22253,-24053,-22302,-24007,-22351,-23962,-22400,-23916,-22449,-23870,-22497,-23824,-22546,-23778,-22595,-23732,-22643,-23686,-22692,-23639,-22740,-23593,-22788,-23546,-22836,-23500,-22884,-23453,-22932,-23406,-22980,-23359,-23028,-23312,-23075,-23265,-23123,-23218,-23170,-23170,-23218,-23123,-23265,-23075,-23312,-23028,-23359,-22980,-23406,-22932,-23453,-22884,-23500,-22836,-23546,-22788,-23593,-22740,-23639,-22692,-23686,-22643,-23732,-22595,-23778,-22546,-23824,-22497,-23870,-22449,-23916,-22400,-23962,-22351,-24007,-22302,-24053,-22253,-24098,-22203,-24144,-22154,-24189,-22105,-24234,-22055,-24279,-22005,-24324,-21956,-24369,-21906,-24414,-21856,-24458,-21806,-24503,-21756,-24547,-21706,-24592,-21656,-24636,-21605,-24680,-21555,-24724,-21504,-24768,-21454,-24812,-21403,-24856,-21352,-24899,-21301,-24943,-21250,-24986,-21199,-25030,-21148,-25073,-21097,-25116,-21046,-25159,-20994,-25202,-20943,-25244,-20891,-25287,-20839,-25330,-20788,-25372,-20736,-25415,-20684,-25457,-20632,-25499,-20580,-25541,-20528,-25583,-20475,-25625,-20423,-25666,-20370,-25708,-20318,-25750,-20265,-25791,-20213,-25832,-20160,-25873,-20107,-25914,-20054,-25955,-20001,-25996,-19948,-26037,-19895,-26078,-19841,-26118,-19788,-26159,-19734,-26199,-19681,-26239,-19627,-26279,-19574,-26319,-19520,-26359,-19466,-26399,-19412,-26438,-19358,-26478,-19304,-26517,-19250,-26557,-19195,-26596,-19141,-26635,-19087,-26674,-19032,-26713,-18977,-26752,-18923,-26790,-18868,-26829,-18813,-26867,-18758,-26906,-18703,-26944,-18648,-26982,-18593,-27020,-18538,-27058,-18483,-27095,-18427,-27133,-18372,-27171,-18316,-27208,-18261,-27245,-18205,-27282,-18149,-27320,-18093,-27356,-18037,-27393,-17981,-27430,-17925,-27467,-17869,-27503,-17813,-27539,-17757,-27576,-17700,-27612,-17644,-27648,-17587,-27684,-17531,-27720,-17474,-27755,-17417,-27791,-17361,-27826,-17304,-27862,-17247,-27897,-17190,-27932,-17133,-27967,-17075,-28002,-17018,-28037,-16961,-28071,-16904,-28106,-16846,-28140,-16789,-28174,-16731,-28209,-16673,-28243,-16616,-28276,-16558,-28310,-16500,-28344,-16442,-28378,-16384,-28411,-16326,-28444,-16268,-28478,-16210,-28511,-16151,-28544,-16093,-28576,-16035,-28609,-15976,-28642,-15918,-28674,-15859,-28707,-15800,-28739,-15741,-28771,-15683,-28803,-15624,-28835,-15565,-28867,-15506,-28898,-15447,-28930,-15388,-28961,-15328,-28993,-15269,-29024,-15210,-29055,-15150,-29086,-15091,-29117,-15031,-29147,-14972,-29178,-14912,-29208,-14853,-29239,-14793,-29269,-14733,-29299,-14673,-29329,-14613,-29359,-14553,-29388,-14493,-29418,-14433,-29447,-14373,-29477,-14312,-29506,-14252,-29535,-14192,-29564,-14131,-29593,-14071,-29622,-14010,-29650,-13950,-29679,-13889,-29707,-13828,-29735,-13767,-29763,-13707,-29791,-13646,-29819,-13585,-29847,-13524,-29874,-13463,-29902,-13401,-29929,-13340,-29956,-13279,-29984,-13218,-30010,-13156,-30037,-13095,-30064,-13034,-30091,-12972,-30117,-12910,-30143,-12849,-30170,-12787,-30196,-12725,-30222,-12664,-30248,-12602,-30273,-12540,-30299,-12478,-30324,-12416,-30350,-12354,-30375,-12292,-30400,-12230,-30425,-12167,-30450,-12105,-30474,-12043,-30499,-11981,-30523,-11918,-30548,-11856,-30572,-11793,-30596,-11731,-30620,-11668,-30644,-11605,-30667,-11543,-30691,-11480,-30714,-11417,-30738,-11354,-30761,-11291,-30784,-11228,-30807,-11165,-30829,-11102,-30852,-11039,-30875,-10976,-30897,-10913,-30919,-10850,-30941,-10787,-30963,-10723,-30985,-10660,-31007,-10597,-31029,-10533,-31050,-10470,-31071,-10406,-31093,-10343,-31114,-10279,-31135,-10215,-31155,-10152,-31176,-10088,-31197,-10024,-31217,-9960,-31237,-9896,-31258,-9832,-31278,-9768,-31298,-9704,-31317,-9640,-31337,-9576,-31357,-9512,-31376,-9448,-31395,-9384,-31414,-9320,-31433,-9255,-31452,-9191,-31471,-9127,-31490,-9062,-31508,-8998,-31526,-8933,-31545,-8869,-31563,-8804,-31581,-8740,-31598,-8675,-31616,-8611,-31634,-8546,-31651,-8481,-31668,-8416,-31685,-8352,-31702,-8287,-31719,-8222,-31736,-8157,-31753,-8092,-31769,-8027,-31786,-7962,-31802,-7897,-31818,-7832,-31834,-7767,-31850,-7702,-31865,-7637,-31881,-7572,-31896,-7506,-31912,-7441,-31927,-7376,-31942,-7311,-31957,-7245,-31971,-7180,-31986,-7114,-32000,-7049,-32015,-6983,-32029,-6918,-32043,-6852,-32057,-6787,-32071,-6721,-32085,-6656,-32098,-6590,-32111,-6524,-32125,-6459,-32138,-6393,-32151,-6327,-32164,-6262,-32177,-6196,-32189,-6130,-32202,-6064,-32214,-5998,-32226,-5932,-32238,-5866,-32250,-5800,-32262,-5734,-32274,-5668,-32285,-5602,-32296,-5536,-32308,-5470,-32319,-5404,-32330,-5338,-32341,-5272,-32351,-5206,-32362,-5140,-32372,-5073,-32383,-5007,-32393,-4941,-32403,-4875,-32413,-4808,-32423,-4742,-32432,-4676,-32442,-4609,-32451,-4543,-32460,-4477,-32469,-4410,-32478,-4344,-32487,-4277,-32496,-4211,-32504,-4145,-32513,-4078,-32521,-4012,-32529,-3945,-32537,-3878,-32545,-3812,-32553,-3745,-32560,-3679,-32568,-3612,-32575,-3546,-32582,-3479,-32589,-3412,-32596,-3346,-32603,-3279,-32610,-3212,-32616,-3146,-32623,-3079,-32629,-3012,-32635,-2945,-32641,-2879,-32647,-2812,-32652,-2745,-32658,-2678,-32663,-2611,-32669,-2545,-32674,-2478,-32679,-2411,-32684,-2344,-32688,-2277,-32693,-2210,-32697,-2144,-32702,-2077,-32706,-2010,-32710,-1943,-32714,-1876,-32718,-1809,-32721,-1742,-32725,-1675,-32728,-1608,-32731,-1541,-32734,-1474,-32737,-1407,-32740,-1340,-32743,-1274,-32745,-1207,-32748,-1140,-32750,-1073,-32752,-1006,-32754,-939,-32756,-872,-32758,-805,-32759,-738,-32761,-671,-32762,-604,-32763,-537,-32764,-470,-32765,-403,-32766,-336,-32766,-269,-32767,-202,-32767,-135,-32767,-68}; - -int16_t s100n_kHz_7_5[30720]__attribute__((aligned(16)))= {31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51}; - -int16_t s100e_kHz_7_5[30720]__attribute__((aligned(16)))= {23169,23169,23205,23134,23240,23098,23276,23062,23311,23027,23346,22991,23382,22955,23417,22919,23452,22883,23487,22847,23522,22811,23557,22775,23592,22739,23627,22703,23661,22666,23696,22630,23731,22594,23766,22557,23800,22521,23835,22484,23869,22448,23903,22411,23938,22374,23972,22338,24006,22301,24041,22264,24075,22227,24109,22190,24143,22153,24177,22116,24211,22079,24244,22042,24278,22004,24312,21967,24346,21930,24379,21893,24413,21855,24446,21818,24480,21780,24513,21743,24546,21705,24580,21667,24613,21629,24646,21592,24679,21554,24712,21516,24745,21478,24778,21440,24811,21402,24844,21364,24877,21326,24909,21288,24942,21249,24974,21211,25007,21173,25039,21134,25072,21096,25104,21057,25136,21019,25169,20980,25201,20942,25233,20903,25265,20864,25297,20825,25329,20787,25361,20748,25392,20709,25424,20670,25456,20631,25487,20592,25519,20553,25550,20513,25582,20474,25613,20435,25645,20396,25676,20356,25707,20317,25738,20277,25769,20238,25800,20198,25831,20159,25862,20119,25893,20079,25924,20040,25954,20000,25985,19960,26016,19920,26046,19880,26077,19840,26107,19800,26137,19760,26168,19720,26198,19680,26228,19640,26258,19599,26288,19559,26318,19519,26348,19478,26378,19438,26408,19397,26437,19357,26467,19316,26497,19276,26526,19235,26556,19194,26585,19154,26615,19113,26644,19072,26673,19031,26702,18990,26731,18949,26760,18908,26789,18867,26818,18826,26847,18785,26876,18744,26905,18702,26933,18661,26962,18620,26990,18578,27019,18537,27047,18495,27076,18454,27104,18412,27132,18371,27160,18329,27188,18287,27216,18246,27244,18204,27272,18162,27300,18120,27328,18078,27355,18036,27383,17994,27411,17952,27438,17910,27466,17868,27493,17826,27520,17784,27548,17742,27575,17699,27602,17657,27629,17615,27656,17572,27683,17530,27710,17487,27736,17445,27763,17402,27790,17360,27816,17317,27843,17274,27869,17232,27896,17189,27922,17146,27948,17103,27975,17060,28001,17017,28027,16974,28053,16931,28079,16888,28105,16845,28131,16802,28156,16759,28182,16716,28208,16672,28233,16629,28259,16586,28284,16542,28309,16499,28335,16455,28360,16412,28385,16368,28410,16325,28435,16281,28460,16238,28485,16194,28510,16150,28534,16107,28559,16063,28584,16019,28608,15975,28633,15931,28657,15887,28681,15843,28706,15799,28730,15755,28754,15711,28778,15667,28802,15623,28826,15579,28850,15534,28874,15490,28897,15446,28921,15401,28945,15357,28968,15313,28992,15268,29015,15224,29038,15179,29062,15135,29085,15090,29108,15045,29131,15001,29154,14956,29177,14911,29200,14866,29222,14822,29245,14777,29268,14732,29290,14687,29313,14642,29335,14597,29358,14552,29380,14507,29402,14462,29424,14417,29446,14372,29468,14326,29490,14281,29512,14236,29534,14191,29556,14145,29577,14100,29599,14055,29621,14009,29642,13964,29663,13918,29685,13873,29706,13827,29727,13782,29748,13736,29769,13690,29790,13645,29811,13599,29832,13553,29853,13507,29873,13462,29894,13416,29915,13370,29935,13324,29955,13278,29976,13232,29996,13186,30016,13140,30036,13094,30056,13048,30076,13002,30096,12956,30116,12909,30136,12863,30156,12817,30175,12771,30195,12724,30214,12678,30234,12632,30253,12585,30272,12539,30291,12492,30311,12446,30330,12399,30349,12353,30368,12306,30386,12260,30405,12213,30424,12166,30442,12120,30461,12073,30480,12026,30498,11980,30516,11933,30535,11886,30553,11839,30571,11792,30589,11745,30607,11698,30625,11651,30643,11604,30660,11557,30678,11510,30696,11463,30713,11416,30731,11369,30748,11322,30766,11275,30783,11227,30800,11180,30817,11133,30834,11086,30851,11038,30868,10991,30885,10944,30902,10896,30918,10849,30935,10801,30951,10754,30968,10706,30984,10659,31001,10611,31017,10564,31033,10516,31049,10469,31065,10421,31081,10373,31097,10326,31113,10278,31128,10230,31144,10182,31160,10135,31175,10087,31191,10039,31206,9991,31221,9943,31236,9895,31252,9847,31267,9799,31282,9751,31297,9703,31311,9655,31326,9607,31341,9559,31356,9511,31370,9463,31385,9415,31399,9367,31413,9319,31428,9270,31442,9222,31456,9174,31470,9126,31484,9077,31498,9029,31512,8981,31525,8932,31539,8884,31553,8836,31566,8787,31580,8739,31593,8690,31606,8642,31619,8593,31633,8545,31646,8496,31659,8448,31672,8399,31684,8351,31697,8302,31710,8253,31723,8205,31735,8156,31748,8107,31760,8059,31772,8010,31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,23169,23169,23205,23134,23240,23098,23276,23062,23311,23027,23346,22991,23382,22955,23417,22919,23452,22883,23487,22847,23522,22811,23557,22775,23592,22739,23627,22703,23661,22666,23696,22630,23731,22594,23766,22557,23800,22521,23835,22484,23869,22448,23903,22411,23938,22374,23972,22338,24006,22301,24041,22264,24075,22227,24109,22190,24143,22153,24177,22116,24211,22079,24244,22042,24278,22004,24312,21967,24346,21930,24379,21893,24413,21855,24446,21818,24480,21780,24513,21743,24546,21705,24580,21667,24613,21629,24646,21592,24679,21554,24712,21516,24745,21478,24778,21440,24811,21402,24844,21364,24877,21326,24909,21288,24942,21249,24974,21211,25007,21173,25039,21134,25072,21096,25104,21057,25136,21019,25169,20980,25201,20942,25233,20903,25265,20864,25297,20825,25329,20787,25361,20748,25392,20709,25424,20670,25456,20631,25487,20592,25519,20553,25550,20513,25582,20474,25613,20435,25645,20396,25676,20356,25707,20317,25738,20277,25769,20238,25800,20198,25831,20159,25862,20119,25893,20079,25924,20040,25954,20000,25985,19960,26016,19920,26046,19880,26077,19840,26107,19800,26137,19760,26168,19720,26198,19680,26228,19640,26258,19599,26288,19559,26318,19519,26348,19478,26378,19438,26408,19397,26437,19357,26467,19316,26497,19276,26526,19235,26556,19194,26585,19154,26615,19113,26644,19072,26673,19031,26702,18990,26731,18949,26760,18908,26789,18867,26818,18826,26847,18785,26876,18744,26905,18702,26933,18661,26962,18620,26990,18578,27019,18537,27047,18495,27076,18454,27104,18412,27132,18371,27160,18329,27188,18287,27216,18246,27244,18204,27272,18162,27300,18120,27328,18078,27355,18036,27383,17994,27411,17952,27438,17910,27466,17868,27493,17826,27520,17784,27548,17742,27575,17699,27602,17657,27629,17615,27656,17572,27683,17530,27710,17487,27736,17445,27763,17402,27790,17360,27816,17317,27843,17274,27869,17232,27896,17189,27922,17146,27948,17103,27975,17060,28001,17017,28027,16974,28053,16931,28079,16888,28105,16845,28131,16802,28156,16759,28182,16716,28208,16672,28233,16629,28259,16586,28284,16542,28309,16499,28335,16455,28360,16412,28385,16368,28410,16325,28435,16281,28460,16238,28485,16194,28510,16150,28534,16107,28559,16063,28584,16019,28608,15975,28633,15931,28657,15887,28681,15843,28706,15799,28730,15755,28754,15711,28778,15667,28802,15623,28826,15579,28850,15534,28874,15490,28897,15446,28921,15401,28945,15357,28968,15313,28992,15268,29015,15224,29038,15179,29062,15135,29085,15090,29108,15045,29131,15001,29154,14956,29177,14911,29200,14866,29222,14822,29245,14777,29268,14732,29290,14687,29313,14642,29335,14597,29358,14552,29380,14507,29402,14462,29424,14417,29446,14372,29468,14326,29490,14281,29512,14236,29534,14191,29556,14145,29577,14100,29599,14055,29621,14009,29642,13964,29663,13918,29685,13873,29706,13827,29727,13782,29748,13736,29769,13690,29790,13645,29811,13599,29832,13553,29853,13507,29873,13462,29894,13416,29915,13370,29935,13324,29955,13278,29976,13232,29996,13186,30016,13140,30036,13094,30056,13048,30076,13002,30096,12956,30116,12909,30136,12863,30156,12817,30175,12771,30195,12724,30214,12678,30234,12632,30253,12585,30272,12539,30291,12492,30311,12446,30330,12399,30349,12353,30368,12306,30386,12260,30405,12213,30424,12166,30442,12120,30461,12073,30480,12026,30498,11980,30516,11933,30535,11886,30553,11839,30571,11792,30589,11745,30607,11698,30625,11651,30643,11604,30660,11557,30678,11510,30696,11463,30713,11416,30731,11369,30748,11322,30766,11275,30783,11227,30800,11180,30817,11133,30834,11086,30851,11038,30868,10991,30885,10944,30902,10896,30918,10849,30935,10801,30951,10754,30968,10706,30984,10659,31001,10611,31017,10564,31033,10516,31049,10469,31065,10421,31081,10373,31097,10326,31113,10278,31128,10230,31144,10182,31160,10135,31175,10087,31191,10039,31206,9991,31221,9943,31236,9895,31252,9847,31267,9799,31282,9751,31297,9703,31311,9655,31326,9607,31341,9559,31356,9511,31370,9463,31385,9415,31399,9367,31413,9319,31428,9270,31442,9222,31456,9174,31470,9126,31484,9077,31498,9029,31512,8981,31525,8932,31539,8884,31553,8836,31566,8787,31580,8739,31593,8690,31606,8642,31619,8593,31633,8545,31646,8496,31659,8448,31672,8399,31684,8351,31697,8302,31710,8253,31723,8205,31735,8156,31748,8107,31760,8059,31772,8010,31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,23169,23169,23205,23134,23240,23098,23276,23062,23311,23027,23346,22991,23382,22955,23417,22919,23452,22883,23487,22847,23522,22811,23557,22775,23592,22739,23627,22703,23661,22666,23696,22630,23731,22594,23766,22557,23800,22521,23835,22484,23869,22448,23903,22411,23938,22374,23972,22338,24006,22301,24041,22264,24075,22227,24109,22190,24143,22153,24177,22116,24211,22079,24244,22042,24278,22004,24312,21967,24346,21930,24379,21893,24413,21855,24446,21818,24480,21780,24513,21743,24546,21705,24580,21667,24613,21629,24646,21592,24679,21554,24712,21516,24745,21478,24778,21440,24811,21402,24844,21364,24877,21326,24909,21288,24942,21249,24974,21211,25007,21173,25039,21134,25072,21096,25104,21057,25136,21019,25169,20980,25201,20942,25233,20903,25265,20864,25297,20825,25329,20787,25361,20748,25392,20709,25424,20670,25456,20631,25487,20592,25519,20553,25550,20513,25582,20474,25613,20435,25645,20396,25676,20356,25707,20317,25738,20277,25769,20238,25800,20198,25831,20159,25862,20119,25893,20079,25924,20040,25954,20000,25985,19960,26016,19920,26046,19880,26077,19840,26107,19800,26137,19760,26168,19720,26198,19680,26228,19640,26258,19599,26288,19559,26318,19519,26348,19478,26378,19438,26408,19397,26437,19357,26467,19316,26497,19276,26526,19235,26556,19194,26585,19154,26615,19113,26644,19072,26673,19031,26702,18990,26731,18949,26760,18908,26789,18867,26818,18826,26847,18785,26876,18744,26905,18702,26933,18661,26962,18620,26990,18578,27019,18537,27047,18495,27076,18454,27104,18412,27132,18371,27160,18329,27188,18287,27216,18246,27244,18204,27272,18162,27300,18120,27328,18078,27355,18036,27383,17994,27411,17952,27438,17910,27466,17868,27493,17826,27520,17784,27548,17742,27575,17699,27602,17657,27629,17615,27656,17572,27683,17530,27710,17487,27736,17445,27763,17402,27790,17360,27816,17317,27843,17274,27869,17232,27896,17189,27922,17146,27948,17103,27975,17060,28001,17017,28027,16974,28053,16931,28079,16888,28105,16845,28131,16802,28156,16759,28182,16716,28208,16672,28233,16629,28259,16586,28284,16542,28309,16499,28335,16455,28360,16412,28385,16368,28410,16325,28435,16281,28460,16238,28485,16194,28510,16150,28534,16107,28559,16063,28584,16019,28608,15975,28633,15931,28657,15887,28681,15843,28706,15799,28730,15755,28754,15711,28778,15667,28802,15623,28826,15579,28850,15534,28874,15490,28897,15446,28921,15401,28945,15357,28968,15313,28992,15268,29015,15224,29038,15179,29062,15135,29085,15090,29108,15045,29131,15001,29154,14956,29177,14911,29200,14866,29222,14822,29245,14777,29268,14732,29290,14687,29313,14642,29335,14597,29358,14552,29380,14507,29402,14462,29424,14417,29446,14372,29468,14326,29490,14281,29512,14236,29534,14191,29556,14145,29577,14100,29599,14055,29621,14009,29642,13964,29663,13918,29685,13873,29706,13827,29727,13782,29748,13736,29769,13690,29790,13645,29811,13599,29832,13553,29853,13507,29873,13462,29894,13416,29915,13370,29935,13324,29955,13278,29976,13232,29996,13186,30016,13140,30036,13094,30056,13048,30076,13002,30096,12956,30116,12909,30136,12863,30156,12817,30175,12771,30195,12724,30214,12678,30234,12632,30253,12585,30272,12539,30291,12492,30311,12446,30330,12399,30349,12353,30368,12306,30386,12260,30405,12213,30424,12166,30442,12120,30461,12073,30480,12026,30498,11980,30516,11933,30535,11886,30553,11839,30571,11792,30589,11745,30607,11698,30625,11651,30643,11604,30660,11557,30678,11510,30696,11463,30713,11416,30731,11369,30748,11322,30766,11275,30783,11227,30800,11180,30817,11133,30834,11086,30851,11038,30868,10991,30885,10944,30902,10896,30918,10849,30935,10801,30951,10754,30968,10706,30984,10659,31001,10611,31017,10564,31033,10516,31049,10469,31065,10421,31081,10373,31097,10326,31113,10278,31128,10230,31144,10182,31160,10135,31175,10087,31191,10039,31206,9991,31221,9943,31236,9895,31252,9847,31267,9799,31282,9751,31297,9703,31311,9655,31326,9607,31341,9559,31356,9511,31370,9463,31385,9415,31399,9367,31413,9319,31428,9270,31442,9222,31456,9174,31470,9126,31484,9077,31498,9029,31512,8981,31525,8932,31539,8884,31553,8836,31566,8787,31580,8739,31593,8690,31606,8642,31619,8593,31633,8545,31646,8496,31659,8448,31672,8399,31684,8351,31697,8302,31710,8253,31723,8205,31735,8156,31748,8107,31760,8059,31772,8010,31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,23169,23169,23205,23134,23240,23098,23276,23062,23311,23027,23346,22991,23382,22955,23417,22919,23452,22883,23487,22847,23522,22811,23557,22775,23592,22739,23627,22703,23661,22666,23696,22630,23731,22594,23766,22557,23800,22521,23835,22484,23869,22448,23903,22411,23938,22374,23972,22338,24006,22301,24041,22264,24075,22227,24109,22190,24143,22153,24177,22116,24211,22079,24244,22042,24278,22004,24312,21967,24346,21930,24379,21893,24413,21855,24446,21818,24480,21780,24513,21743,24546,21705,24580,21667,24613,21629,24646,21592,24679,21554,24712,21516,24745,21478,24778,21440,24811,21402,24844,21364,24877,21326,24909,21288,24942,21249,24974,21211,25007,21173,25039,21134,25072,21096,25104,21057,25136,21019,25169,20980,25201,20942,25233,20903,25265,20864,25297,20825,25329,20787,25361,20748,25392,20709,25424,20670,25456,20631,25487,20592,25519,20553,25550,20513,25582,20474,25613,20435,25645,20396,25676,20356,25707,20317,25738,20277,25769,20238,25800,20198,25831,20159,25862,20119,25893,20079,25924,20040,25954,20000,25985,19960,26016,19920,26046,19880,26077,19840,26107,19800,26137,19760,26168,19720,26198,19680,26228,19640,26258,19599,26288,19559,26318,19519,26348,19478,26378,19438,26408,19397,26437,19357,26467,19316,26497,19276,26526,19235,26556,19194,26585,19154,26615,19113,26644,19072,26673,19031,26702,18990,26731,18949,26760,18908,26789,18867,26818,18826,26847,18785,26876,18744,26905,18702,26933,18661,26962,18620,26990,18578,27019,18537,27047,18495,27076,18454,27104,18412,27132,18371,27160,18329,27188,18287,27216,18246,27244,18204,27272,18162,27300,18120,27328,18078,27355,18036,27383,17994,27411,17952,27438,17910,27466,17868,27493,17826,27520,17784,27548,17742,27575,17699,27602,17657,27629,17615,27656,17572,27683,17530,27710,17487,27736,17445,27763,17402,27790,17360,27816,17317,27843,17274,27869,17232,27896,17189,27922,17146,27948,17103,27975,17060,28001,17017,28027,16974,28053,16931,28079,16888,28105,16845,28131,16802,28156,16759,28182,16716,28208,16672,28233,16629,28259,16586,28284,16542,28309,16499,28335,16455,28360,16412,28385,16368,28410,16325,28435,16281,28460,16238,28485,16194,28510,16150,28534,16107,28559,16063,28584,16019,28608,15975,28633,15931,28657,15887,28681,15843,28706,15799,28730,15755,28754,15711,28778,15667,28802,15623,28826,15579,28850,15534,28874,15490,28897,15446,28921,15401,28945,15357,28968,15313,28992,15268,29015,15224,29038,15179,29062,15135,29085,15090,29108,15045,29131,15001,29154,14956,29177,14911,29200,14866,29222,14822,29245,14777,29268,14732,29290,14687,29313,14642,29335,14597,29358,14552,29380,14507,29402,14462,29424,14417,29446,14372,29468,14326,29490,14281,29512,14236,29534,14191,29556,14145,29577,14100,29599,14055,29621,14009,29642,13964,29663,13918,29685,13873,29706,13827,29727,13782,29748,13736,29769,13690,29790,13645,29811,13599,29832,13553,29853,13507,29873,13462,29894,13416,29915,13370,29935,13324,29955,13278,29976,13232,29996,13186,30016,13140,30036,13094,30056,13048,30076,13002,30096,12956,30116,12909,30136,12863,30156,12817,30175,12771,30195,12724,30214,12678,30234,12632,30253,12585,30272,12539,30291,12492,30311,12446,30330,12399,30349,12353,30368,12306,30386,12260,30405,12213,30424,12166,30442,12120,30461,12073,30480,12026,30498,11980,30516,11933,30535,11886,30553,11839,30571,11792,30589,11745,30607,11698,30625,11651,30643,11604,30660,11557,30678,11510,30696,11463,30713,11416,30731,11369,30748,11322,30766,11275,30783,11227,30800,11180,30817,11133,30834,11086,30851,11038,30868,10991,30885,10944,30902,10896,30918,10849,30935,10801,30951,10754,30968,10706,30984,10659,31001,10611,31017,10564,31033,10516,31049,10469,31065,10421,31081,10373,31097,10326,31113,10278,31128,10230,31144,10182,31160,10135,31175,10087,31191,10039,31206,9991,31221,9943,31236,9895,31252,9847,31267,9799,31282,9751,31297,9703,31311,9655,31326,9607,31341,9559,31356,9511,31370,9463,31385,9415,31399,9367,31413,9319,31428,9270,31442,9222,31456,9174,31470,9126,31484,9077,31498,9029,31512,8981,31525,8932,31539,8884,31553,8836,31566,8787,31580,8739,31593,8690,31606,8642,31619,8593,31633,8545,31646,8496,31659,8448,31672,8399,31684,8351,31697,8302,31710,8253,31723,8205,31735,8156,31748,8107,31760,8059,31772,8010,31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,23169,23169,23205,23134,23240,23098,23276,23062,23311,23027,23346,22991,23382,22955,23417,22919,23452,22883,23487,22847,23522,22811,23557,22775,23592,22739,23627,22703,23661,22666,23696,22630,23731,22594,23766,22557,23800,22521,23835,22484,23869,22448,23903,22411,23938,22374,23972,22338,24006,22301,24041,22264,24075,22227,24109,22190,24143,22153,24177,22116,24211,22079,24244,22042,24278,22004,24312,21967,24346,21930,24379,21893,24413,21855,24446,21818,24480,21780,24513,21743,24546,21705,24580,21667,24613,21629,24646,21592,24679,21554,24712,21516,24745,21478,24778,21440,24811,21402,24844,21364,24877,21326,24909,21288,24942,21249,24974,21211,25007,21173,25039,21134,25072,21096,25104,21057,25136,21019,25169,20980,25201,20942,25233,20903,25265,20864,25297,20825,25329,20787,25361,20748,25392,20709,25424,20670,25456,20631,25487,20592,25519,20553,25550,20513,25582,20474,25613,20435,25645,20396,25676,20356,25707,20317,25738,20277,25769,20238,25800,20198,25831,20159,25862,20119,25893,20079,25924,20040,25954,20000,25985,19960,26016,19920,26046,19880,26077,19840,26107,19800,26137,19760,26168,19720,26198,19680,26228,19640,26258,19599,26288,19559,26318,19519,26348,19478,26378,19438,26408,19397,26437,19357,26467,19316,26497,19276,26526,19235,26556,19194,26585,19154,26615,19113,26644,19072,26673,19031,26702,18990,26731,18949,26760,18908,26789,18867,26818,18826,26847,18785,26876,18744,26905,18702,26933,18661,26962,18620,26990,18578,27019,18537,27047,18495,27076,18454,27104,18412,27132,18371,27160,18329,27188,18287,27216,18246,27244,18204,27272,18162,27300,18120,27328,18078,27355,18036,27383,17994,27411,17952,27438,17910,27466,17868,27493,17826,27520,17784,27548,17742,27575,17699,27602,17657,27629,17615,27656,17572,27683,17530,27710,17487,27736,17445,27763,17402,27790,17360,27816,17317,27843,17274,27869,17232,27896,17189,27922,17146,27948,17103,27975,17060,28001,17017,28027,16974,28053,16931,28079,16888,28105,16845,28131,16802,28156,16759,28182,16716,28208,16672,28233,16629,28259,16586,28284,16542,28309,16499,28335,16455,28360,16412,28385,16368,28410,16325,28435,16281,28460,16238,28485,16194,28510,16150,28534,16107,28559,16063,28584,16019,28608,15975,28633,15931,28657,15887,28681,15843,28706,15799,28730,15755,28754,15711,28778,15667,28802,15623,28826,15579,28850,15534,28874,15490,28897,15446,28921,15401,28945,15357,28968,15313,28992,15268,29015,15224,29038,15179,29062,15135,29085,15090,29108,15045,29131,15001,29154,14956,29177,14911,29200,14866,29222,14822,29245,14777,29268,14732,29290,14687,29313,14642,29335,14597,29358,14552,29380,14507,29402,14462,29424,14417,29446,14372,29468,14326,29490,14281,29512,14236,29534,14191,29556,14145,29577,14100,29599,14055,29621,14009,29642,13964,29663,13918,29685,13873,29706,13827,29727,13782,29748,13736,29769,13690,29790,13645,29811,13599,29832,13553,29853,13507,29873,13462,29894,13416,29915,13370,29935,13324,29955,13278,29976,13232,29996,13186,30016,13140,30036,13094,30056,13048,30076,13002,30096,12956,30116,12909,30136,12863,30156,12817,30175,12771,30195,12724,30214,12678,30234,12632,30253,12585,30272,12539,30291,12492,30311,12446,30330,12399,30349,12353,30368,12306,30386,12260,30405,12213,30424,12166,30442,12120,30461,12073,30480,12026,30498,11980,30516,11933,30535,11886,30553,11839,30571,11792,30589,11745,30607,11698,30625,11651,30643,11604,30660,11557,30678,11510,30696,11463,30713,11416,30731,11369,30748,11322,30766,11275,30783,11227,30800,11180,30817,11133,30834,11086,30851,11038,30868,10991,30885,10944,30902,10896,30918,10849,30935,10801,30951,10754,30968,10706,30984,10659,31001,10611,31017,10564,31033,10516,31049,10469,31065,10421,31081,10373,31097,10326,31113,10278,31128,10230,31144,10182,31160,10135,31175,10087,31191,10039,31206,9991,31221,9943,31236,9895,31252,9847,31267,9799,31282,9751,31297,9703,31311,9655,31326,9607,31341,9559,31356,9511,31370,9463,31385,9415,31399,9367,31413,9319,31428,9270,31442,9222,31456,9174,31470,9126,31484,9077,31498,9029,31512,8981,31525,8932,31539,8884,31553,8836,31566,8787,31580,8739,31593,8690,31606,8642,31619,8593,31633,8545,31646,8496,31659,8448,31672,8399,31684,8351,31697,8302,31710,8253,31723,8205,31735,8156,31748,8107,31760,8059,31772,8010,31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51,23169,23169,23205,23134,23240,23098,23276,23062,23311,23027,23346,22991,23382,22955,23417,22919,23452,22883,23487,22847,23522,22811,23557,22775,23592,22739,23627,22703,23661,22666,23696,22630,23731,22594,23766,22557,23800,22521,23835,22484,23869,22448,23903,22411,23938,22374,23972,22338,24006,22301,24041,22264,24075,22227,24109,22190,24143,22153,24177,22116,24211,22079,24244,22042,24278,22004,24312,21967,24346,21930,24379,21893,24413,21855,24446,21818,24480,21780,24513,21743,24546,21705,24580,21667,24613,21629,24646,21592,24679,21554,24712,21516,24745,21478,24778,21440,24811,21402,24844,21364,24877,21326,24909,21288,24942,21249,24974,21211,25007,21173,25039,21134,25072,21096,25104,21057,25136,21019,25169,20980,25201,20942,25233,20903,25265,20864,25297,20825,25329,20787,25361,20748,25392,20709,25424,20670,25456,20631,25487,20592,25519,20553,25550,20513,25582,20474,25613,20435,25645,20396,25676,20356,25707,20317,25738,20277,25769,20238,25800,20198,25831,20159,25862,20119,25893,20079,25924,20040,25954,20000,25985,19960,26016,19920,26046,19880,26077,19840,26107,19800,26137,19760,26168,19720,26198,19680,26228,19640,26258,19599,26288,19559,26318,19519,26348,19478,26378,19438,26408,19397,26437,19357,26467,19316,26497,19276,26526,19235,26556,19194,26585,19154,26615,19113,26644,19072,26673,19031,26702,18990,26731,18949,26760,18908,26789,18867,26818,18826,26847,18785,26876,18744,26905,18702,26933,18661,26962,18620,26990,18578,27019,18537,27047,18495,27076,18454,27104,18412,27132,18371,27160,18329,27188,18287,27216,18246,27244,18204,27272,18162,27300,18120,27328,18078,27355,18036,27383,17994,27411,17952,27438,17910,27466,17868,27493,17826,27520,17784,27548,17742,27575,17699,27602,17657,27629,17615,27656,17572,27683,17530,27710,17487,27736,17445,27763,17402,27790,17360,27816,17317,27843,17274,27869,17232,27896,17189,27922,17146,27948,17103,27975,17060,28001,17017,28027,16974,28053,16931,28079,16888,28105,16845,28131,16802,28156,16759,28182,16716,28208,16672,28233,16629,28259,16586,28284,16542,28309,16499,28335,16455,28360,16412,28385,16368,28410,16325,28435,16281,28460,16238,28485,16194,28510,16150,28534,16107,28559,16063,28584,16019,28608,15975,28633,15931,28657,15887,28681,15843,28706,15799,28730,15755,28754,15711,28778,15667,28802,15623,28826,15579,28850,15534,28874,15490,28897,15446,28921,15401,28945,15357,28968,15313,28992,15268,29015,15224,29038,15179,29062,15135,29085,15090,29108,15045,29131,15001,29154,14956,29177,14911,29200,14866,29222,14822,29245,14777,29268,14732,29290,14687,29313,14642,29335,14597,29358,14552,29380,14507,29402,14462,29424,14417,29446,14372,29468,14326,29490,14281,29512,14236,29534,14191,29556,14145,29577,14100,29599,14055,29621,14009,29642,13964,29663,13918,29685,13873,29706,13827,29727,13782,29748,13736,29769,13690,29790,13645,29811,13599,29832,13553,29853,13507,29873,13462,29894,13416,29915,13370,29935,13324,29955,13278,29976,13232,29996,13186,30016,13140,30036,13094,30056,13048,30076,13002,30096,12956,30116,12909,30136,12863,30156,12817,30175,12771,30195,12724,30214,12678,30234,12632,30253,12585,30272,12539,30291,12492,30311,12446,30330,12399,30349,12353,30368,12306,30386,12260,30405,12213,30424,12166,30442,12120,30461,12073,30480,12026,30498,11980,30516,11933,30535,11886,30553,11839,30571,11792,30589,11745,30607,11698,30625,11651,30643,11604,30660,11557,30678,11510,30696,11463,30713,11416,30731,11369,30748,11322,30766,11275,30783,11227,30800,11180,30817,11133,30834,11086,30851,11038,30868,10991,30885,10944,30902,10896,30918,10849,30935,10801,30951,10754,30968,10706,30984,10659,31001,10611,31017,10564,31033,10516,31049,10469,31065,10421,31081,10373,31097,10326,31113,10278,31128,10230,31144,10182,31160,10135,31175,10087,31191,10039,31206,9991,31221,9943,31236,9895,31252,9847,31267,9799,31282,9751,31297,9703,31311,9655,31326,9607,31341,9559,31356,9511,31370,9463,31385,9415,31399,9367,31413,9319,31428,9270,31442,9222,31456,9174,31470,9126,31484,9077,31498,9029,31512,8981,31525,8932,31539,8884,31553,8836,31566,8787,31580,8739,31593,8690,31606,8642,31619,8593,31633,8545,31646,8496,31659,8448,31672,8399,31684,8351,31697,8302,31710,8253,31723,8205,31735,8156,31748,8107,31760,8059,31772,8010,31785,7961,31797,7912,31809,7864,31821,7815,31833,7766,31845,7717,31856,7668,31868,7619,31880,7571,31891,7522,31903,7473,31914,7424,31926,7375,31937,7326,31948,7277,31959,7228,31970,7179,31981,7130,31992,7081,32003,7032,32014,6982,32024,6933,32035,6884,32046,6835,32056,6786,32066,6737,32077,6688,32087,6638,32097,6589,32107,6540,32117,6491,32127,6441,32137,6392,32147,6343,32156,6293,32166,6244,32176,6195,32185,6145,32194,6096,32204,6047,32213,5997,32222,5948,32231,5898,32240,5849,32249,5799,32258,5750,32267,5700,32275,5651,32284,5601,32293,5552,32301,5502,32310,5453,32318,5403,32326,5354,32334,5304,32342,5254,32350,5205,32358,5155,32366,5106,32374,5056,32382,5006,32389,4957,32397,4907,32404,4857,32412,4807,32419,4758,32426,4708,32434,4658,32441,4608,32448,4559,32455,4509,32462,4459,32468,4409,32475,4359,32482,4310,32488,4260,32495,4210,32501,4160,32508,4110,32514,4060,32520,4011,32526,3961,32532,3911,32538,3861,32544,3811,32550,3761,32556,3711,32561,3661,32567,3611,32572,3561,32578,3511,32583,3461,32588,3411,32594,3361,32599,3311,32604,3261,32609,3211,32614,3161,32618,3111,32623,3061,32628,3011,32632,2961,32637,2911,32641,2861,32646,2811,32650,2761,32654,2711,32658,2661,32662,2610,32666,2560,32670,2510,32674,2460,32678,2410,32681,2360,32685,2310,32688,2260,32692,2209,32695,2159,32699,2109,32702,2059,32705,2009,32708,1959,32711,1908,32714,1858,32717,1808,32719,1758,32722,1708,32725,1658,32727,1607,32729,1557,32732,1507,32734,1457,32736,1406,32738,1356,32740,1306,32742,1256,32744,1206,32746,1155,32748,1105,32750,1055,32751,1005,32753,954,32754,904,32755,854,32757,804,32758,753,32759,703,32760,653,32761,603,32762,552,32763,502,32763,452,32764,402,32765,351,32765,301,32766,251,32766,201,32766,150,32766,100,32766,50,32767,0,32766,-51,32766,-101,32766,-151,32766,-202,32766,-252,32765,-302,32765,-352,32764,-403,32763,-453,32763,-503,32762,-553,32761,-604,32760,-654,32759,-704,32758,-754,32757,-805,32755,-855,32754,-905,32753,-955,32751,-1006,32750,-1056,32748,-1106,32746,-1156,32744,-1207,32742,-1257,32740,-1307,32738,-1357,32736,-1407,32734,-1458,32732,-1508,32729,-1558,32727,-1608,32725,-1659,32722,-1709,32719,-1759,32717,-1809,32714,-1859,32711,-1909,32708,-1960,32705,-2010,32702,-2060,32699,-2110,32695,-2160,32692,-2210,32688,-2261,32685,-2311,32681,-2361,32678,-2411,32674,-2461,32670,-2511,32666,-2561,32662,-2611,32658,-2662,32654,-2712,32650,-2762,32646,-2812,32641,-2862,32637,-2912,32632,-2962,32628,-3012,32623,-3062,32618,-3112,32614,-3162,32609,-3212,32604,-3262,32599,-3312,32594,-3362,32588,-3412,32583,-3462,32578,-3512,32572,-3562,32567,-3612,32561,-3662,32556,-3712,32550,-3762,32544,-3812,32538,-3862,32532,-3912,32526,-3962,32520,-4012,32514,-4061,32508,-4111,32501,-4161,32495,-4211,32488,-4261,32482,-4311,32475,-4360,32468,-4410,32462,-4460,32455,-4510,32448,-4560,32441,-4609,32434,-4659,32426,-4709,32419,-4759,32412,-4808,32404,-4858,32397,-4908,32389,-4958,32382,-5007,32374,-5057,32366,-5107,32358,-5156,32350,-5206,32342,-5255,32334,-5305,32326,-5355,32318,-5404,32310,-5454,32301,-5503,32293,-5553,32284,-5602,32275,-5652,32267,-5701,32258,-5751,32249,-5800,32240,-5850,32231,-5899,32222,-5949,32213,-5998,32204,-6048,32194,-6097,32185,-6146,32176,-6196,32166,-6245,32156,-6294,32147,-6344,32137,-6393,32127,-6442,32117,-6492,32107,-6541,32097,-6590,32087,-6639,32077,-6689,32066,-6738,32056,-6787,32046,-6836,32035,-6885,32024,-6934,32014,-6983,32003,-7033,31992,-7082,31981,-7131,31970,-7180,31959,-7229,31948,-7278,31937,-7327,31926,-7376,31914,-7425,31903,-7474,31891,-7523,31880,-7572,31868,-7620,31856,-7669,31845,-7718,31833,-7767,31821,-7816,31809,-7865,31797,-7913,31785,-7962,31772,-8011,31760,-8060,31748,-8108,31735,-8157,31723,-8206,31710,-8254,31697,-8303,31684,-8352,31672,-8400,31659,-8449,31646,-8497,31633,-8546,31619,-8594,31606,-8643,31593,-8691,31580,-8740,31566,-8788,31553,-8837,31539,-8885,31525,-8933,31512,-8982,31498,-9030,31484,-9078,31470,-9127,31456,-9175,31442,-9223,31428,-9271,31413,-9320,31399,-9368,31385,-9416,31370,-9464,31356,-9512,31341,-9560,31326,-9608,31311,-9656,31297,-9704,31282,-9752,31267,-9800,31252,-9848,31236,-9896,31221,-9944,31206,-9992,31191,-10040,31175,-10088,31160,-10136,31144,-10183,31128,-10231,31113,-10279,31097,-10327,31081,-10374,31065,-10422,31049,-10470,31033,-10517,31017,-10565,31001,-10612,30984,-10660,30968,-10707,30951,-10755,30935,-10802,30918,-10850,30902,-10897,30885,-10945,30868,-10992,30851,-11039,30834,-11087,30817,-11134,30800,-11181,30783,-11228,30766,-11276,30748,-11323,30731,-11370,30713,-11417,30696,-11464,30678,-11511,30660,-11558,30643,-11605,30625,-11652,30607,-11699,30589,-11746,30571,-11793,30553,-11840,30535,-11887,30516,-11934,30498,-11981,30480,-12027,30461,-12074,30442,-12121,30424,-12167,30405,-12214,30386,-12261,30368,-12307,30349,-12354,30330,-12400,30311,-12447,30291,-12493,30272,-12540,30253,-12586,30234,-12633,30214,-12679,30195,-12725,30175,-12772,30156,-12818,30136,-12864,30116,-12910,30096,-12957,30076,-13003,30056,-13049,30036,-13095,30016,-13141,29996,-13187,29976,-13233,29955,-13279,29935,-13325,29915,-13371,29894,-13417,29873,-13463,29853,-13508,29832,-13554,29811,-13600,29790,-13646,29769,-13691,29748,-13737,29727,-13783,29706,-13828,29685,-13874,29663,-13919,29642,-13965,29621,-14010,29599,-14056,29577,-14101,29556,-14146,29534,-14192,29512,-14237,29490,-14282,29468,-14327,29446,-14373,29424,-14418,29402,-14463,29380,-14508,29358,-14553,29335,-14598,29313,-14643,29290,-14688,29268,-14733,29245,-14778,29222,-14823,29200,-14867,29177,-14912,29154,-14957,29131,-15002,29108,-15046,29085,-15091,29062,-15136,29038,-15180,29015,-15225,28992,-15269,28968,-15314,28945,-15358,28921,-15402,28897,-15447,28874,-15491,28850,-15535,28826,-15580,28802,-15624,28778,-15668,28754,-15712,28730,-15756,28706,-15800,28681,-15844,28657,-15888,28633,-15932,28608,-15976,28584,-16020,28559,-16064,28534,-16108,28510,-16151,28485,-16195,28460,-16239,28435,-16282,28410,-16326,28385,-16369,28360,-16413,28335,-16456,28309,-16500,28284,-16543,28259,-16587,28233,-16630,28208,-16673,28182,-16717,28156,-16760,28131,-16803,28105,-16846,28079,-16889,28053,-16932,28027,-16975,28001,-17018,27975,-17061,27948,-17104,27922,-17147,27896,-17190,27869,-17233,27843,-17275,27816,-17318,27790,-17361,27763,-17403,27736,-17446,27710,-17488,27683,-17531,27656,-17573,27629,-17616,27602,-17658,27575,-17700,27548,-17743,27520,-17785,27493,-17827,27466,-17869,27438,-17911,27411,-17953,27383,-17995,27355,-18037,27328,-18079,27300,-18121,27272,-18163,27244,-18205,27216,-18247,27188,-18288,27160,-18330,27132,-18372,27104,-18413,27076,-18455,27047,-18496,27019,-18538,26990,-18579,26962,-18621,26933,-18662,26905,-18703,26876,-18745,26847,-18786,26818,-18827,26789,-18868,26760,-18909,26731,-18950,26702,-18991,26673,-19032,26644,-19073,26615,-19114,26585,-19155,26556,-19195,26526,-19236,26497,-19277,26467,-19317,26437,-19358,26408,-19398,26378,-19439,26348,-19479,26318,-19520,26288,-19560,26258,-19600,26228,-19641,26198,-19681,26168,-19721,26137,-19761,26107,-19801,26077,-19841,26046,-19881,26016,-19921,25985,-19961,25954,-20001,25924,-20041,25893,-20080,25862,-20120,25831,-20160,25800,-20199,25769,-20239,25738,-20278,25707,-20318,25676,-20357,25645,-20397,25613,-20436,25582,-20475,25550,-20514,25519,-20554,25487,-20593,25456,-20632,25424,-20671,25392,-20710,25361,-20749,25329,-20788,25297,-20826,25265,-20865,25233,-20904,25201,-20943,25169,-20981,25136,-21020,25104,-21058,25072,-21097,25039,-21135,25007,-21174,24974,-21212,24942,-21250,24909,-21289,24877,-21327,24844,-21365,24811,-21403,24778,-21441,24745,-21479,24712,-21517,24679,-21555,24646,-21593,24613,-21630,24580,-21668,24546,-21706,24513,-21744,24480,-21781,24446,-21819,24413,-21856,24379,-21894,24346,-21931,24312,-21968,24278,-22005,24244,-22043,24211,-22080,24177,-22117,24143,-22154,24109,-22191,24075,-22228,24041,-22265,24006,-22302,23972,-22339,23938,-22375,23903,-22412,23869,-22449,23835,-22485,23800,-22522,23766,-22558,23731,-22595,23696,-22631,23661,-22667,23627,-22704,23592,-22740,23557,-22776,23522,-22812,23487,-22848,23452,-22884,23417,-22920,23382,-22956,23346,-22992,23311,-23028,23276,-23063,23240,-23099,23205,-23135,23169,-23170,23134,-23206,23098,-23241,23062,-23277,23027,-23312,22991,-23347,22955,-23383,22919,-23418,22883,-23453,22847,-23488,22811,-23523,22775,-23558,22739,-23593,22703,-23628,22666,-23662,22630,-23697,22594,-23732,22557,-23767,22521,-23801,22484,-23836,22448,-23870,22411,-23904,22374,-23939,22338,-23973,22301,-24007,22264,-24042,22227,-24076,22190,-24110,22153,-24144,22116,-24178,22079,-24212,22042,-24245,22004,-24279,21967,-24313,21930,-24347,21893,-24380,21855,-24414,21818,-24447,21780,-24481,21743,-24514,21705,-24547,21667,-24581,21629,-24614,21592,-24647,21554,-24680,21516,-24713,21478,-24746,21440,-24779,21402,-24812,21364,-24845,21326,-24878,21288,-24910,21249,-24943,21211,-24975,21173,-25008,21134,-25040,21096,-25073,21057,-25105,21019,-25137,20980,-25170,20942,-25202,20903,-25234,20864,-25266,20825,-25298,20787,-25330,20748,-25362,20709,-25393,20670,-25425,20631,-25457,20592,-25488,20553,-25520,20513,-25551,20474,-25583,20435,-25614,20396,-25646,20356,-25677,20317,-25708,20277,-25739,20238,-25770,20198,-25801,20159,-25832,20119,-25863,20079,-25894,20040,-25925,20000,-25955,19960,-25986,19920,-26017,19880,-26047,19840,-26078,19800,-26108,19760,-26138,19720,-26169,19680,-26199,19640,-26229,19599,-26259,19559,-26289,19519,-26319,19478,-26349,19438,-26379,19397,-26409,19357,-26438,19316,-26468,19276,-26498,19235,-26527,19194,-26557,19154,-26586,19113,-26616,19072,-26645,19031,-26674,18990,-26703,18949,-26732,18908,-26761,18867,-26790,18826,-26819,18785,-26848,18744,-26877,18702,-26906,18661,-26934,18620,-26963,18578,-26991,18537,-27020,18495,-27048,18454,-27077,18412,-27105,18371,-27133,18329,-27161,18287,-27189,18246,-27217,18204,-27245,18162,-27273,18120,-27301,18078,-27329,18036,-27356,17994,-27384,17952,-27412,17910,-27439,17868,-27467,17826,-27494,17784,-27521,17742,-27549,17699,-27576,17657,-27603,17615,-27630,17572,-27657,17530,-27684,17487,-27711,17445,-27737,17402,-27764,17360,-27791,17317,-27817,17274,-27844,17232,-27870,17189,-27897,17146,-27923,17103,-27949,17060,-27976,17017,-28002,16974,-28028,16931,-28054,16888,-28080,16845,-28106,16802,-28132,16759,-28157,16716,-28183,16672,-28209,16629,-28234,16586,-28260,16542,-28285,16499,-28310,16455,-28336,16412,-28361,16368,-28386,16325,-28411,16281,-28436,16238,-28461,16194,-28486,16150,-28511,16107,-28535,16063,-28560,16019,-28585,15975,-28609,15931,-28634,15887,-28658,15843,-28682,15799,-28707,15755,-28731,15711,-28755,15667,-28779,15623,-28803,15579,-28827,15534,-28851,15490,-28875,15446,-28898,15401,-28922,15357,-28946,15313,-28969,15268,-28993,15224,-29016,15179,-29039,15135,-29063,15090,-29086,15045,-29109,15001,-29132,14956,-29155,14911,-29178,14866,-29201,14822,-29223,14777,-29246,14732,-29269,14687,-29291,14642,-29314,14597,-29336,14552,-29359,14507,-29381,14462,-29403,14417,-29425,14372,-29447,14326,-29469,14281,-29491,14236,-29513,14191,-29535,14145,-29557,14100,-29578,14055,-29600,14009,-29622,13964,-29643,13918,-29664,13873,-29686,13827,-29707,13782,-29728,13736,-29749,13690,-29770,13645,-29791,13599,-29812,13553,-29833,13507,-29854,13462,-29874,13416,-29895,13370,-29916,13324,-29936,13278,-29956,13232,-29977,13186,-29997,13140,-30017,13094,-30037,13048,-30057,13002,-30077,12956,-30097,12909,-30117,12863,-30137,12817,-30157,12771,-30176,12724,-30196,12678,-30215,12632,-30235,12585,-30254,12539,-30273,12492,-30292,12446,-30312,12399,-30331,12353,-30350,12306,-30369,12260,-30387,12213,-30406,12166,-30425,12120,-30443,12073,-30462,12026,-30481,11980,-30499,11933,-30517,11886,-30536,11839,-30554,11792,-30572,11745,-30590,11698,-30608,11651,-30626,11604,-30644,11557,-30661,11510,-30679,11463,-30697,11416,-30714,11369,-30732,11322,-30749,11275,-30767,11227,-30784,11180,-30801,11133,-30818,11086,-30835,11038,-30852,10991,-30869,10944,-30886,10896,-30903,10849,-30919,10801,-30936,10754,-30952,10706,-30969,10659,-30985,10611,-31002,10564,-31018,10516,-31034,10469,-31050,10421,-31066,10373,-31082,10326,-31098,10278,-31114,10230,-31129,10182,-31145,10135,-31161,10087,-31176,10039,-31192,9991,-31207,9943,-31222,9895,-31237,9847,-31253,9799,-31268,9751,-31283,9703,-31298,9655,-31312,9607,-31327,9559,-31342,9511,-31357,9463,-31371,9415,-31386,9367,-31400,9319,-31414,9270,-31429,9222,-31443,9174,-31457,9126,-31471,9077,-31485,9029,-31499,8981,-31513,8932,-31526,8884,-31540,8836,-31554,8787,-31567,8739,-31581,8690,-31594,8642,-31607,8593,-31620,8545,-31634,8496,-31647,8448,-31660,8399,-31673,8351,-31685,8302,-31698,8253,-31711,8205,-31724,8156,-31736,8107,-31749,8059,-31761,8010,-31773,7961,-31786,7912,-31798,7864,-31810,7815,-31822,7766,-31834,7717,-31846,7668,-31857,7619,-31869,7571,-31881,7522,-31892,7473,-31904,7424,-31915,7375,-31927,7326,-31938,7277,-31949,7228,-31960,7179,-31971,7130,-31982,7081,-31993,7032,-32004,6982,-32015,6933,-32025,6884,-32036,6835,-32047,6786,-32057,6737,-32067,6688,-32078,6638,-32088,6589,-32098,6540,-32108,6491,-32118,6441,-32128,6392,-32138,6343,-32148,6293,-32157,6244,-32167,6195,-32177,6145,-32186,6096,-32195,6047,-32205,5997,-32214,5948,-32223,5898,-32232,5849,-32241,5799,-32250,5750,-32259,5700,-32268,5651,-32276,5601,-32285,5552,-32294,5502,-32302,5453,-32311,5403,-32319,5354,-32327,5304,-32335,5254,-32343,5205,-32351,5155,-32359,5106,-32367,5056,-32375,5006,-32383,4957,-32390,4907,-32398,4857,-32405,4807,-32413,4758,-32420,4708,-32427,4658,-32435,4608,-32442,4559,-32449,4509,-32456,4459,-32463,4409,-32469,4359,-32476,4310,-32483,4260,-32489,4210,-32496,4160,-32502,4110,-32509,4060,-32515,4011,-32521,3961,-32527,3911,-32533,3861,-32539,3811,-32545,3761,-32551,3711,-32557,3661,-32562,3611,-32568,3561,-32573,3511,-32579,3461,-32584,3411,-32589,3361,-32595,3311,-32600,3261,-32605,3211,-32610,3161,-32615,3111,-32619,3061,-32624,3011,-32629,2961,-32633,2911,-32638,2861,-32642,2811,-32647,2761,-32651,2711,-32655,2661,-32659,2610,-32663,2560,-32667,2510,-32671,2460,-32675,2410,-32679,2360,-32682,2310,-32686,2260,-32689,2209,-32693,2159,-32696,2109,-32700,2059,-32703,2009,-32706,1959,-32709,1908,-32712,1858,-32715,1808,-32718,1758,-32720,1708,-32723,1658,-32726,1607,-32728,1557,-32730,1507,-32733,1457,-32735,1406,-32737,1356,-32739,1306,-32741,1256,-32743,1206,-32745,1155,-32747,1105,-32749,1055,-32751,1005,-32752,954,-32754,904,-32755,854,-32756,804,-32758,753,-32759,703,-32760,653,-32761,603,-32762,552,-32763,502,-32764,452,-32764,402,-32765,351,-32766,301,-32766,251,-32767,201,-32767,150,-32767,100,-32767,50,-32767,0,-32767,-51,-32767,-101,-32767,-151,-32767,-202,-32767,-252,-32767,-302,-32766,-352,-32766,-403,-32765,-453,-32764,-503,-32764,-553,-32763,-604,-32762,-654,-32761,-704,-32760,-754,-32759,-805,-32758,-855,-32756,-905,-32755,-955,-32754,-1006,-32752,-1056,-32751,-1106,-32749,-1156,-32747,-1207,-32745,-1257,-32743,-1307,-32741,-1357,-32739,-1407,-32737,-1458,-32735,-1508,-32733,-1558,-32730,-1608,-32728,-1659,-32726,-1709,-32723,-1759,-32720,-1809,-32718,-1859,-32715,-1909,-32712,-1960,-32709,-2010,-32706,-2060,-32703,-2110,-32700,-2160,-32696,-2210,-32693,-2261,-32689,-2311,-32686,-2361,-32682,-2411,-32679,-2461,-32675,-2511,-32671,-2561,-32667,-2611,-32663,-2662,-32659,-2712,-32655,-2762,-32651,-2812,-32647,-2862,-32642,-2912,-32638,-2962,-32633,-3012,-32629,-3062,-32624,-3112,-32619,-3162,-32615,-3212,-32610,-3262,-32605,-3312,-32600,-3362,-32595,-3412,-32589,-3462,-32584,-3512,-32579,-3562,-32573,-3612,-32568,-3662,-32562,-3712,-32557,-3762,-32551,-3812,-32545,-3862,-32539,-3912,-32533,-3962,-32527,-4012,-32521,-4061,-32515,-4111,-32509,-4161,-32502,-4211,-32496,-4261,-32489,-4311,-32483,-4360,-32476,-4410,-32469,-4460,-32463,-4510,-32456,-4560,-32449,-4609,-32442,-4659,-32435,-4709,-32427,-4759,-32420,-4808,-32413,-4858,-32405,-4908,-32398,-4958,-32390,-5007,-32383,-5057,-32375,-5107,-32367,-5156,-32359,-5206,-32351,-5255,-32343,-5305,-32335,-5355,-32327,-5404,-32319,-5454,-32311,-5503,-32302,-5553,-32294,-5602,-32285,-5652,-32276,-5701,-32268,-5751,-32259,-5800,-32250,-5850,-32241,-5899,-32232,-5949,-32223,-5998,-32214,-6048,-32205,-6097,-32195,-6146,-32186,-6196,-32177,-6245,-32167,-6294,-32157,-6344,-32148,-6393,-32138,-6442,-32128,-6492,-32118,-6541,-32108,-6590,-32098,-6639,-32088,-6689,-32078,-6738,-32067,-6787,-32057,-6836,-32047,-6885,-32036,-6934,-32025,-6983,-32015,-7033,-32004,-7082,-31993,-7131,-31982,-7180,-31971,-7229,-31960,-7278,-31949,-7327,-31938,-7376,-31927,-7425,-31915,-7474,-31904,-7523,-31892,-7572,-31881,-7620,-31869,-7669,-31857,-7718,-31846,-7767,-31834,-7816,-31822,-7865,-31810,-7913,-31798,-7962,-31786,-8011,-31773,-8060,-31761,-8108,-31749,-8157,-31736,-8206,-31724,-8254,-31711,-8303,-31698,-8352,-31685,-8400,-31673,-8449,-31660,-8497,-31647,-8546,-31634,-8594,-31620,-8643,-31607,-8691,-31594,-8740,-31581,-8788,-31567,-8837,-31554,-8885,-31540,-8933,-31526,-8982,-31513,-9030,-31499,-9078,-31485,-9127,-31471,-9175,-31457,-9223,-31443,-9271,-31429,-9320,-31414,-9368,-31400,-9416,-31386,-9464,-31371,-9512,-31357,-9560,-31342,-9608,-31327,-9656,-31312,-9704,-31298,-9752,-31283,-9800,-31268,-9848,-31253,-9896,-31237,-9944,-31222,-9992,-31207,-10040,-31192,-10088,-31176,-10136,-31161,-10183,-31145,-10231,-31129,-10279,-31114,-10327,-31098,-10374,-31082,-10422,-31066,-10470,-31050,-10517,-31034,-10565,-31018,-10612,-31002,-10660,-30985,-10707,-30969,-10755,-30952,-10802,-30936,-10850,-30919,-10897,-30903,-10945,-30886,-10992,-30869,-11039,-30852,-11087,-30835,-11134,-30818,-11181,-30801,-11228,-30784,-11276,-30767,-11323,-30749,-11370,-30732,-11417,-30714,-11464,-30697,-11511,-30679,-11558,-30661,-11605,-30644,-11652,-30626,-11699,-30608,-11746,-30590,-11793,-30572,-11840,-30554,-11887,-30536,-11934,-30517,-11981,-30499,-12027,-30481,-12074,-30462,-12121,-30443,-12167,-30425,-12214,-30406,-12261,-30387,-12307,-30369,-12354,-30350,-12400,-30331,-12447,-30312,-12493,-30292,-12540,-30273,-12586,-30254,-12633,-30235,-12679,-30215,-12725,-30196,-12772,-30176,-12818,-30157,-12864,-30137,-12910,-30117,-12957,-30097,-13003,-30077,-13049,-30057,-13095,-30037,-13141,-30017,-13187,-29997,-13233,-29977,-13279,-29956,-13325,-29936,-13371,-29916,-13417,-29895,-13463,-29874,-13508,-29854,-13554,-29833,-13600,-29812,-13646,-29791,-13691,-29770,-13737,-29749,-13783,-29728,-13828,-29707,-13874,-29686,-13919,-29664,-13965,-29643,-14010,-29622,-14056,-29600,-14101,-29578,-14146,-29557,-14192,-29535,-14237,-29513,-14282,-29491,-14327,-29469,-14373,-29447,-14418,-29425,-14463,-29403,-14508,-29381,-14553,-29359,-14598,-29336,-14643,-29314,-14688,-29291,-14733,-29269,-14778,-29246,-14823,-29223,-14867,-29201,-14912,-29178,-14957,-29155,-15002,-29132,-15046,-29109,-15091,-29086,-15136,-29063,-15180,-29039,-15225,-29016,-15269,-28993,-15314,-28969,-15358,-28946,-15402,-28922,-15447,-28898,-15491,-28875,-15535,-28851,-15580,-28827,-15624,-28803,-15668,-28779,-15712,-28755,-15756,-28731,-15800,-28707,-15844,-28682,-15888,-28658,-15932,-28634,-15976,-28609,-16020,-28585,-16064,-28560,-16108,-28535,-16151,-28511,-16195,-28486,-16239,-28461,-16282,-28436,-16326,-28411,-16369,-28386,-16413,-28361,-16456,-28336,-16500,-28310,-16543,-28285,-16587,-28260,-16630,-28234,-16673,-28209,-16717,-28183,-16760,-28157,-16803,-28132,-16846,-28106,-16889,-28080,-16932,-28054,-16975,-28028,-17018,-28002,-17061,-27976,-17104,-27949,-17147,-27923,-17190,-27897,-17233,-27870,-17275,-27844,-17318,-27817,-17361,-27791,-17403,-27764,-17446,-27737,-17488,-27711,-17531,-27684,-17573,-27657,-17616,-27630,-17658,-27603,-17700,-27576,-17743,-27549,-17785,-27521,-17827,-27494,-17869,-27467,-17911,-27439,-17953,-27412,-17995,-27384,-18037,-27356,-18079,-27329,-18121,-27301,-18163,-27273,-18205,-27245,-18247,-27217,-18288,-27189,-18330,-27161,-18372,-27133,-18413,-27105,-18455,-27077,-18496,-27048,-18538,-27020,-18579,-26991,-18621,-26963,-18662,-26934,-18703,-26906,-18745,-26877,-18786,-26848,-18827,-26819,-18868,-26790,-18909,-26761,-18950,-26732,-18991,-26703,-19032,-26674,-19073,-26645,-19114,-26616,-19155,-26586,-19195,-26557,-19236,-26527,-19277,-26498,-19317,-26468,-19358,-26438,-19398,-26409,-19439,-26379,-19479,-26349,-19520,-26319,-19560,-26289,-19600,-26259,-19641,-26229,-19681,-26199,-19721,-26169,-19761,-26138,-19801,-26108,-19841,-26078,-19881,-26047,-19921,-26017,-19961,-25986,-20001,-25955,-20041,-25925,-20080,-25894,-20120,-25863,-20160,-25832,-20199,-25801,-20239,-25770,-20278,-25739,-20318,-25708,-20357,-25677,-20397,-25646,-20436,-25614,-20475,-25583,-20514,-25551,-20554,-25520,-20593,-25488,-20632,-25457,-20671,-25425,-20710,-25393,-20749,-25362,-20788,-25330,-20826,-25298,-20865,-25266,-20904,-25234,-20943,-25202,-20981,-25170,-21020,-25137,-21058,-25105,-21097,-25073,-21135,-25040,-21174,-25008,-21212,-24975,-21250,-24943,-21289,-24910,-21327,-24878,-21365,-24845,-21403,-24812,-21441,-24779,-21479,-24746,-21517,-24713,-21555,-24680,-21593,-24647,-21630,-24614,-21668,-24581,-21706,-24547,-21744,-24514,-21781,-24481,-21819,-24447,-21856,-24414,-21894,-24380,-21931,-24347,-21968,-24313,-22005,-24279,-22043,-24245,-22080,-24212,-22117,-24178,-22154,-24144,-22191,-24110,-22228,-24076,-22265,-24042,-22302,-24007,-22339,-23973,-22375,-23939,-22412,-23904,-22449,-23870,-22485,-23836,-22522,-23801,-22558,-23767,-22595,-23732,-22631,-23697,-22667,-23662,-22704,-23628,-22740,-23593,-22776,-23558,-22812,-23523,-22848,-23488,-22884,-23453,-22920,-23418,-22956,-23383,-22992,-23347,-23028,-23312,-23063,-23277,-23099,-23241,-23135,-23206,-23170,-23170,-23206,-23135,-23241,-23099,-23277,-23063,-23312,-23028,-23347,-22992,-23383,-22956,-23418,-22920,-23453,-22884,-23488,-22848,-23523,-22812,-23558,-22776,-23593,-22740,-23628,-22704,-23662,-22667,-23697,-22631,-23732,-22595,-23767,-22558,-23801,-22522,-23836,-22485,-23870,-22449,-23904,-22412,-23939,-22375,-23973,-22339,-24007,-22302,-24042,-22265,-24076,-22228,-24110,-22191,-24144,-22154,-24178,-22117,-24212,-22080,-24245,-22043,-24279,-22005,-24313,-21968,-24347,-21931,-24380,-21894,-24414,-21856,-24447,-21819,-24481,-21781,-24514,-21744,-24547,-21706,-24581,-21668,-24614,-21630,-24647,-21593,-24680,-21555,-24713,-21517,-24746,-21479,-24779,-21441,-24812,-21403,-24845,-21365,-24878,-21327,-24910,-21289,-24943,-21250,-24975,-21212,-25008,-21174,-25040,-21135,-25073,-21097,-25105,-21058,-25137,-21020,-25170,-20981,-25202,-20943,-25234,-20904,-25266,-20865,-25298,-20826,-25330,-20788,-25362,-20749,-25393,-20710,-25425,-20671,-25457,-20632,-25488,-20593,-25520,-20554,-25551,-20514,-25583,-20475,-25614,-20436,-25646,-20397,-25677,-20357,-25708,-20318,-25739,-20278,-25770,-20239,-25801,-20199,-25832,-20160,-25863,-20120,-25894,-20080,-25925,-20041,-25955,-20001,-25986,-19961,-26017,-19921,-26047,-19881,-26078,-19841,-26108,-19801,-26138,-19761,-26169,-19721,-26199,-19681,-26229,-19641,-26259,-19600,-26289,-19560,-26319,-19520,-26349,-19479,-26379,-19439,-26409,-19398,-26438,-19358,-26468,-19317,-26498,-19277,-26527,-19236,-26557,-19195,-26586,-19155,-26616,-19114,-26645,-19073,-26674,-19032,-26703,-18991,-26732,-18950,-26761,-18909,-26790,-18868,-26819,-18827,-26848,-18786,-26877,-18745,-26906,-18703,-26934,-18662,-26963,-18621,-26991,-18579,-27020,-18538,-27048,-18496,-27077,-18455,-27105,-18413,-27133,-18372,-27161,-18330,-27189,-18288,-27217,-18247,-27245,-18205,-27273,-18163,-27301,-18121,-27329,-18079,-27356,-18037,-27384,-17995,-27412,-17953,-27439,-17911,-27467,-17869,-27494,-17827,-27521,-17785,-27549,-17743,-27576,-17700,-27603,-17658,-27630,-17616,-27657,-17573,-27684,-17531,-27711,-17488,-27737,-17446,-27764,-17403,-27791,-17361,-27817,-17318,-27844,-17275,-27870,-17233,-27897,-17190,-27923,-17147,-27949,-17104,-27976,-17061,-28002,-17018,-28028,-16975,-28054,-16932,-28080,-16889,-28106,-16846,-28132,-16803,-28157,-16760,-28183,-16717,-28209,-16673,-28234,-16630,-28260,-16587,-28285,-16543,-28310,-16500,-28336,-16456,-28361,-16413,-28386,-16369,-28411,-16326,-28436,-16282,-28461,-16239,-28486,-16195,-28511,-16151,-28535,-16108,-28560,-16064,-28585,-16020,-28609,-15976,-28634,-15932,-28658,-15888,-28682,-15844,-28707,-15800,-28731,-15756,-28755,-15712,-28779,-15668,-28803,-15624,-28827,-15580,-28851,-15535,-28875,-15491,-28898,-15447,-28922,-15402,-28946,-15358,-28969,-15314,-28993,-15269,-29016,-15225,-29039,-15180,-29063,-15136,-29086,-15091,-29109,-15046,-29132,-15002,-29155,-14957,-29178,-14912,-29201,-14867,-29223,-14823,-29246,-14778,-29269,-14733,-29291,-14688,-29314,-14643,-29336,-14598,-29359,-14553,-29381,-14508,-29403,-14463,-29425,-14418,-29447,-14373,-29469,-14327,-29491,-14282,-29513,-14237,-29535,-14192,-29557,-14146,-29578,-14101,-29600,-14056,-29622,-14010,-29643,-13965,-29664,-13919,-29686,-13874,-29707,-13828,-29728,-13783,-29749,-13737,-29770,-13691,-29791,-13646,-29812,-13600,-29833,-13554,-29854,-13508,-29874,-13463,-29895,-13417,-29916,-13371,-29936,-13325,-29956,-13279,-29977,-13233,-29997,-13187,-30017,-13141,-30037,-13095,-30057,-13049,-30077,-13003,-30097,-12957,-30117,-12910,-30137,-12864,-30157,-12818,-30176,-12772,-30196,-12725,-30215,-12679,-30235,-12633,-30254,-12586,-30273,-12540,-30292,-12493,-30312,-12447,-30331,-12400,-30350,-12354,-30369,-12307,-30387,-12261,-30406,-12214,-30425,-12167,-30443,-12121,-30462,-12074,-30481,-12027,-30499,-11981,-30517,-11934,-30536,-11887,-30554,-11840,-30572,-11793,-30590,-11746,-30608,-11699,-30626,-11652,-30644,-11605,-30661,-11558,-30679,-11511,-30697,-11464,-30714,-11417,-30732,-11370,-30749,-11323,-30767,-11276,-30784,-11228,-30801,-11181,-30818,-11134,-30835,-11087,-30852,-11039,-30869,-10992,-30886,-10945,-30903,-10897,-30919,-10850,-30936,-10802,-30952,-10755,-30969,-10707,-30985,-10660,-31002,-10612,-31018,-10565,-31034,-10517,-31050,-10470,-31066,-10422,-31082,-10374,-31098,-10327,-31114,-10279,-31129,-10231,-31145,-10183,-31161,-10136,-31176,-10088,-31192,-10040,-31207,-9992,-31222,-9944,-31237,-9896,-31253,-9848,-31268,-9800,-31283,-9752,-31298,-9704,-31312,-9656,-31327,-9608,-31342,-9560,-31357,-9512,-31371,-9464,-31386,-9416,-31400,-9368,-31414,-9320,-31429,-9271,-31443,-9223,-31457,-9175,-31471,-9127,-31485,-9078,-31499,-9030,-31513,-8982,-31526,-8933,-31540,-8885,-31554,-8837,-31567,-8788,-31581,-8740,-31594,-8691,-31607,-8643,-31620,-8594,-31634,-8546,-31647,-8497,-31660,-8449,-31673,-8400,-31685,-8352,-31698,-8303,-31711,-8254,-31724,-8206,-31736,-8157,-31749,-8108,-31761,-8060,-31773,-8011,-31786,-7962,-31798,-7913,-31810,-7865,-31822,-7816,-31834,-7767,-31846,-7718,-31857,-7669,-31869,-7620,-31881,-7572,-31892,-7523,-31904,-7474,-31915,-7425,-31927,-7376,-31938,-7327,-31949,-7278,-31960,-7229,-31971,-7180,-31982,-7131,-31993,-7082,-32004,-7033,-32015,-6983,-32025,-6934,-32036,-6885,-32047,-6836,-32057,-6787,-32067,-6738,-32078,-6689,-32088,-6639,-32098,-6590,-32108,-6541,-32118,-6492,-32128,-6442,-32138,-6393,-32148,-6344,-32157,-6294,-32167,-6245,-32177,-6196,-32186,-6146,-32195,-6097,-32205,-6048,-32214,-5998,-32223,-5949,-32232,-5899,-32241,-5850,-32250,-5800,-32259,-5751,-32268,-5701,-32276,-5652,-32285,-5602,-32294,-5553,-32302,-5503,-32311,-5454,-32319,-5404,-32327,-5355,-32335,-5305,-32343,-5255,-32351,-5206,-32359,-5156,-32367,-5107,-32375,-5057,-32383,-5007,-32390,-4958,-32398,-4908,-32405,-4858,-32413,-4808,-32420,-4759,-32427,-4709,-32435,-4659,-32442,-4609,-32449,-4560,-32456,-4510,-32463,-4460,-32469,-4410,-32476,-4360,-32483,-4311,-32489,-4261,-32496,-4211,-32502,-4161,-32509,-4111,-32515,-4061,-32521,-4012,-32527,-3962,-32533,-3912,-32539,-3862,-32545,-3812,-32551,-3762,-32557,-3712,-32562,-3662,-32568,-3612,-32573,-3562,-32579,-3512,-32584,-3462,-32589,-3412,-32595,-3362,-32600,-3312,-32605,-3262,-32610,-3212,-32615,-3162,-32619,-3112,-32624,-3062,-32629,-3012,-32633,-2962,-32638,-2912,-32642,-2862,-32647,-2812,-32651,-2762,-32655,-2712,-32659,-2662,-32663,-2611,-32667,-2561,-32671,-2511,-32675,-2461,-32679,-2411,-32682,-2361,-32686,-2311,-32689,-2261,-32693,-2210,-32696,-2160,-32700,-2110,-32703,-2060,-32706,-2010,-32709,-1960,-32712,-1909,-32715,-1859,-32718,-1809,-32720,-1759,-32723,-1709,-32726,-1659,-32728,-1608,-32730,-1558,-32733,-1508,-32735,-1458,-32737,-1407,-32739,-1357,-32741,-1307,-32743,-1257,-32745,-1207,-32747,-1156,-32749,-1106,-32751,-1056,-32752,-1006,-32754,-955,-32755,-905,-32756,-855,-32758,-805,-32759,-754,-32760,-704,-32761,-654,-32762,-604,-32763,-553,-32764,-503,-32764,-453,-32765,-403,-32766,-352,-32766,-302,-32767,-252,-32767,-202,-32767,-151,-32767,-101,-32767,-51}; - diff --git a/openair1/PHY/MODULATION/modulation_extern.h b/openair1/PHY/MODULATION/modulation_extern.h index 2834aa00f503113987b5fa27a52f631ff1d235c5..417ae5781be75e02c4ab71a1d35a9bc1284568f6 100644 --- a/openair1/PHY/MODULATION/modulation_extern.h +++ b/openair1/PHY/MODULATION/modulation_extern.h @@ -1,38 +1,44 @@ /* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software -; * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at -extern int16_t s6n_kHz_7_5[1920]; -extern int16_t s6e_kHz_7_5[1920]; -extern int16_t s15n_kHz_7_5[3840]; -extern int16_t s15e_kHz_7_5[3840]; -extern int16_t s25n_kHz_7_5[7680]; -extern int16_t s25e_kHz_7_5[7680]; -extern int16_t s50n_kHz_7_5[15360]; -extern int16_t s50e_kHz_7_5[15360]; -extern int16_t s75n_kHz_7_5[23040]; -extern int16_t s75e_kHz_7_5[23040]; -extern int16_t s100n_kHz_7_5[30720]; -extern int16_t s100e_kHz_7_5[30720]; + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + ; * distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ------------------------------------------------------------------------------- + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org +*/ +#ifdef __cplusplus +extern "C" { +#endif + +extern int16_t *s6n_kHz_7_5; +extern int16_t *s6e_kHz_7_5; +extern int16_t *s15n_kHz_7_5; +extern int16_t *s15e_kHz_7_5; +extern int16_t *s25n_kHz_7_5; +extern int16_t *s25e_kHz_7_5; +extern int16_t *s50n_kHz_7_5; +extern int16_t *s50e_kHz_7_5; +extern int16_t *s75n_kHz_7_5; +extern int16_t *s75e_kHz_7_5; +extern int16_t *s100n_kHz_7_5; +extern int16_t *s100e_kHz_7_5; extern short conjugate75[8]; extern short conjugate75_2[8]; extern short negate[8]; +#ifdef __cplusplus +} +#endif diff --git a/openair1/PHY/MODULATION/modulation_vars.h b/openair1/PHY/MODULATION/modulation_vars.h index dbea92ab3f5e3e9998bab0bb417a8e7a11c629eb..1428d5f9750388183d0f980caca2eb12d608f982 100644 --- a/openair1/PHY/MODULATION/modulation_vars.h +++ b/openair1/PHY/MODULATION/modulation_vars.h @@ -19,7 +19,6 @@ * contact@openairinterface.org */ -#include "kHz_7_5.h" short conjugate75[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; short conjugate75_2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index e7a7f1a2592a4b1bc24a0763532b0795c1778c48..45373ab9e2ac57f768c59f2a80e20123062587fc 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -3097,10 +3097,10 @@ void dft128(int16_t *x,int16_t *y,int scale) dft64((int16_t*)(xtmp),(int16_t*)ytmp,1); dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1); - - /* LOG_M("dft128a.m","dfta",ytmp,64,1,1); - LOG_M("dft128b.m","dftb",ytmp+16,64,1,1);*/ - + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft128a.m","dfta",ytmp,64,1,1); + LOG_M("dft128b.m","dftb",ytmp+16,64,1,1); + } for (i=0; i<16; i++) { bfly2_16(ytmpp,ytmpp+16, y128p,y128p+16, @@ -3149,9 +3149,10 @@ void dft128(int16_t *x,int16_t *y,int scale) } - - /* LOG_M("dft128out.m","dft128",y,128,1,1); - exit(-1);*/ + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft128out.m","dft128",y,128,1,1); + exit(-1); + } _mm_empty(); _m_empty(); @@ -3176,17 +3177,17 @@ void dft128(int16_t *x,int16_t *y,int scale) transpose4_ooff_simd256(x256+10,xtmp+5,8); transpose4_ooff_simd256(x256+12,xtmp+6,8); transpose4_ooff_simd256(x256+14,xtmp+7,8); - - /* LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1); - LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1); - */ + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1); + LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1); + } dft64((int16_t*)(xtmp),(int16_t*)ytmp,1); dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1); - - /*LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1); - LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1); - */ + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1); + LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1); + } for (i=0; i<8; i++) { bfly2_16_256(ytmpp,ytmpp+8, @@ -3219,9 +3220,10 @@ void dft128(int16_t *x,int16_t *y,int scale) y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256); } - - /* LOG_M("dft128.m","dft",y256,128,1,1); - exit(-1);*/ + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft128.m","dft",y256,128,1,1); + exit(-1); + } } #endif @@ -5422,10 +5424,11 @@ void dft1536(int16_t *input, int16_t *output, int scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ - - // LOG_M("out0.m","o0",tmpo[0],2048,1,1); - // LOG_M("out1.m","o1",tmpo[1],2048,1,1); - // LOG_M("out2.m","o2",tmpo[2],2048,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft1536out0.m","o0",tmpo[0],2048,1,1); + LOG_M("dft1536out1.m","o1",tmpo[1],2048,1,1); + LOG_M("dft1536out2.m","o2",tmpo[2],2048,1,1); + } for (i=0,i2=0; i<1024; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i), @@ -5585,12 +5588,20 @@ void idft6144(int16_t *input, int16_t *output,int scale) idft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); idft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("idft6144in.m","in",input,6144,1,1); + LOG_M("idft6144out0.m","o0",tmpo[0],2048,1,1); + LOG_M("idft6144out1.m","o1",tmpo[1],2048,1,1); + LOG_M("idft6144out2.m","o2",tmpo[2],2048,1,1); + } + for (i=0,i2=0; i<4096; i+=8,i2+=4) { ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i), (simd_q15_t*)(twa6144+i),(simd_q15_t*)(twb6144+i)); } + if (scale==1) { for (i=0; i<96; i++) { y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128); @@ -5643,10 +5654,11 @@ void dft6144(int16_t *input, int16_t *output,int scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ - - // LOG_M("out0.m","o0",tmpo[0],2048,1,1); - // LOG_M("out1.m","o1",tmpo[1],2048,1,1); - // LOG_M("out2.m","o2",tmpo[2],2048,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("ft6144out0.m","o0",tmpo[0],2048,1,1); + LOG_M("ft6144out1.m","o1",tmpo[1],2048,1,1); + LOG_M("ft6144out2.m","o2",tmpo[2],2048,1,1); + } for (i=0,i2=0; i<4096; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i), @@ -5707,10 +5719,11 @@ void dft12288(int16_t *input, int16_t *output,int scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ - - // LOG_M("out0.m","o0",tmpo[0],4096,1,1); - // LOG_M("out1.m","o1",tmpo[1],4096,1,1); - // LOG_M("out2.m","o2",tmpo[2],4096,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft12288out0.m","o0",tmpo[0],4096,1,1); + LOG_M("dft12288out1.m","o1",tmpo[1],4096,1,1); + LOG_M("dft12288out2.m","o2",tmpo[2],4096,1,1); + } for (i=0,i2=0; i<8192; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i), @@ -5758,9 +5771,18 @@ void idft12288(int16_t *input, int16_t *output,int scale) } + idft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale); idft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale); idft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale); + + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("idft12288in.m","in",input,12288,1,1); + LOG_M("idft12288out0.m","o0",tmpo[0],4096,1,1); + LOG_M("idft12288out1.m","o1",tmpo[1],4096,1,1); + LOG_M("idft12288out2.m","o2",tmpo[2],4096,1,1); + } + for (i=0,i2=0; i<8192; i+=8,i2+=4) { ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i), @@ -5790,8 +5812,9 @@ void idft12288(int16_t *input, int16_t *output,int scale) } _mm_empty(); _m_empty(); - - // LOG_M("out.m","out",output,6144,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("idft12288out.m","out",output,6144,1,1); + } } int16_t twa18432[12288] __attribute__((aligned(32))); @@ -5920,16 +5943,18 @@ void dft24576(int16_t *input, int16_t *output,int scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ - - // LOG_M("out0.m","o0",tmpo[0],8192,1,1); - // LOG_M("out1.m","o1",tmpo[1],8192,1,1); - // LOG_M("out2.m","o2",tmpo[2],8192,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft24576out0.m","o0",tmpo[0],8192,1,1); + LOG_M("dft24576out1.m","o1",tmpo[1],8192,1,1); + LOG_M("dft24576out2.m","o2",tmpo[2],8192,1,1); + } for (i=0,i2=0; i<16384; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i), (simd_q15_t*)(twa24576+i),(simd_q15_t*)(twb24576+i)); } + if (scale==1) { for (i=0; i<384; i++) { y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128); @@ -5953,8 +5978,9 @@ void dft24576(int16_t *input, int16_t *output,int scale) } _mm_empty(); _m_empty(); - - // LOG_M("out.m","out",output,24576,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("out.m","out",output,24576,1,1); + } } void idft24576(int16_t *input, int16_t *output,int scale) @@ -5975,12 +6001,12 @@ void idft24576(int16_t *input, int16_t *output,int scale) idft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); idft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); - /* - LOG_M("in.m","in",input,24576,1,1); - LOG_M("out0.m","o0",tmpo[0],8192,1,1); - LOG_M("out1.m","o1",tmpo[1],8192,1,1); - LOG_M("out2.m","o2",tmpo[2],8192,1,1); - */ + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("idft24576in.m","in",input,24576,1,1); + LOG_M("idft24576out0.m","o0",tmpo[0],8192,1,1); + LOG_M("idft24576out1.m","o1",tmpo[1],8192,1,1); + LOG_M("idft24576out2.m","o2",tmpo[2],8192,1,1); + } for (i=0,i2=0; i<16384; i+=8,i2+=4) { ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), @@ -6011,7 +6037,9 @@ void idft24576(int16_t *input, int16_t *output,int scale) _mm_empty(); _m_empty(); - // LOG_M("out.m","out",output,24576,1,1); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("idft24576out.m","out",output,24576,1,1); + } } /// THIS SECTION IS FOR ALL PUSCH DFTS (i.e. radix 2^a * 3^b * 4^c * 5^d) diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index cb7775904099a769091795d62d23cc1b1d950b25..b37f146b0a8eb9b05f4c871f4e8562d0cc1e3afa 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -52,8 +52,8 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){ if (ts->trials>0) { - //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now); - fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000.0)),(double)ts->diff_now); + //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->p_time/(cpu_freq_GHz*1000000.0)),subframe,ts->p_time); + fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->p_time/(cpu_freq_GHz*1000.0)),(double)ts->p_time); } } diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index 32e6883d56f5a7c2fca509b282e8205ef2a04104..eac057095a42d41ef89efc86a090715f9c09292a 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -40,7 +40,6 @@ typedef struct { long long in; long long diff; - long long diff_now; long long p_time; /*!< \brief absolute process duration */ long long diff_square; /*!< \brief process duration square */ long long max; @@ -50,7 +49,6 @@ typedef struct { #elif defined(__arm__) typedef struct { uint32_t in; - uint32_t diff_now; uint32_t diff; uint32_t p_time; /*!< \brief absolute process duration */ uint32_t diff_square; /*!< \brief process duration square */ @@ -116,9 +114,6 @@ static inline void stop_meas(time_stats_t *ts) if (opp_enabled) { long long out = rdtsc_oai(); - ts->diff_now = (out-ts->in); - - ts->diff_now = (out-ts->in); ts->diff += (out-ts->in); /// process duration is the difference between two clock points ts->p_time = (out-ts->in); @@ -135,7 +130,6 @@ static inline void reset_meas(time_stats_t *ts) { ts->trials=0; ts->diff=0; - ts->diff_now=0; ts->p_time=0; ts->diff_square=0; ts->max=0; diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index a5e8d49eb7d95eeeca4120fe5705eeb80fc3df61..6b7e0f559589453a60dfb5ea64117f485c9edc00 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -375,6 +375,7 @@ void dft576(int16_t *x,int16_t *y,uint8_t scale_flag); void dft600(int16_t *x,int16_t *y,uint8_t scale_flag); void dft648(int16_t *x,int16_t *y,uint8_t scale_flag); void dft720(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft768(int16_t *x,int16_t *y,uint8_t scale_flag); void dft864(int16_t *x,int16_t *y,uint8_t scale_flag); void dft900(int16_t *x,int16_t *y,uint8_t scale_flag); void dft960(int16_t *x,int16_t *y,uint8_t scale_flag); diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index bb08d5122dd68033f1c7871a37faabd4a1355a68..8a7c853df55d10fbd148d94077683eabfd873a39 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -52,7 +52,7 @@ # include "COMMON/ral_messages_types.h" # include "UTIL/queue.h" # endif -# include "log.h" +# include "common/utils/LOG/log.h" # define msg(aRGS...) LOG_D(PHY, ##aRGS) # else # define msg printf diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index f079794a34afa069d83032b6f0e20a00353d50e4..55f8c9639ab281316a25784b62f45811c69d9203 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -93,7 +93,7 @@ # include "COMMON/ral_messages_types.h" # include "UTIL/queue.h" # endif -# include "log.h" +# include "common/utils/LOG/log.h" # define msg(aRGS...) LOG_D(PHY, ##aRGS) # else # define msg printf diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index fce7f1b8851ae473ab0037fdcf47845b88a21da9..9a735b038fedd588a06afe665824d02f68d47da0 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -33,7 +33,9 @@ #define __PHY_DEFS_COMMON_H__ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include <sched.h> #include <stdio.h> #include <stdlib.h> @@ -860,7 +862,22 @@ typedef enum { RESYNCH=4 } UE_MODE_t; +/// Threading Parameter +typedef enum { + PARALLEL_SINGLE_THREAD =0, + PARALLEL_RU_L1_SPLIT =1, + PARALLEL_RU_L1_TRX_SPLIT =2 +}PARALLEL_CONF_t; + +typedef enum { + WORKER_DISABLE =0, + WORKER_ENABLE =1 +}WORKER_CONF_t; +typedef struct THREAD_STRUCT_s { + PARALLEL_CONF_t parallel_conf; + WORKER_CONF_t worker_conf; +} THREAD_STRUCT; typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t; @@ -928,7 +945,6 @@ typedef enum { #endif -void exit_fun(const char* s); #include "common/utils/LOG/log_extern.h" extern pthread_cond_t sync_cond; @@ -990,13 +1006,18 @@ static inline void wait_sync(char *thread_name) { pthread_mutex_unlock(&sync_mutex); printf( "got sync (%s)\n", thread_name); - + /* + * Raphael Defosseux: added for CI to get faster the got sync message. + */ + fflush(stdout); + fflush(stderr); } static inline int wakeup_thread(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "wakeup_thread(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } @@ -1013,8 +1034,10 @@ static inline int wakeup_thread(pthread_mutex_t *mutex,pthread_cond_t *cond,int } static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] wait_on_condition(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } @@ -1034,9 +1057,10 @@ static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond, } static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] wait_on_busy_condition(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } @@ -1056,9 +1080,10 @@ static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t * } static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); + int rc; + if ((rc = pthread_mutex_lock(mutex)) != 0) { + LOG_E(PHY, "[SCHED][eNB] release_thread(): error locking mutex for %s (%d %s, %p)\n", + name, rc, strerror(rc), (void *)mutex); exit_fun("nothing to add"); return(-1); } diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index c58fffe0ef2ebe8fa890dbac762dcd4e9bb2a56f..f23485cad84e732ec2459da1ec7c005052b6b74e 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -270,7 +270,6 @@ typedef enum { REMOTE_IF4p5 =3, REMOTE_IF1pp =4, MAX_RU_IF_TYPES =5 - //EMULATE_RF =6 } RU_if_south_t; typedef struct RU_t_s{ diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a6a44c66e27913e30afa90b6b5ac04fd867622f5..276006ec3be58e40a413856efc288d7d9d2f3a43 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -347,7 +347,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, dlsch_harq->rvidx, dlsch_harq->round); } -#if defined(MESSAGE_CHART_GENERATOR_PHY) + MSC_LOG_TX_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, @@ -368,7 +368,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, pmi2hex_2Ar1(dlsch_harq->pmi_alloc), dlsch_harq->rvidx, dlsch_harq->round); -#endif + if (ue_stats) ue_stats->dlsch_sliding_cnt++; @@ -412,7 +412,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, &eNB->dlsch_turbo_encoding_wakeup_stats1, &eNB->dlsch_interleaving_stats); stop_meas(&eNB->dlsch_encoding_stats); - if(eNB->dlsch_encoding_stats.diff_now>500*3000 && opp_enabled == 1) + if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) { print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); } @@ -1337,21 +1337,26 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ret, ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK, - eNB->ulsch_decoding_stats.diff_now, eNB->ulsch_decoding_stats.max); + eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); //compute the expected ULSCH RX power (for the stats) ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered - if (ulsch_harq->cqi_crc_status == 1) { + if (RC.mac != NULL) { /* ulsim dose not use RC.mac context. */ + if (ulsch_harq->cqi_crc_status == 1) { #ifdef DEBUG_PHY_PROC //if (((frame%10) == 0) || (frame < 50)) print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL); #endif - - fill_ulsch_cqi_indication(eNB,frame,subframe, - ulsch_harq, - ulsch->rnti); - + fill_ulsch_cqi_indication(eNB,frame,subframe,ulsch_harq,ulsch->rnti); + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); + } else { + if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ){ + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30; + LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe); + } + } } if (ret == (1+MAX_TURBO_ITERATIONS)) { @@ -1375,7 +1380,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ulsch->harq_mask &= ~(1 << harq_pid); ulsch_harq->round = 0; } -#if defined(MESSAGE_CHART_GENERATOR_PHY) + MSC_LOG_RX_DISCARDED_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, @@ -1384,7 +1389,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ulsch->rnti,harq_pid, ulsch_harq->round-1 ); -#endif + /* Mark the HARQ process to release it later if max transmission reached * (see below). @@ -1403,7 +1408,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti), T_INT(harq_pid)); -#if defined(MESSAGE_CHART_GENERATOR_PHY) + MSC_LOG_RX_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, @@ -1411,7 +1416,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) frame,subframe, ulsch->rnti,harq_pid ); -#endif + #ifdef DEBUG_PHY_PROC #ifdef DEBUG_ULSCH @@ -1604,6 +1609,16 @@ static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,ui dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); +#if T_TRACER + if (after_rounds != -1) { + T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(dlsch0->rnti), T_INT(harq_pid)); + } else { + T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(dlsch0->rnti), T_INT(harq_pid)); + } +#endif + if (dlsch0_harq->round >= after_rounds) { dlsch0_harq->status = SCH_IDLE; /*if ((dlsch1_harq == NULL)|| @@ -1631,6 +1646,15 @@ static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,ui dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); +#if T_TRACER + if (after_rounds != -1) { + T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(dlsch0->rnti), T_INT(harq_pid)); + } else { + T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), + T_INT(dlsch0->rnti), T_INT(harq_pid)); + } +#endif if (dlsch0_harq->round >= after_rounds) { dlsch0_harq->status = SCH_IDLE; if ((dlsch1_harq == NULL)|| @@ -1753,22 +1777,6 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i]; // release DLSCH if needed release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); - - -#if T_TRACER - /* TODO: get correct harq pid */ - { - int subframe_tx = (subframe+6)%10; - int frame_tx = subframe_tx >= 6 ? (frame+1023)%1024 : frame; - if (ulsch_harq->o_ACK[i] != 1) { - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx%2][subframe_tx])); - } else { - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx%2][subframe_tx])); - } - } -#endif } } else { // TDD @@ -1857,21 +1865,6 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; // release DLSCH if needed release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); - - -#if T_TRACER - { - int subframe_tx = (subframe+6)%10; - int frame_tx = subframe_tx >= 6 ? (frame+1023)%1024 : frame; - if (harq_ack[0] != 1) { - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx%2][subframe_tx])); - } else { - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[frame_tx%2][subframe_tx])); - } - } -#endif } else if (uci->pucch_fmt == pucch_format1b) { pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; @@ -2041,16 +2034,15 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; - - T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); - /* TODO: use correct rxdata */ T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), T_BUFFER(&eNB->RU_list[0]->common.rxdata[0][subframe*eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti * 4)); + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; + + T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 ); LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe); @@ -2092,7 +2084,4 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); - - stop_meas(&eNB->phy_proc_rx); - } diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 6272650f72b56b8af9b6cdf78af68603e85e9351..6a2fef68224b07f72edc518507858b57dbd3579a 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -50,10 +50,6 @@ #include "targets/RT/USER/rt_wrapper.h" -// RU OFDM Modulator, used in IF4p5 RRU, RCC/RAU with IF5, eNodeB - -extern openair0_config_t openair0_cfg[MAX_CARDS]; - extern int oai_exit; @@ -160,7 +156,7 @@ static void *feptx_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return NULL; } - /*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.diff_now>30*3000){ + /*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); }*/ @@ -220,7 +216,7 @@ void feptx_ofdm_2thread(RU_t *ru) { start_meas(&ru->ofdm_mod_wait_stats); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); stop_meas(&ru->ofdm_mod_wait_stats); - /*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.diff_now>30*3000){ + /*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 codition in frame_rx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); }*/ @@ -467,7 +463,7 @@ static void *fep_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return NULL; } - /*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){ + /*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); printf("delay in fep wakeup in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); }*/ @@ -582,7 +578,7 @@ void ru_fep_full_2thread(RU_t *ru) { start_meas(&ru->ofdm_demod_wait_stats); wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread"); stop_meas(&ru->ofdm_demod_wait_stats); - if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){ + if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); } diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index ed258ed47c6f0ab6875d15582d5b8879c4b29395..b7d05ba006204fd9cde6456d3e5085353dee8a9a 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -99,77 +99,77 @@ void get_dumpparam(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid) { -LOG_M_BEGIN(DEBUG_UE_PHYPROC) - unsigned int coded_bits_per_codeword; - uint8_t nsymb ; - - get_dumpparam(ue, proc, eNB_id, - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb , - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - subframe, - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm, - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], - &nsymb, &coded_bits_per_codeword); - - LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1); - LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1); - /* - LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1); - LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1); - LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1); - LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1); - */ - LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1); - LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0); + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { + unsigned int coded_bits_per_codeword; + uint8_t nsymb ; + + get_dumpparam(ue, proc, eNB_id, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb , + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + subframe, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + &nsymb, &coded_bits_per_codeword); + + LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1); + LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1); + /* + LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1); + LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1); + LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1); + LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1); + */ + LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1); + LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0); - LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1); - LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1); -LOG_M_END + LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1); + LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1); + } } void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe) { -LOG_M_BEGIN(DEBUG_UE_PHYPROC) - unsigned int coded_bits_per_codeword; - uint8_t nsymb; - - get_dumpparam(ue, proc, eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, - subframe,2,1,0, - &nsymb, &coded_bits_per_codeword); - - LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n", - ue->Mod_id, - ue->frame_parms.ofdm_symbol_size, - nsymb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, - coded_bits_per_codeword); - - LOG_M("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1); - - LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1); - /* - LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1); - LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1); - LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1); - LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1); - */ - LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_SI[0]->rxdataF_comp0[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1); - LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0); - - LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1); - LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1); - sleep(1); - exit(-1); -LOG_M_END + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)){ + unsigned int coded_bits_per_codeword; + uint8_t nsymb; + + get_dumpparam(ue, proc, eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, + subframe,2,1,0, + &nsymb, &coded_bits_per_codeword); + + LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n", + ue->Mod_id, + ue->frame_parms.ofdm_symbol_size, + nsymb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs, + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, + coded_bits_per_codeword); + + LOG_M("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1); + + LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1); + /* + LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1); + LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1); + LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1); + LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1); + */ + LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_SI[0]->rxdataF_comp0[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1); + LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0); + + LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1); + LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1); + sleep(1); + exit(-1); + } } #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) @@ -234,40 +234,40 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe) { -LOG_M_BEGIN(DEBUG_UE_PHYPROC) - unsigned int coded_bits_per_codeword; - uint8_t nsymb ; - - - get_dumpparam(ue, proc, eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, - subframe,2,1,0, - &nsymb, &coded_bits_per_codeword); - - LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n", - ue->Mod_id, - ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs, - ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, - ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, - coded_bits_per_codeword); - - LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1); - LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1); - /* - LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1); - LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1); - LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1); - LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1); - */ - LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1); - LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0); + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)){ + unsigned int coded_bits_per_codeword; + uint8_t nsymb ; + + + get_dumpparam(ue, proc, eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, + subframe,2,1,0, + &nsymb, &coded_bits_per_codeword); + + LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n", + ue->Mod_id, + ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs, + ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, + ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, + coded_bits_per_codeword); + + LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1); + LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1); + /* + LOG_M("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1); + LOG_M("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1); + LOG_M("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1); + LOG_M("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1); + */ + LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1); + LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0); - LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1); - LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1); -LOG_M_END + LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1); + LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1); + } } void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) @@ -362,11 +362,11 @@ void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t ti ue->timing_advance = timing_advance*4; -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { /* TODO: fix this log, what is 'HW timing advance'? */ /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);*/ - LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance); -LOG_DEBUG_END + LOG_UI(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance); + } } @@ -740,17 +740,17 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, } else { bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - if (bundling_flag==bundling) { - LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - } else { - LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + if (bundling_flag==bundling) { + LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, + ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } else { + LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, + ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } } -LOG_DEBUG_END switch (frame_parms->tdd_config) { case 1: // DL:S:UL:UL:DL:DL:S:UL:UL:DL @@ -1226,9 +1226,9 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->ofdm_mod_stats); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_mod_stats); + } nsymb = (frame_parms->Ncp == 0) ? 14 : 12; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case @@ -1345,9 +1345,9 @@ LOG_DEBUG_END } //nb_antennas_tx -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ofdm_mod_stats); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_mod_stats); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT); @@ -1634,30 +1634,30 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - if(ue->ulsch[eNB_id]->o_ACK[0]) - { - LOG_I(PHY,"PUSCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } - else - { - LOG_I(PHY,"PUSCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } - LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", - Mod_id, - ue->ulsch[eNB_id]->rnti, - frame_tx%1024,subframe_tx, - ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + if(ue->ulsch[eNB_id]->o_ACK[0]) + { + LOG_I(PHY,"PUSCH ACK\n"); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } + else + { + LOG_I(PHY,"PUSCH NACK\n"); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } + LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", + Mod_id, + ue->ulsch[eNB_id]->rnti, + frame_tx%1024,subframe_tx, + ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } + } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ LOG_D(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n", @@ -1679,7 +1679,7 @@ LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) ue->ulsch[eNB_id]->bundling, Nbundled, cqi_status, ri_status); -LOG_DEBUG_END + } @@ -1701,9 +1701,9 @@ LOG_DEBUG_END ue->prach_resources[eNB_id]->Msg3[6], ue->prach_resources[eNB_id]->Msg3[7], ue->prach_resources[eNB_id]->Msg3[8]); -LOG_DEBUG_BEGIN(UE_TIMING) + if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ulsch_encoding_stats); -LOG_DEBUG_END + } AssertFatal(ulsch_encoding(ue->prach_resources[eNB_id]->Msg3, ue, @@ -1713,11 +1713,11 @@ LOG_DEBUG_END ue->transmission_mode[eNB_id],0,0)==0, "ulsch_coding.c: FATAL ERROR: returning\n"); -LOG_DEBUG_BEGIN(UE_TIMING) + if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->phy_proc_tx); LOG_UI(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); stop_meas(&ue->ulsch_encoding_stats); -LOG_DEBUG_END + } if (ue->mac_enabled == 1) { @@ -1752,26 +1752,25 @@ LOG_DEBUG_END -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d) (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3); for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++) LOG_T(PHY,"%x.",ulsch_input_buffer[i]); LOG_T(PHY,"\n"); -LOG_DEBUG_END } - else { + } else { unsigned int taus(void); for (i=0; i<input_buffer_length; i++) ulsch_input_buffer[i]= (uint8_t)(taus()&0xff); - } + } -LOG_DEBUG_BEGIN(UE_TIMING) + if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ulsch_encoding_stats); -LOG_DEBUG_END + } if (abstraction_flag==0) { if (ulsch_encoding(ulsch_input_buffer, @@ -1783,16 +1782,16 @@ LOG_DEBUG_END Nbundled)!=0) { LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->phy_proc_tx); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->phy_proc_tx); + } return; } } -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ulsch_encoding_stats); -LOG_DEBUG_END + if(LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ulsch_encoding_stats); + } } if (abstraction_flag == 0) { @@ -1817,13 +1816,13 @@ LOG_DEBUG_END T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_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)); -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", - Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); -LOG_DEBUG_END -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->ulsch_modulation_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); + } + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ulsch_modulation_stats); + } ulsch_modulation(ue->common_vars.txdataF, tx_amp, frame_tx, @@ -1840,9 +1839,9 @@ LOG_DEBUG_END nb_rb, aa); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ulsch_modulation_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ulsch_modulation_stats); + } } @@ -2219,18 +2218,18 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - if(pucch_payload[0]) - { - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + if(pucch_payload[0]) + { + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } + else + { + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } } - else - { - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } -LOG_DEBUG_END generate_pucch1x(ue->common_vars.txdataF, &ue->frame_parms, @@ -2268,15 +2267,15 @@ LOG_DEBUG_END #endif T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx, - Po_PUCCH, - isShortenPucch, - tx_amp); -LOG_DEBUG_END + if( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, subframe_tx, + Po_PUCCH, + isShortenPucch, + tx_amp); + } generate_pucch2x(ue->common_vars.txdataF, &ue->frame_parms, ue->ncs_cell, @@ -2354,9 +2353,9 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui ue->generate_ul_signal[eNB_id] = 0; -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->phy_proc_tx); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->phy_proc_tx); + } ue->tx_power_dBm[subframe_tx]=-127; @@ -2449,9 +2448,9 @@ LOG_DEBUG_END LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->phy_proc_tx); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->phy_proc_tx); + } } void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag) @@ -2516,7 +2515,7 @@ void ue_measurement_procedures( T_INT((int)ue->common_vars.freq_offset)); } - if (l==(6-ue->frame_parms.Ncp)) { + if (( (slot%2) == 0) && (l==(6-ue->frame_parms.Ncp))) { // make sure we have signal from PSS/SSS for N0 measurement // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); @@ -2617,7 +2616,7 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin dummy[0] = ue->pbch_vars[eNB_id]->decoded_output[2]; dummy[1] = ue->pbch_vars[eNB_id]->decoded_output[1]; dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0]; - trace_pdu(1, dummy, 3, ue->Mod_id, 0, 0, + trace_pdu( DIRECTION_DOWNLINK, dummy, WS_C_RNTI, ue->Mod_id, 0, 0, frame_rx, subframe_rx, 0, 0); LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n", ue->Mod_id, subframe_rx); @@ -2693,40 +2692,36 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_UI(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n", - ue->Mod_id, - frame_rx, - subframe_rx, - ue->frame_parms.nb_antenna_ports_eNB, - pbch_tx_ant, - frame_tx, - ue->frame_parms.N_RB_DL, - ue->frame_parms.phich_config_common.phich_duration, - ue->frame_parms.phich_config_common.phich_resource); -LOG_DEBUG_END + LOG_UI(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n", + ue->Mod_id, + frame_rx, + subframe_rx, + ue->frame_parms.nb_antenna_ports_eNB, + pbch_tx_ant, + frame_tx, + ue->frame_parms.N_RB_DL, + ue->frame_parms.phich_config_common.phich_duration, + ue->frame_parms.phich_config_common.phich_resource); + } } else { - /* - LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n", - ue->Mod_id,frame_rx, subframe_rx); - - LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset); + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { + LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n", + ue->Mod_id,frame_rx, subframe_rx); + LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset); - LOG_M("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1); - LOG_M("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); - LOG_M("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); + LOG_M("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1); - LOG_M("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1); - LOG_M("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1); - LOG_M("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4); - exit(-1); - */ + LOG_M("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1); + LOG_M("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1); + LOG_M("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4); + exit(-1); + } ue->pbch_vars[eNB_id]->pdu_errors_conseq++; ue->pbch_vars[eNB_id]->pdu_errors++; @@ -2742,12 +2737,12 @@ LOG_DEBUG_END ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors; } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_UI(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", - ue->Mod_id,frame_rx, subframe_rx, - ue->pbch_vars[eNB_id]->pdu_errors, - ue->pbch_vars[eNB_id]->pdu_errors_conseq); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_UI(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", + ue->Mod_id,frame_rx, subframe_rx, + ue->pbch_vars[eNB_id]->pdu_errors, + ue->pbch_vars[eNB_id]->pdu_errors_conseq); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } @@ -2767,9 +2762,9 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint LOG_D(PHY,"DCI Decoding procedure in %d.%d\n",frame_rx,subframe_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->dlsch_rx_pdcch_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_rx_pdcch_stats); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); rx_pdcch(ue, @@ -2896,17 +2891,17 @@ LOG_DEBUG_END ue->dlsch_received[eNB_id]++; -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); - dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); + dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active); + } // we received a CRNTI, so we're in PUSCH if (ue->UE_mode[eNB_id] != PUSCH) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti); -LOG_DEBUG_END + } //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); ue->UE_mode[eNB_id] = PUSCH; @@ -2921,9 +2916,9 @@ LOG_DEBUG_END ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + } if (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, @@ -2952,9 +2947,9 @@ LOG_DEBUG_END else if ((dci_alloc_rx[i].rnti == P_RNTI) && ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + } if (generate_ue_dlsch_params_from_dci(frame_rx, @@ -2982,18 +2977,18 @@ LOG_DEBUG_END else if ((ue->prach_resources[eNB_id]) && (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) && - (dci_alloc_rx[i].format == format1A)) { + ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + } if (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, - (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu, + (void *)&dci_alloc_rx[i].dci_pdu, ue->prach_resources[eNB_id]->ra_RNTI, - format1A, + dci_alloc_rx[i].format, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], ue->pdsch_vars_ra[eNB_id], &ue->dlsch_ra[eNB_id], @@ -3005,20 +3000,20 @@ LOG_DEBUG_END ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], 0)==0) { - ue->dlsch_ra_received[eNB_id]++; + ue->dlsch_ra_received[eNB_id]++; -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n", - ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n", + ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]); + } } } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) && (dci_alloc_rx[i].format == format0)) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n", - ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n", + ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); + } ue->ulsch_no_allocation_counter[eNB_id] = 0; //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]); @@ -3036,42 +3031,41 @@ LOG_DEBUG_END CBA_RNTI, eNB_id, 0)==0)) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_USEDINLOG_VAR(int8_t,harq_pid) = subframe2harq_pid(&ue->frame_parms, - pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx), - pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx)); - T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), - T_INT(dci_alloc_rx[i].rnti), - T_INT(harq_pid), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); - - LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); -LOG_DEBUG_END - + LOG_USEDINLOG_VAR(int8_t,harq_pid) = subframe2harq_pid(&ue->frame_parms, + pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx), + pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx)); + T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), + T_INT(dci_alloc_rx[i].rnti), + T_INT(harq_pid), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); + + LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); + } } } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) && (dci_alloc_rx[i].format == format0)) { // UE could belong to more than one CBA group // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups] -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n", - ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n", + ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); /* if (((frame_rx%100) == 0) || (frame_rx < 20)) dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); */ -LOG_DEBUG_END + } ue->ulsch_no_allocation_counter[eNB_id] = 0; //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]); if ((ue->UE_mode[eNB_id] > PRACH) && - (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu, + (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu, ue->ulsch[eNB_id]->cba_rnti[0], subframe_rx, format0, @@ -3084,28 +3078,28 @@ LOG_DEBUG_END eNB_id, 0)==0)) { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); -LOG_DEBUG_END - ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++; + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); + } + ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++; } } else { -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, - ue->ulsch[eNB_id]->cba_rnti[0], + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, + ue->ulsch[eNB_id]->cba_rnti[0], dci_alloc_rx[i].format); // dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); -LOG_DEBUG_END + } } } -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_rx_pdcch_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_rx_pdcch_stats); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT); return(0); } @@ -3128,7 +3122,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs // LOG_D(PHY,"ue calling pmch subframe ..\n "); LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", - ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx); + ue->Mod_id,frame_rx,subframe_rx); #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) pmch_mcs = ue_query_mch(ue->Mod_id, @@ -3147,9 +3141,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs); fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0); - for (l=2; l<12; l++) { - slot_fep_mbsfn(ue, l, subframe_rx, @@ -3164,6 +3156,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs } + ue->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(pmch_mcs); + ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, @@ -3177,7 +3171,14 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs 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); - + + 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); + LOG_D(PHY,"start turbo decode for MCH %d.%d --> Nl %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Nl); + 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->frame_parms, @@ -3206,15 +3207,16 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, ue->dlsch_MCH[0]->max_turbo_iterations, ue->dlsch_MCH[0]->harq_processes[0]->G); - dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) + // dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); + + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) { - LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]); - } + for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) { + LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]); + } - LOG_T(PHY,"\n"); -LOG_DEBUG_END + LOG_T(PHY,"\n"); + } // if (subframe_rx==9) @@ -3222,25 +3224,24 @@ LOG_DEBUG_END } else { // decoding successful #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if (mcch_active == 1) { - ue_send_mch_sdu(ue->Mod_id, - CC_id, - frame_rx, - ue->dlsch_MCH[0]->harq_processes[0]->b, - ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, - eNB_id,// not relevant in eMBMS context - sync_area); + ue_send_mch_sdu(ue->Mod_id, + CC_id, + frame_rx, + ue->dlsch_MCH[0]->harq_processes[0]->b, + ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, + eNB_id,// not relevant in eMBMS context + sync_area); + + if (mcch_active == 1) ue->dlsch_mcch_received[sync_area][0]++; - - - if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) { - ue->dlsch_mch_received_sf[subframe_rx%5][0]=0; - } else { - ue->dlsch_mch_received[0]+=1; - ue->dlsch_mch_received_sf[subframe_rx][0]=1; - } - - + else + ue->dlsch_mtch_received[sync_area][0]++; + + if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) { + ue->dlsch_mch_received_sf[subframe_rx%5][0]=0; + } else { + ue->dlsch_mch_received[0]+=1; + ue->dlsch_mch_received_sf[subframe_rx][0]=1; } #endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -3345,12 +3346,12 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC else first_symbol_flag = 0; -LOG_DEBUG_BEGIN(UE_TIMING) - uint8_t slot = 0; - if(m >= ue->frame_parms.symbols_per_tti>>1) + if (LOG_DEBUGFLAG(UE_TIMING)) { + uint8_t slot = 0; + if(m >= ue->frame_parms.symbols_per_tti>>1) slot = 1; - start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); -LOG_DEBUG_END + start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); + } // process DLSCH received in first slot rx_pdsch(ue, pdsch, @@ -3363,13 +3364,13 @@ LOG_DEBUG_END dual_stream_UE, i_mod, dlsch0->current_harq_pid); -LOG_DEBUG_BEGIN(UE_TIMING) - uint8_t slot = 0; - if(m >= ue->frame_parms.symbols_per_tti>>1) - slot = 1; - stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); - LOG_UI(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + uint8_t slot = 0; + if(m >= ue->frame_parms.symbols_per_tti>>1) + slot = 1; + stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); + LOG_UI(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); + } @@ -3564,9 +3565,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, frame_rx, subframe_rx, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->dlsch_unscrambling_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_unscrambling_stats); + } dlsch_unscrambling(&ue->frame_parms, 0, dlsch0, @@ -3574,9 +3575,9 @@ LOG_DEBUG_END pdsch_vars->llr[0], 0, subframe_rx<<1); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_unscrambling_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_unscrambling_stats); + } LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, subframe_rx, harq_pid); LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); @@ -3587,9 +3588,9 @@ LOG_DEBUG_END LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo); LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); + } ret = dlsch_decoding(ue, pdsch_vars->llr[0], &ue->frame_parms, @@ -3601,14 +3602,14 @@ LOG_DEBUG_END pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, " --> Unscrambling for CW0 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", - frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, " --> Unscrambling for CW0 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); -LOG_DEBUG_END + } if(is_cw1_active) { // start turbo decode for CW 1 @@ -3621,9 +3622,9 @@ LOG_DEBUG_END frame_rx, subframe_rx, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->dlsch_unscrambling_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_unscrambling_stats); + } dlsch_unscrambling(&ue->frame_parms, 0, dlsch1, @@ -3631,9 +3632,9 @@ LOG_DEBUG_END pdsch_vars->llr[1], 1, subframe_rx<<1); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_unscrambling_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_unscrambling_stats); + } LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, (uint16_t)((intptr_t)dlsch1->harq_processes[harq_pid]->rb_alloc_even)); @@ -3643,9 +3644,9 @@ LOG_DEBUG_END LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo); LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); + } ret1 = dlsch_decoding(ue, pdsch_vars->llr[1], @@ -3658,13 +3659,13 @@ LOG_DEBUG_END pdsch==PDSCH?1:0, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, " --> Unscrambling for CW1 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", - frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, " --> Unscrambling for CW1 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); + } LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); @@ -3703,15 +3704,15 @@ LOG_DEBUG_END dlsch0->harq_processes[harq_pid]->TBS); } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - int j; - LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid); + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ + int j; + LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid); - for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++) - LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]); + for (j=0; j<dlsch0->harq_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"); -LOG_DEBUG_END + LOG_T(PHY,"\n"); + } if (ue->mac_enabled == 1) { @@ -3804,26 +3805,26 @@ LOG_DEBUG_END } } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n", - ue->Mod_id, - dlsch0->rnti,harq_pid, - frame_rx,subframe_rx,ret, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->TBS); - - if (frame_rx%100==0) { - LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n", - ue->Mod_id,dlsch0->rnti, - frame_rx,subframe_rx, - ue->dlsch_errors[eNB_id], - ue->dlsch_received[eNB_id], - ue->dlsch_fer[eNB_id], - ue->measurements.wideband_cqi_tot[eNB_id]); - } + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n", + ue->Mod_id, + dlsch0->rnti,harq_pid, + frame_rx,subframe_rx,ret, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->TBS); + + if (frame_rx%100==0) { + LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n", + ue->Mod_id,dlsch0->rnti, + frame_rx,subframe_rx, + ue->dlsch_errors[eNB_id], + ue->dlsch_received[eNB_id], + ue->dlsch_fer[eNB_id], + ue->measurements.wideband_cqi_tot[eNB_id]); + } -LOG_DEBUG_END + } /*LOG_DEBUGFLAG(DEBUG_UE_PHYPROC) */ } @@ -3909,9 +3910,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { } /**** Slot1 FE Processing ****/ -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); + } // I- start dl slot1 processing // do first symbol of next downlink subframe for channel estimation /* @@ -3936,9 +3937,9 @@ LOG_DEBUG_END { //if( (l != pilot0) && (l != pilot1)) { -LOG_DEBUG_BEGIN(UE_TIMING) + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l); front_end_fft(ue, @@ -3947,9 +3948,9 @@ LOG_DEBUG_END 0, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } } } // for l=1..l2 @@ -4002,11 +4003,10 @@ LOG_DEBUG_END //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); - -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); + LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + } //wait until pdcch is decoded @@ -4025,9 +4025,9 @@ LOG_DEBUG_END //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); + } // start slave thread for Pdsch Procedure (slot1) // do procedures for C-RNTI uint8_t eNB_id = 0; @@ -4097,10 +4097,10 @@ LOG_DEBUG_END proc->llr_slot1_available=1; //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); + LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + } if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { @@ -4144,14 +4144,14 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr // start timers -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + } -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + } pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; @@ -4170,16 +4170,16 @@ LOG_DEBUG_END ue->dlsch_ra[eNB_id]->active = 0; } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - ue->Mod_id,frame_rx, subframe_rx); -LOG_DEBUG_END + if ( LOG_DEBUG_FLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", + ue->Mod_id,frame_rx, subframe_rx); + } if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 5; + l2 = 4; } else if (pmch_flag == 1) { // do first 2 symbols only l2 = 1; } else { // normal subframe, last symbol to be processed is the first of the second slot @@ -4247,9 +4247,9 @@ LOG_DEBUG_END /**** Slot0 FE Processing ****/ // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7 -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + } // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3)) //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0); front_end_fft(ue, @@ -4282,9 +4282,9 @@ LOG_DEBUG_END if( (l != pilot0) && (l != pilot1)) { //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_demod_stats); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); front_end_fft(ue, l, @@ -4292,9 +4292,9 @@ LOG_DEBUG_END 0, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } } } // for l=1..l2 @@ -4313,32 +4313,32 @@ LOG_DEBUG_END } if (do_pdcch_flag) { -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) + if (LOG_DEBUGFLAG(UE_TIMING)) { LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + } //proc->dci_slot0_available = 1; return(-1); } //proc->dci_slot0_available=1; -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } } //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + } //wait until slot1 FE is done uint32_t wait = 0; @@ -4348,10 +4348,10 @@ LOG_DEBUG_END wait++; } -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + } /**** End Subframe FE Processing ****/ @@ -4365,13 +4365,13 @@ LOG_DEBUG_END //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx); //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + } if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, @@ -4437,10 +4437,10 @@ LOG_DEBUG_END //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)){ + stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + } //wait until LLR Slot1 is done @@ -4453,16 +4453,16 @@ LOG_DEBUG_END -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)){ + stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } //=====================================================================// -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)){ + start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active, ue->dlsch_SI[eNB_id]->active, @@ -4524,10 +4524,10 @@ LOG_DEBUG_END ue->dlsch_ra[eNB_id]->active = 0; } -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING) + stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } // duplicate harq structure uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid; @@ -4587,10 +4587,10 @@ LOG_DEBUG_END VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) + if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); LOG_UI(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + } LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); return (0); @@ -4626,14 +4626,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, // start timers -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + } -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->generic_stat); -LOG_DEBUG_END + if(LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->generic_stat); + } pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; @@ -4652,10 +4652,10 @@ LOG_DEBUG_END ue->dlsch_ra[eNB_id]->active = 0; } -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - ue->Mod_id,frame_rx, subframe_rx); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", + ue->Mod_id,frame_rx, subframe_rx); + } if (ue->frame_parms.Ncp == 0) { // normal prefix pilot1 = 4; @@ -4665,7 +4665,7 @@ LOG_DEBUG_END if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 5; + l2 = 4; } else if (pmch_flag == 1) { // do first 2 symbols only l2 = 1; } else { // normal subframe, last symbol to be processed is the first of the second slot @@ -4689,9 +4689,9 @@ LOG_DEBUG_END LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); for (; l<=l2; l++) { if (abstraction_flag == 0) { -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_demod_stats); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); slot_fep(ue, l, @@ -4700,16 +4700,16 @@ LOG_DEBUG_END 0, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } } ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); if (do_pdcch_flag) { if ((l==pilot1) || - ((pmch_flag==1)&(l==l2))) { + ((pmch_flag==1)&&(l==l2))) { LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); //start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); @@ -4729,9 +4729,22 @@ LOG_DEBUG_END ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - // If this is PMCH, call procedures and return + + // If this is PMCH, call procedures, do channel estimation for first symbol of next DL subframe and return if (pmch_flag == 1) { ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag); + + int next_subframe_rx = (1+subframe_rx)%10; + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) + { + slot_fep(ue, + 0, + (next_subframe_rx<<1), + 0, + 0, + 0); + } + return 0; } @@ -4743,16 +4756,16 @@ LOG_DEBUG_END 0); // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->generic_stat); - LOG_UI(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->generic_stat); + LOG_UI(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + } LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->generic_stat); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->generic_stat); + } // do procedures for C-RNTI if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); @@ -4822,9 +4835,9 @@ LOG_DEBUG_END if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) { // do front-end processing for second slot, and first symbol of next subframe for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) { if (abstraction_flag == 0) { -LOG_DEBUG_BEGIN(UE_TIMING) + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); slot_fep(ue, l, @@ -4833,14 +4846,15 @@ LOG_DEBUG_END 0, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->ofdm_demod_stats); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } } ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); } // for l=1..l2 + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); // do first symbol of next downlink subframe for channel estimation int next_subframe_rx = (1+subframe_rx)%10; @@ -4854,10 +4868,10 @@ LOG_DEBUG_END 0); } } // not an S-subframe -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->generic_stat); - LOG_UI(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if(LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->generic_stat); + LOG_UI(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + } LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); @@ -4872,9 +4886,9 @@ LOG_DEBUG_END LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } ue_pdsch_procedures(ue, proc, eNB_id, @@ -4886,10 +4900,10 @@ LOG_DEBUG_END abstraction_flag); LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } ue_dlsch_procedures(ue, proc, eNB_id, @@ -4899,38 +4913,38 @@ LOG_DEBUG_END &ue->dlsch_errors[eNB_id], mode, abstraction_flag); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - LOG_UI(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_UI(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->generic_stat); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->generic_stat); + } -LOG_M_BEGIN(DEBUG_UE_PHYPROC) - if(subframe_rx==5 && ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){ - //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); - //LOG_M("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { + if(subframe_rx==5 && ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){ + //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); + //LOG_M("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - LOG_M("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); - LOG_M("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); - //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); - //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + LOG_M("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); - AssertFatal (0,""); + AssertFatal (0,""); + } } -LOG_M_END // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { @@ -5035,25 +5049,25 @@ LOG_M_END ue->Mod_id,frame_rx,ue->total_TBS[eNB_id], ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0); -LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC) - if ((frame_rx % 100 == 0)) { - LOG_I(PHY,"[UE %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx); + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + if ((frame_rx % 100 == 0)) { + LOG_UI(PHY,"[UE %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx); + } } -LOG_DEBUG_END } -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->generic_stat); - printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->generic_stat); + LOG_UI(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING) ) { + stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); + LOG_UI(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); return (0); @@ -5083,9 +5097,9 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1); -LOG_DEBUG_BEGIN(UE_TIMING) - start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); + } #if defined(ENABLE_ITTI) @@ -5168,9 +5182,9 @@ LOG_DEBUG_END } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0); -LOG_DEBUG_BEGIN(UE_TIMING) - stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); + } } // slot } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 7e2f1ad2e02f4e3e694f96483c227bcaf2a74275..3583c0f25eae1246f0f86760b79734700313067b 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -82,7 +82,30 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ -int codingw = 0; +char *parallel_config = NULL; +char *worker_config = NULL; +static THREAD_STRUCT thread_struct; +void set_parallel_conf(char *parallel_conf) +{ + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) +{ + if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; + printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) +{ + return thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) +{ + return thread_struct.worker_conf; +} int emulate_rf = 0; @@ -523,7 +546,7 @@ int main(int argc, char **argv) int c; int k,i,j,aa; int re; - + int loglvl=OAILOG_DEBUG; int s,Kr,Kr_bytes; @@ -1001,7 +1024,7 @@ int main(int argc, char **argv) break; case 'L': - set_glog(atoi(optarg)); + loglvl = atoi(optarg); break; case 'h': @@ -1041,6 +1064,8 @@ int main(int argc, char **argv) break; } } + set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); + set_worker_conf("WORKER_ENABLE"); if (transmission_mode>1) pa=dBm3; printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); @@ -1049,7 +1074,7 @@ int main(int argc, char **argv) "cannot load configuration module, exiting\n"); logInit(); // enable these lines if you need debug info - set_glog(LOG_DEBUG); + set_glog(loglvl); // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt @@ -2046,24 +2071,9 @@ int main(int argc, char **argv) qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); if (dump_table == 1 ) { - set_component_filelog(USIM); // file located in /tmp/usim.txt - int n; - LOG_F(USIM,"The transmitter raw data: \n"); - - for (n=0; n< time_vector_tx.size; n++) { - printf("%f ", table_tx[n]); - LOG_F(USIM,"%f ", table_tx[n]); - } - - LOG_F(USIM,"\n"); - LOG_F(USIM,"The receiver raw data: \n"); - - for (n=0; n< time_vector_rx.size; n++) { - // printf("%f ", table_rx[n]); - LOG_F(USIM,"%f ", table_rx[n]); - } - - LOG_F(USIM,"\n"); + set_component_filelog(SIM); // file located in /tmp/usim.txt + LOG_UDUMPMSG(SIM,table_tx,time_vector_tx.size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,table_rx,time_vector_rx.size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n"); } double tx_median = table_tx[time_vector_tx.size/2]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 0c942df275f7ce5b8dab0d1b1f2cba0c42066a33..2176e272c8a5483c3e4ed8b2b046ba8e21ee375d 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -5016,24 +5016,11 @@ int main(int argc, char **argv) if (dump_table == 1 ) { set_component_filelog(USIM); // file located in /tmp/usim.txt - int n; - LOG_F(USIM,"The transmitter raw data: \n"); + LOG_UDUMPMSG(RRC,(char *)table_tx,time_vector_tx.size,LOG_DUMP_DOUBLE, + "The transmitter raw data: \n"); + LOG_UDUMPMSG(RRC,(char *)table_rx,time_vector_rx.size,LOG_DUMP_DOUBLE, + "The receiver raw data: \n"); - for (n=0; n< time_vector_tx.size; n++) { - printf("%f ", table_tx[n]); - LOG_F(USIM,"%f ", table_tx[n]); - } - - LOG_F(USIM,"\n"); - LOG_F(USIM,"The receiver raw data: \n"); - - for (n=0; n< time_vector_rx.size; n++) { - // printf("%f ", table_rx[n]); - LOG_F(USIM,"%f ", table_rx[n]); - } - - LOG_F(USIM,"\n"); - } double tx_median = table_tx[time_vector_tx.size/2]; double tx_q1 = table_tx[time_vector_tx.size/4]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index b41dd5536c360c073c7ec8c0cc576333b8adbeb7..570c13c0b64f0abec0a817b1cfc1223583fffb61 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -3851,24 +3851,9 @@ PMI_FEEDBACK: qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); if (dump_table == 1 ) { - set_component_filelog(USIM); // file located in /tmp/usim.txt - int n; - LOG_F(USIM,"The transmitter raw data: \n"); - - for (n=0; n< time_vector_tx.size; n++) { - printf("%f ", table_tx[n]); - LOG_F(USIM,"%f ", table_tx[n]); - } - - LOG_F(USIM,"\n"); - LOG_F(USIM,"The receiver raw data: \n"); - - for (n=0; n< time_vector_rx.size; n++) { - // printf("%f ", table_rx[n]); - LOG_F(USIM,"%f ", table_rx[n]); - } - - LOG_F(USIM,"\n"); + set_component_filelog(SIM); // file located in /tmp/usim.txt + LOG_UDUMPMSG(SIM,table_tx,time_vector_tx.size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,table_rx,time_vector_rx.size,LOG_DUMP_DOUBLE,"The receiver raw data: \n"); } double tx_median = table_tx[time_vector_tx.size/2]; diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index b9e059529b6b3d98b5065b1a1b7d07008d72f75f..ad236a6f7568bb9a7d6aeb4a81195bf48a60039e 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -30,7 +30,6 @@ #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" -#include "intertask_interface_init.h" #include "OCG_vars.h" #include "UTIL/LOG/log_extern.h" diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index ab7a29b096c0a292583b43d8e0a97f56b7e48021..8c09da1daf9e3c77cb54e9535fc27f07b6f944a6 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -1,33 +1,33 @@ /* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the 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 ulsim.c - \brief Top-level UL simulator - \author R. Knopp - \date 2011 - 2014 - \version 0.1 - \company Eurecom - \email: knopp@eurecom.fr - \note - \warning + \brief Top-level UL simulator + \author R. Knopp + \date 2011 - 2014 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr + \note + \warning */ #include <string.h> @@ -58,21 +58,43 @@ #include "common/config/config_load_configmodule.h" double cpuf; +#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +//#define MCS_COUNT 23//added for PHY abstraction +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} +double median(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); +} +double q1(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(input->size/4)*input->atomSize); +} -//#define MCS_COUNT 23//added for PHY abstraction +double q3(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(3*input->size/4)*input->atomSize); +} + +void dumpVarArray(varArray_t *input) { + double *ptr=dataArray(input); + printf("dumping size=%ld\n", input->size); + + for (int i=0; i < input->size; i++) + printf("%.1f:", *ptr++); + + printf("\n"); +} channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; -//Added for PHY abstraction +//Added for PHY abstractionopenair1/PHY/TOOLS/lte_phy_scope.h node_desc_t *enb_data[NUMBER_OF_eNB_MAX]; node_desc_t *ue_data[NUMBER_OF_UE_MAX]; //double sinr_bler_map[MCS_COUNT][2][16]; extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16]; //extern char* namepointer_chMag ; - int xforms=0; FD_lte_phy_scope_enb *form_enb; char title[255]; @@ -88,6 +110,8 @@ int nfapi_mode = 0; extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); +extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; @@ -97,36 +121,56 @@ nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; nfapi_tx_request_t TX_req; Sched_Rsp_t sched_resp; -int codingw = 0; +char *parallel_config = NULL; +char *worker_config = NULL; +static THREAD_STRUCT thread_struct; +void set_parallel_conf(char *parallel_conf) +{ + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) +{ + if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; + printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) +{ + return thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) +{ + return thread_struct.worker_conf; +} void fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint8_t cqi_req, - uint8_t p_eNB, - uint8_t cqi_ReportModeAperiodic, - uint8_t betaOffset_CQI_Index, - uint8_t betaOffset_RI_Index, - uint8_t dl_cqi_pmi_size, - uint8_t tmode, - uint32_t handle, - uint16_t rnti, - uint8_t resource_block_start, - uint8_t number_of_resource_blocks, - uint8_t modulation_type, - uint8_t cyclic_shift_2_for_drms, - uint8_t frequency_hopping_enabled_flag, - uint8_t frequency_hopping_bits, - uint8_t new_data_indication, - uint8_t redundancy_version, - uint8_t harq_process_number, - uint8_t ul_tx_mode, - uint8_t current_tx_nb, - uint8_t n_srs, - uint16_t size) -{ + uint8_t cqi_req, + uint8_t p_eNB, + uint8_t cqi_ReportModeAperiodic, + uint8_t betaOffset_CQI_Index, + uint8_t betaOffset_RI_Index, + uint8_t dl_cqi_pmi_size, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t modulation_type, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) { memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; @@ -158,15 +202,15 @@ fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); if (p_eNB <= 2 - && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; for (int ri = 0; - ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); - ri++) - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_Index; @@ -174,585 +218,538 @@ fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, } void fill_ulsch_dci(PHY_VARS_eNB *eNB, - int frame, - int subframe, - Sched_Rsp_t *sched_resp, - uint16_t rnti, - void *UL_dci, - int first_rb, - int nb_rb, - int mcs, - int modulation_type, - int ndi, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint16_t rnti, + void *UL_dci, + int first_rb, + int nb_rb, + int mcs, + int modulation_type, + int ndi, int TBS, - int cqi_flag, - uint8_t beta_CQI, - uint8_t beta_RI, - uint8_t cqi_size) { - + int cqi_flag, + uint8_t beta_CQI, + uint8_t beta_RI, + uint8_t cqi_size) { nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body; int harq_pid = ((frame*10)+subframe)&7; //printf("ulsch in frame %d, subframe %d => harq_pid %d, mcs %d, ndi %d\n",frame,subframe,harq_pid,mcs,ndi); switch (eNB->frame_parms.N_RB_UL) { - case 6: - break; - - case 25: - if (eNB->frame_parms.frame_type == TDD) { - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->type = 0; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->TPC = 0; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->cshift = 0; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->dai = 1; - } else { - ((DCI0_5MHz_FDD_t*)UL_dci)->type = 0; - ((DCI0_5MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x) (dcip %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,UL_dci); - ((DCI0_5MHz_FDD_t*)UL_dci)->mcs = mcs; - ((DCI0_5MHz_FDD_t*)UL_dci)->ndi = ndi; - ((DCI0_5MHz_FDD_t*)UL_dci)->TPC = 0; - ((DCI0_5MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_5MHz_FDD_t*)UL_dci)->cshift = 0; - } + case 6: + break; - break; - - case 50: - if (eNB->frame_parms.frame_type == TDD) { - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->type = 0; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->TPC = 0; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cshift = 0; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->dai = 1; - } else { - ((DCI0_10MHz_FDD_t*)UL_dci)->type = 0; - ((DCI0_10MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_10MHz_FDD_t*)UL_dci)->mcs = mcs; - ((DCI0_10MHz_FDD_t*)UL_dci)->ndi = ndi; - ((DCI0_10MHz_FDD_t*)UL_dci)->TPC = 0; - ((DCI0_10MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_10MHz_FDD_t*)UL_dci)->cshift = 0; - } + case 25: + if (eNB->frame_parms.frame_type == TDD) { + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->type = 0; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->mcs = mcs; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->ndi = ndi; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->TPC = 0; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cshift = 0; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->dai = 1; + } else { + ((DCI0_5MHz_FDD_t *)UL_dci)->type = 0; + ((DCI0_5MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x) (dcip %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,UL_dci); + ((DCI0_5MHz_FDD_t *)UL_dci)->mcs = mcs; + ((DCI0_5MHz_FDD_t *)UL_dci)->ndi = ndi; + ((DCI0_5MHz_FDD_t *)UL_dci)->TPC = 0; + ((DCI0_5MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_5MHz_FDD_t *)UL_dci)->cshift = 0; + } - break; - - case 100: - if (eNB->frame_parms.frame_type == TDD) { - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->type = 0; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->TPC = 0; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cshift = 0; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->dai = 1; - } else { - ((DCI0_20MHz_FDD_t*)UL_dci)->type = 0; - ((DCI0_20MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci); - ((DCI0_20MHz_FDD_t*)UL_dci)->mcs = mcs; - ((DCI0_20MHz_FDD_t*)UL_dci)->ndi = ndi; - ((DCI0_20MHz_FDD_t*)UL_dci)->TPC = 0; - ((DCI0_20MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_20MHz_FDD_t*)UL_dci)->cshift = 0; - } + break; - break; + case 50: + if (eNB->frame_parms.frame_type == TDD) { + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->type = 0; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->mcs = mcs; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->ndi = ndi; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->TPC = 0; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->cshift = 0; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->dai = 1; + } else { + ((DCI0_10MHz_FDD_t *)UL_dci)->type = 0; + ((DCI0_10MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_10MHz_FDD_t *)UL_dci)->mcs = mcs; + ((DCI0_10MHz_FDD_t *)UL_dci)->ndi = ndi; + ((DCI0_10MHz_FDD_t *)UL_dci)->TPC = 0; + ((DCI0_10MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_10MHz_FDD_t *)UL_dci)->cshift = 0; + } + + break; - default: - break; + case 100: + if (eNB->frame_parms.frame_type == TDD) { + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->type = 0; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->mcs = mcs; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->ndi = ndi; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->TPC = 0; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->cshift = 0; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->dai = 1; + } else { + ((DCI0_20MHz_FDD_t *)UL_dci)->type = 0; + ((DCI0_20MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci); + ((DCI0_20MHz_FDD_t *)UL_dci)->mcs = mcs; + ((DCI0_20MHz_FDD_t *)UL_dci)->ndi = ndi; + ((DCI0_20MHz_FDD_t *)UL_dci)->TPC = 0; + ((DCI0_20MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_20MHz_FDD_t *)UL_dci)->cshift = 0; + } + + break; + + default: + break; } fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], - cqi_flag&1, - 1, // p_eNB - 0, // reportmode Aperiodic - beta_CQI, - beta_RI, - cqi_size, - //cc, - //UE_template->physicalConfigDedicated, - 1, - 0, - 14, // rnti - first_rb, // resource_block_start - nb_rb, // number_of_resource_blocks - modulation_type, - 0, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - mcs>28?(mcs-28):0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - TBS); - + cqi_flag&1, + 1, // p_eNB + 0, // reportmode Aperiodic + beta_CQI, + beta_RI, + cqi_size, + //cc, + //UE_template->physicalConfigDedicated, + 1, + 0, + 14, // rnti + first_rb, // resource_block_start + nb_rb, // number_of_resource_blocks + modulation_type, + 0, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + mcs>28?(mcs-28):0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + TBS); sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req->number_of_pdus=1; ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; +} +void printStatIndent(time_stats_t *ptr, char *txt) { + printf("|__ %-50s %.2f us (%d trials)\n", + txt, + inMicroS(ptr->diff/ptr->trials), + ptr->trials); } -extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) { + double timeBase=1/(1000*cpu_freq_GHz); + printf(" |__ %-45s %.2f us (cycles/block %7g, %5d trials)\n", + txt, + ((double)ptr->diff)/ptr->trials*timeBase, + round(((double)ptr->diff)/turbo_iter), + ptr->trials); +} -int main(int argc, char **argv) -{ +double squareRoot(time_stats_t *ptr) { + double timeBase=1/(1000*cpu_freq_GHz); + return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - + pow((double)ptr->diff/ptr->trials*timeBase,2)); +} + +void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { + double timeBase=1/(1000*cpu_freq_GHz); + printf("%-50s :%.2f us (%d trials)\n", + txt, + (double)ptr->diff/ptr->trials*timeBase, + ptr->trials); + printf("|__ Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", + squareRoot(ptr), median(sortedList),q1(sortedList),q3(sortedList), sortedList->size); +} - char c; +void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dropped) { + fprintf(fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(ptr), + (double)ptr->max, *(double*)dataArray(sortedList), + median(sortedList),q1(sortedList),q3(sortedList), + dropped); +} + +enum eTypes { eBool, eInt, eFloat, eText }; +static int verbose,disable_bundling=0,cqi_flag=0, extended_prefix_flag=0, test_perf=0, subframe=3, transmission_m=1,n_rx=1; + +int main(int argc, char **argv) { int i,j,aa,u; PHY_VARS_eNB *eNB; PHY_VARS_UE *UE; RU_t *ru; int aarx,aatx; double channelx,channely; - double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; - double input_snr_step=.2,snr_int=30; + static double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; + static double input_snr_step=.2,snr_int=30; double blerr; - int rvidx[8]={0,2,3,1,0,2,3,1}; + int rvidx[8]= {0,2,3,1,0,2,3,1}; int **txdata; - LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720]; double s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720]; double r_re2[30720],r_im2[30720]; double r_re3[30720],r_im3[30720]; - double *s_re[2]={s_re0,s_re1}; - double *s_im[2]={s_im0,s_im1}; - double *r_re[4]={r_re0,r_re1,r_re2,r_re3}; - double *r_im[4]={r_im0,r_im1,r_im2,r_im3}; + double *s_re[2]= {s_re0,s_re1}; + double *s_im[2]= {s_im0,s_im1}; + double *r_re[4]= {r_re0,r_re1,r_re2,r_re3}; + double *r_im[4]= {r_im0,r_im1,r_im2,r_im3}; double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; - uint8_t extended_prefix_flag=0; - int cqi_flag=0,cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives; + int cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives; int ch_realization; int eNB_id = 0; int chMod = 0 ; int UE_id = 0; - unsigned char nb_rb=25,first_rb=0,mcs=0,round=0,bundling_flag=1; + static int nb_rb=25,first_rb=0,mcs=0,round=0; //unsigned char l; - - unsigned char awgn_flag = 0 ; + static int awgn_flag = 0 ; SCM_t channel_model=Rice1; - - - unsigned char *input_buffer,harq_pid; + unsigned char *input_buffer=0,harq_pid; unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - int subframe=3; unsigned int tx_lev=0,tx_lev_dB,trials,errs[4]= {0,0,0,0},round_trials[4]= {0,0,0,0}; - uint8_t transmission_mode=1,n_rx=1; - FILE *bler_fd=NULL; char bler_fname[512]; - FILE *time_meas_fd=NULL; char time_meas_fname[256]; - FILE *input_fdUL=NULL,*trch_out_fdUL=NULL; // unsigned char input_file=0; char input_val_str[50],input_val_str2[50]; - // FILE *rx_frame_file; FILE *csv_fdUL=NULL; - /* - FILE *fperen=NULL; - char fperen_name[512]; + FILE *fperen=NULL; + char fperen_name[512]; - FILE *fmageren=NULL; - char fmageren_name[512]; + FILE *fmageren=NULL; + char fmageren_name[512]; - FILE *flogeren=NULL; - char flogeren_name[512]; + FILE *flogeren=NULL; + char flogeren_name[512]; */ - /* FILE *ftxlev; char ftxlev_name[512]; */ - char csv_fname[512]; - int n_frames=5000; - int n_ch_rlz = 1; - int abstx = 0; + static int n_frames=5000; + static int n_ch_rlz = 1; + static int abstx = 0; int hold_channel=0; channel_desc_t *UE2eNB; - //uint8_t control_only_flag = 0; - int delay = 0; - double maxDoppler = 0.0; - uint8_t srs_flag = 0; - - uint8_t N_RB_DL=25,osf=1; - + static int delay = 0; + static double maxDoppler = 0.0; + static int srs_flag = 0; + static int N_RB_DL=25,osf=1; //uint8_t cyclic_shift = 0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; - uint8_t tdd_config=3,frame_type=FDD; - - uint8_t N0=30; - double tx_gain=1.0; + static uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; + static uint8_t tdd_config=3,frame_type=FDD; + static int N0=30; + static double tx_gain=1.0; double cpu_freq_GHz; - int avg_iter,iter_trials; - + int iter_trials; uint32_t UL_alloc_pdu; int s,Kr,Kr_bytes; int dump_perf=0; - int test_perf=0; - int dump_table =0; - + static int dump_table =0; double effective_rate=0.0; - char channel_model_input[10]; - - uint8_t max_turbo_iterations=4; - uint8_t parallel_flag=0; + char channel_model_input[10]= {0}; + static int max_turbo_iterations=4; + static int parallel_flag=0; int nb_rb_set = 0; int sf; - - int threequarter_fs=0; + static int threequarter_fs=0; int ndi; - opp_enabled=1; // to enable the time meas - sched_resp.DL_req = &DL_req; sched_resp.UL_req = &UL_req; sched_resp.HI_DCI0_req = &HI_DCI0_req; sched_resp.TX_req = &TX_req; - memset((void*)&DL_req,0,sizeof(DL_req)); - memset((void*)&UL_req,0,sizeof(UL_req)); - memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); - memset((void*)&TX_req,0,sizeof(TX_req)); - + memset((void *)&DL_req,0,sizeof(DL_req)); + memset((void *)&UL_req,0,sizeof(UL_req)); + memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void *)&TX_req,0,sizeof(TX_req)); UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list; TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; - cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; - printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); AssertFatal(load_configmodule(argc,argv) != NULL, - "cannot load configuration module, exiting\n"); - + "cannot load configuration module, exiting\n"); logInit(); - // enable these lines if you need debug info // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); //set_comp_log(PHY,LOG_DEBUG,LOG_MED,1); //set_glog(LOG_DEBUG,LOG_MED); - + //hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF + static paramdef_t options[] = { + { "awgn", "Additive white gaussian noise", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 }, + { "mcs", "The MCS to use", 0, iptr:&mcs, defintval:10, TYPE_INT, 0 }, + { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 }, + { "snr", "starting snr", 0, dblptr:&snr0, defdblval:-2.9, TYPE_DOUBLE, 0 }, + { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 }, + { "e_snr_step", "step increasint snr",0, dblptr:&input_snr_step, defdblval:0.2, TYPE_DOUBLE, 0 }, + { "rb_dynamic", "number of rb in dynamic allocation",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "first_rb", "first rb used in dynamic allocation",0, iptr:&first_rb, defintval:0, TYPE_INT, 0 }, + { "osrs", "enable srs generation",PARAMFLAG_BOOL, iptr:&srs_flag, defintval:0, TYPE_INT, 0 }, + { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, + { "delay_chan", "Channel delay",0, iptr:&delay, defintval:0, TYPE_INT, 0 }, + { "Doppler", "Maximum doppler shift",0, dblptr:&maxDoppler, defdblval:0.0, TYPE_DOUBLE, 0 }, + { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, + { "Forms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, + { "Lparallel", "Enable parallel execution", PARAMFLAG_BOOL, iptr:¶llel_flag, defintval:0, TYPE_INT, 0 }, + { "Iterations", "Number of iterations of turbo decoder", 0, iptr:&max_turbo_iterations, defintval:4, TYPE_INT, 0 }, + { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Q_cqi", "Enable CQI", PARAMFLAG_BOOL, iptr:&cqi_flag, defintval:0, TYPE_INT, 0 }, + { "prefix_extended","Extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag, defintval:0, TYPE_INT, 0 }, + { "RI_beta", "TBD", 0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "CQI_beta", "TBD",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "ACK_beta", "TBD",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "input_file", "input IQ data file",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "N0", "N0",0, iptr:&N0, defintval:30, TYPE_INT, 0 }, + { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 }, + { "TDD", "Enable TDD and set the tdd configuration mode",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "Subframe", "subframe to use",0, iptr:&subframe, defintval:3, TYPE_INT, 0 }, + { "xTransmission","transmission mode (1 or 2 are supported)",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "yN_rx", "TBD: n_rx",0, iptr:&n_rx, defintval:1, TYPE_INT, 0 }, + { "bundling_disable", "bundling disable",PARAMFLAG_BOOL, iptr:&disable_bundling, defintval:0, TYPE_INT, 0 }, + { "Y", "n_ch_rlz",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 }, + { "X", "abstx", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 }, + { "Operf", "test perf mode ?",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, + { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + }; + int l; + + for(l=0; options[l].optname[0]!=0; l++) {}; + + struct option *long_options=calloc(sizeof(struct option),l); + + for(int i=0; options[i].optname[0]!=0; i++) { + long_options[i].name=options[i].optname; + long_options[i].has_arg=options[i].paramflags==PARAMFLAG_BOOL?no_argument:required_argument; + + if ( options[i].voidptr) + switch (options[i].type) { + case TYPE_INT: + *options[i].iptr=options[i].defintval; + break; - while ((c = getopt (argc, argv, "hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF")) != -1) { - switch (c) { - case 'a': - channel_model = AWGN; - chMod = 1; - break; + case TYPE_DOUBLE: + *options[i].dblptr=options[i].defdblval; + break; - case 'b': - bundling_flag = 0; - break; + default: + printf("not parsed type for default value %s\n", options[i].optname ); + exit(1); + } - case 'd': - delay = atoi(optarg); - break; + continue; + }; - case 'D': - maxDoppler = atoi(optarg); - break; + int option_index; - case 'm': - mcs = atoi(optarg); - break; + int res; - case 'n': - n_frames = atoi(optarg); - break; - - case 'Y': - n_ch_rlz = atoi(optarg); - break; - - case 'X': - abstx= atoi(optarg); - break; + while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) { + if (options[option_index].voidptr != NULL ) { + if (long_options[option_index].has_arg==no_argument) + *(bool *)options[option_index].iptr=1; + else switch (options[option_index].type) { + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; - case 'g': - sprintf(channel_model_input,optarg,10); + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; - chMod = 2; - break; + default: + printf("not decoded type.\n"); + exit(1); + } - case 'B': - channel_model=SCM_B; - chMod = 3; - break; + continue; + } - case 'C': - channel_model=SCM_C; - chMod = 4; + switch (long_options[option_index].name[0]) { + case 'T': + tdd_config=atoi(optarg); + frame_type=TDD; break; - case 'D': - channel_model=SCM_D; - chMod = 5; + case 'a': + channel_model = AWGN; + chMod = 1; break; - case 'E': - channel_model=EPA; - chMod = 6; - break; + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; + + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + chMod=ptr->M; + break; + } - case 'F': - channel_model=EVA; - chMod = 7; + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); break; - case 'G': - channel_model=ETU; - chMod = 8; + case 'x': + transmission_m=atoi(optarg); + AssertFatal(transmission_m==1 || transmission_m==2, + "Unsupported transmission mode %d\n",transmission_m); break; - case 'H': - channel_model=Rayleigh8; - chMod = 9; + case 'r': + nb_rb = atoi(optarg); + nb_rb_set = 1; break; - case 'I': - channel_model=Rayleigh1; - chMod = 10; - break; + //case 'c': + // cyclic_shift = atoi(optarg); + // break; - case 'J': - channel_model=Rayleigh1_corr; - chMod = 11; + case 'i': + input_fdUL = fopen(optarg,"r"); + printf("Reading in %s (%p)\n",optarg,input_fdUL); + AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); break; - case 'K': - channel_model=Rayleigh1_anticorr; - chMod = 12; + case 'A': + beta_ACK = atoi(optarg); + AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); break; - case 'L': - channel_model=Rice8; - chMod = 13; + case 'C': + beta_CQI = atoi(optarg); + AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); break; - case 'M': - channel_model=Rice1; - chMod = 14; + case 'R': + beta_RI = atoi(optarg); + AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); break; - case 'N': - channel_model=AWGN; - chMod = 1; + case 'P': + dump_perf=1; + opp_enabled=1; break; default: - printf("Unsupported channel model!\n"); - exit(-1); + printf("Wrong option\n"); + exit(1); break; - } - - break; - - case 's': - snr0 = atof(optarg); - break; - - case 'w': - snr_int = atof(optarg); - break; - - case 'e': - input_snr_step= atof(optarg); - break; - - case 'x': - transmission_mode=atoi(optarg); - - if ((transmission_mode!=1) && - (transmission_mode!=2)) { - printf("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } - - break; - - case 'y': - n_rx = atoi(optarg); - break; - - case 'S': - subframe = atoi(optarg); - break; - - case 'T': - tdd_config=atoi(optarg); - frame_type=TDD; - break; - - case 'p': - extended_prefix_flag=1; - break; - - case 'r': - nb_rb = atoi(optarg); - nb_rb_set = 1; - break; - - case 'f': - first_rb = atoi(optarg); - break; - - //case 'c': - // cyclic_shift = atoi(optarg); - // break; - - case 'E': - threequarter_fs=1; - break; - - case 'N': - N0 = atoi(optarg); - break; - - case 'o': - srs_flag = 1; - break; - - case 'i': - input_fdUL = fopen(optarg,"r"); - printf("Reading in %s (%p)\n",optarg,input_fdUL); - - if (input_fdUL == (FILE*)NULL) { - printf("Unknown file %s\n",optarg); - exit(-1); - } - - // input_file=1; - break; - - case 'A': - beta_ACK = atoi(optarg); - - if (beta_ACK>15) { - printf("beta_ack must be in (0..15)\n"); - exit(-1); - } - - break; - - case 'C': - beta_CQI = atoi(optarg); - - if ((beta_CQI>15)||(beta_CQI<2)) { - printf("beta_cqi must be in (2..15)\n"); - exit(-1); - } - - break; - - case 'R': - beta_RI = atoi(optarg); - - if ((beta_RI>15)||(beta_RI<2)) { - printf("beta_ri must be in (0..13)\n"); - exit(-1); - } - - break; - - case 'Q': - cqi_flag=1; - break; + } + } - case 'B': - N_RB_DL=atoi(optarg); - break; + if ( res != -1 ) { + printf("A wrong option has been found\n"); + exit(1); + } - case 'P': - dump_perf=1; - opp_enabled=1; - break; + paramdef_t *ptr=options ; - case 'O': - test_perf=atoi(optarg); - //print_perf =1; - break; + for( ptr=options; ptr->optname[0]!=0; ptr++) { + char varText[256]="need specific display"; - case 'L': - parallel_flag=1; - break; + if (ptr->voidptr != NULL) { + if ( (ptr->paramflags & PARAMFLAG_BOOL) ) + strcpy(varText, *(bool *)ptr->iptr ? "True": "False" ); + else switch (ptr->type) { + case TYPE_INT: + sprintf(varText,"%d",*ptr->iptr); + break; - case 'I': - max_turbo_iterations=atoi(optarg); - break; + case TYPE_DOUBLE: + sprintf(varText,"%.2f",*ptr->dblptr); + break; - case 'F': - xforms=1; - break; + default: + printf("not decoded type\n"); + exit(1); + } + } - case 'Z': - dump_table = 1; - break; + printf("Option: %20s set to %s\n",ptr->optname, varText); - case 'h': - default: - /* option "-c cyclic_shift" is not used, let's remove from documentation */ - //printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -c cyclic_shift -o (srs on) -g channel_model [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M'), -d Channel delay, -D maximum Doppler shift \n", - printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -o (srs on) -g channel_model [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M'), -d Channel delay, -D maximum Doppler shift \n", - argv[0]); - exit(1); - break; - } + if (verbose) + printf("%s\n",ptr->helpstr); } + set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); + set_worker_conf("WORKER_ENABLE"); RC.nb_L1_inst = 1; RC.nb_RU = 1; - lte_param_init(&eNB,&UE,&ru, - 1, - 1, - n_rx, 1, - 1, - extended_prefix_flag, - frame_type, - 0, - tdd_config, - N_RB_DL, - 4, - threequarter_fs, - osf, - 0); - + 1, + n_rx, + 1, + 1, + extended_prefix_flag, + frame_type, + 0, + tdd_config, + N_RB_DL, + 4, + threequarter_fs, + osf, + 0); RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); RC.ru = (RU_t **)malloc(sizeof(RC.ru)); RC.eNB[0][0] = eNB; RC.ru[0] = ru; - for (int k=0;k<eNB->RU_list[0]->nb_rx;k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; - memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + for (int k=0; k<eNB->RU_list[0]->nb_rx; k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; + memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); printf("Setting indication lists\n"); eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; @@ -760,12 +757,10 @@ int main(int argc, char **argv) eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; - printf("lte_param_init done\n"); - // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE - PHY_vars_UE_g = (PHY_VARS_UE***)malloc(sizeof(PHY_VARS_UE**)); - PHY_vars_UE_g[0] = (PHY_VARS_UE**) malloc(sizeof(PHY_VARS_UE*)); + PHY_vars_UE_g = (PHY_VARS_UE ***)malloc(sizeof(PHY_VARS_UE **)); + PHY_vars_UE_g[0] = (PHY_VARS_UE **) malloc(sizeof(PHY_VARS_UE *)); PHY_vars_UE_g[0][0] = UE; if (nb_rb_set == 0) @@ -774,19 +769,14 @@ int main(int argc, char **argv) printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]); printf("Setting mcs = %d\n",mcs); printf("n_frames = %d\n", n_frames); - snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; - txdata = UE->common_vars.txdata; - nsymb = (eNB->frame_parms.Ncp == NORMAL) ? 14 : 12; - - sprintf(bler_fname,"ULbler_mcs%d_nrb%d_ChannelModel%d_nsim%d.csv",mcs,nb_rb,chMod,n_frames); bler_fd = fopen(bler_fname,"w"); + if (bler_fd==NULL) { fprintf(stderr,"Problem creating file %s\n",bler_fname); exit(-1); @@ -803,8 +793,9 @@ int main(int argc, char **argv) //sprintf(dirname, "%s//SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname); //mkdir(dirname, 0777); sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_antrx%d_channel%s_tx%d.csv", - N_RB_DL,mcs,n_rx,channel_model_input,transmission_mode); + N_RB_DL,mcs,n_rx,channel_model_input,transmission_m); time_meas_fd = fopen(time_meas_fname,"w"); + if (time_meas_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); exit(-1); @@ -813,16 +804,17 @@ int main(int argc, char **argv) if(abstx) { // CSV file - sprintf(csv_fname,"EULdataout_tx%d_mcs%d_nbrb%d_chan%d_nsimus%d_eren.m",transmission_mode,mcs,nb_rb,chMod,n_frames); + sprintf(csv_fname,"EULdataout_tx%d_mcs%d_nbrb%d_chan%d_nsimus%d_eren.m",transmission_m,mcs,nb_rb,chMod,n_frames); csv_fdUL = fopen(csv_fname,"w"); + if (csv_fdUL == NULL) { fprintf(stderr,"Problem opening file %s\n",csv_fname); exit(-1); } + fprintf(csv_fdUL,"data_all%d=[",mcs); } - if (xforms==1) { fl_initialize (&argc, argv, NULL, 0, 0); form_enb = create_lte_phy_scope_enb(); @@ -831,7 +823,6 @@ int main(int argc, char **argv) } UE->pdcch_vars[0][0]->crnti = 14; - UE->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; @@ -842,7 +833,6 @@ int main(int argc, char **argv) UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0; UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0; UE->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = 0; - eNB->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; @@ -853,29 +843,22 @@ int main(int argc, char **argv) eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb = 0; eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0; - - eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI; UE->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK; UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = beta_RI; UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI; - UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1; - // disable periodic cqi/ri reporting UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - - printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8); - UE2eNB = new_channel_desc_scm(1, n_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), forgetting_factor, delay, 0); @@ -883,7 +866,8 @@ int main(int argc, char **argv) UE2eNB->max_Doppler = maxDoppler; // NN: N_RB_UL has to be defined in ulsim - for (int k=0;k<NUMBER_OF_UE_MAX;k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + for (int k=0; k<NUMBER_OF_UE_MAX; k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); printf("ULSCH %p\n",UE->ulsch[0]); @@ -893,70 +877,66 @@ int main(int argc, char **argv) init_fep_thread(eNB,NULL); init_td_thread(eNB); } + // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); + if (!eNB->dlsch[0][i]) { printf("Can't get eNB dlsch structures\n"); exit(-1); } + eNB->dlsch[0][i]->rnti = 14; } + /* allocate memory for both subframes (only one is really used - * but there is now "copy_harq_proc_struct" which needs both - * to be valid) - * TODO: refine this somehow (necessary?) - */ + but there is now "copy_harq_proc_struct" which needs both + to be valid) + TODO: refine this somehow (necessary?) + */ for (sf = 0; sf < 2; sf++) { for (i=0; i<2; i++) { UE->dlsch[sf][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + if (!UE->dlsch[sf][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } + UE->dlsch[sf][0][i]->rnti = 14; } } UE->dlsch_SI[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->dlsch_ra[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); - UE->measurements.rank[0] = 0; UE->transmission_mode[0] = 2; - UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing; + UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = disable_bundling == 0 ? bundling : multiplexing; eNB->transmission_mode[0] = 2; - eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing; + eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = disable_bundling == 0 ? bundling : multiplexing; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - - UE->mac_enabled=0; - eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; proc_rxtx->subframe_rx=subframe; - proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); - proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; - printf("Init UL hopping UE\n"); init_ul_hopping(&UE->frame_parms); printf("Init UL hopping eNB\n"); init_ul_hopping(&eNB->frame_parms); - - UE->dlsch[subframe&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; - UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb; @@ -964,26 +944,20 @@ int main(int argc, char **argv) if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O; rate = (double)dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1]/(coded_bits_per_codeword); - printf("Rate = %f (mod %d), coded bits %d\n",rate,get_Qm_ul(mcs),coded_bits_per_codeword); - - for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) { - /* if(abstx){ int ulchestim_f[300*12]; int ulchestim_t[2*(frame_parms->ofdm_symbol_size)]; } */ - if(abstx) { printf("**********************Channel Realization Index = %d **************************\n", ch_realization); saving_bler=1; } - // if ((subframe>5) || (subframe < 4)) // UE->frame++; @@ -1001,17 +975,17 @@ int main(int argc, char **argv) cqi_crc_falsepositives=0; cqi_crc_falsenegatives=0; round=0; - //randominit(0); - - harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe); input_buffer_length = UE->ulsch[0]->harq_processes[harq_pid]->TBS/8; + + if ( input_buffer != NULL ) + free(input_buffer); + input_buffer = (unsigned char *)memalign(32,input_buffer_length+64); + // printf("UL frame %d/subframe %d, harq_pid %d\n",UE->frame,subframe,harq_pid); if (input_fdUL == NULL) { - - if (n_frames == 1) { trch_out_fdUL= fopen("ulsch_trchUL.txt","w"); @@ -1033,14 +1007,15 @@ int main(int argc, char **argv) while (!feof(input_fdUL)) { ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); + if (ret != 2) printf("ERROR: error reading file\n"); if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); + ((short *)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); + ((short *)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); + printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short *)txdata[0])[i/4],((short *)txdata[0])[(i/4)+1]); //1,input_val2,); } i++; @@ -1055,10 +1030,8 @@ int main(int argc, char **argv) tx_lev = signal_energy(&txdata[0][0], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - } - avg_iter = 0; iter_trials=0; reset_meas(&UE->phy_proc_tx); reset_meas(&UE->ofdm_mod_stats); @@ -1069,7 +1042,6 @@ int main(int argc, char **argv) reset_meas(&UE->ulsch_turbo_encoding_stats); reset_meas(&UE->ulsch_segmentation_stats); reset_meas(&UE->ulsch_multiplexing_stats); - reset_meas(&eNB->phy_proc_rx); reset_meas(&eNB->ulsch_channel_estimation_stats); reset_meas(&eNB->ulsch_freq_offset_estimation_stats); @@ -1079,6 +1051,7 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_deinterleaving_stats); reset_meas(&eNB->ulsch_demultiplexing_stats); reset_meas(&eNB->ulsch_rate_unmatching_stats); + reset_meas(&eNB->ulsch_demodulation_stats); reset_meas(&eNB->ulsch_tc_init_stats); reset_meas(&eNB->ulsch_tc_alpha_stats); reset_meas(&eNB->ulsch_tc_beta_stats); @@ -1086,91 +1059,82 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_tc_ext_stats); reset_meas(&eNB->ulsch_tc_intl1_stats); reset_meas(&eNB->ulsch_tc_intl2_stats); - // initialization - struct list time_vector_tx; - initialize(&time_vector_tx); - struct list time_vector_tx_ifft; - initialize(&time_vector_tx_ifft); - struct list time_vector_tx_mod; - initialize(&time_vector_tx_mod); - struct list time_vector_tx_enc; - initialize(&time_vector_tx_enc); - - struct list time_vector_rx; - initialize(&time_vector_rx); - struct list time_vector_rx_fft; - initialize(&time_vector_rx_fft); - struct list time_vector_rx_demod; - initialize(&time_vector_rx_demod); - struct list time_vector_rx_dec; - initialize(&time_vector_rx_dec); - + varArray_t *table_tx=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_mod=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_enc=initVarArray(1000,sizeof(double)); + varArray_t *table_rx=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_fft=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_demod=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_dec=initVarArray(1000,sizeof(double)); ndi=0; - phy_reset_ue(0,0,0); UE->UE_mode[eNB_id]=PUSCH; + SET_LOG_DEBUG(UE_TIMING); for (trials = 0; trials<n_frames; trials++) { // printf("*"); // UE->frame++; // eNB->frame++; - ndi = (1-ndi); + ndi = (1-ndi); fflush(stdout); round=0; while (round < 4) { - proc_rxtx->frame_rx=1; - proc_rxtx->subframe_rx=subframe; - - proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); - proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); - - proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); - proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; - + proc_rxtx->frame_rx=1; + proc_rxtx->subframe_rx=subframe; + proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); + proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; eNB->ulsch[0]->harq_processes[harq_pid]->round=round; UE->ulsch[0]->harq_processes[harq_pid]->round=round; - if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); - round_trials[round]++; - UL_req.sfn_sf = (1<<4)+subframe; - if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); + if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); - int modulation_type; - if (mcs < 11) modulation_type = 2; - else if (mcs < 21) modulation_type = 4; - else if (mcs < 29) modulation_type = 6; - else { - LOG_E(SIM,"mcs %i is not valid\n",mcs); - exit(-1); - } + round_trials[round]++; + UL_req.sfn_sf = (1<<4)+subframe; - fill_ulsch_dci(eNB,proc_rxtx->frame_rx,subframe,&sched_resp,14,(void*)&UL_alloc_pdu,first_rb,nb_rb,(round==0)?mcs:(28+rvidx[round]),modulation_type,ndi,get_TBS_UL(mcs,nb_rb),cqi_flag,beta_CQI,beta_RI,cqi_size); + if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); - UE->ulsch_Msg3_active[eNB_id] = 0; - UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; - if (n_frames==1) printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); - generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, - 14, - (subframe+6)%10, - format0, - UE, - proc_rxtx_ue, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - 0, - srs_flag); + int modulation_type; - sched_resp.subframe=(subframe+6)%10; - sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + if (mcs < 11) modulation_type = 2; + else if (mcs < 21) modulation_type = 4; + else if (mcs < 29) modulation_type = 6; + else { + LOG_E(SIM,"mcs %i is not valid\n",mcs); + exit(-1); + } - schedule_response(&sched_resp); + fill_ulsch_dci(eNB, proc_rxtx->frame_rx, subframe, &sched_resp, 14, + (void *)&UL_alloc_pdu, first_rb,nb_rb, (round==0)?mcs:(28+rvidx[round]), + modulation_type, ndi, get_TBS_UL(mcs,nb_rb), cqi_flag, beta_CQI, + beta_RI, cqi_size); + UE->ulsch_Msg3_active[eNB_id] = 0; + UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; + if (n_frames==1) + printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); + + generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, + 14, + (subframe+6)%10, + format0, + UE, + proc_rxtx_ue, + SI_RNTI, + 0, + P_RNTI, + CBA_RNTI, + 0, + srs_flag); + sched_resp.subframe=(subframe+6)%10; + sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + schedule_response(&sched_resp); ///////////////////// if (abstx) { @@ -1189,31 +1153,24 @@ int main(int argc, char **argv) /////////////////////////////////////// if (input_fdUL == NULL) { - - eNB->proc.frame_rx = 1; - eNB->proc.subframe_rx = subframe; - ru->proc.frame_rx = 1; - ru->proc.subframe_rx = subframe; - - proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; - proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; - - phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx); - - - tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], - eNB->frame_parms.samples_per_tti); - + eNB->proc.frame_rx = 1; + eNB->proc.subframe_rx = subframe; + ru->proc.frame_rx = 1; + ru->proc.subframe_rx = subframe; + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; + phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx); + tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], + eNB->frame_parms.samples_per_tti); if (n_frames==1) { LOG_M("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1, - 1); + 1); //LOG_M("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); } - - } // input_fd == NULL + } // input_fd == NULL tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev); @@ -1226,21 +1183,17 @@ int main(int argc, char **argv) //Set target wideband RX noise level to N0 sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); - // compute tx_gain to achieve target SNR (per resource element!) tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);//*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); - - if (n_frames==1) + if (n_frames==1) printf("tx_lev = %d (%d.%d dB,%f), gain %f\n",tx_lev,tx_lev_dB/10,tx_lev_dB,10*log10((double)tx_lev),10*log10(tx_gain)); - // fill measurement symbol (19) with noise for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - - ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -1268,7 +1221,6 @@ int main(int argc, char **argv) if (trials==0 && round==0) { // calculate freq domain representation to compute SINR freq_channel(UE2eNB, N_RB_DL,12*N_RB_DL + 1); - // snr=pow(10.0,.1*SNR); fprintf(csv_fdUL,"%f,%d,%d,%f,%f,%f,",SNR,tx_lev,tx_lev_dB,sigma2_dB,tx_gain,SNR2); @@ -1279,7 +1231,7 @@ int main(int argc, char **argv) // abs_channel = (eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x + eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y); channelx = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].x; channely = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].y; - // if(transmission_mode==5){ + // if(transmission_m==5){ fprintf(csv_fdUL,"%e+i*(%e),",channelx,channely); // } // else{ @@ -1297,39 +1249,42 @@ int main(int argc, char **argv) for (i=0; i<eNB->frame_parms.samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( - sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = + (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = + (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); } } if (n_frames<=10) { - printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int*) - &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int *) + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) - + eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level data symbol %f\n", + 10*log10(signal_energy((int *)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], + OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); } - SNRmeas = 10*log10(((double)signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int*) + SNRmeas = 10*log10(((double)signal_energy((int *)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], + OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int *) &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb); if (n_frames<=10) { printf("SNRmeas %f\n",SNRmeas); + LOG_M("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - LOG_M("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } - - ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; - eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - - - ru->feprx(ru); - phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); - + start_meas(&eNB->phy_proc_rx); + ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; + eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + ru->feprx(ru); + phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); + stop_meas(&eNB->phy_proc_rx); + if (cqi_flag > 0) { cqi_error = 0; @@ -1340,7 +1295,6 @@ int main(int argc, char **argv) cqi_error = 1; } } else { - } if (cqi_error == 1) { @@ -1358,15 +1312,10 @@ int main(int argc, char **argv) ack_errors++; // printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]); + // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { + iter_trials++; - - // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { - - if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { - - // avg_iter += ret; - iter_trials++; - + if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { if (n_frames==1) { printf("No ULSCH errors found, o_ACK[0]= %d, cqi_crc_status=%d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0],eNB->ulsch[0]->harq_processes[harq_pid]->cqi_crc_status); @@ -1380,9 +1329,6 @@ int main(int argc, char **argv) round=5; } else { - // avg_iter += ret-1; - iter_trials++; - errs[round]++; if (n_frames==1) { @@ -1395,7 +1341,6 @@ int main(int argc, char **argv) Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; Kr_bytes = Kr>>3; - printf("Decoded_output (Segment %d):\n",s); for (i=0; i<Kr_bytes; i++) @@ -1404,169 +1349,80 @@ int main(int argc, char **argv) } dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); + if (round == 4) exit(-1); } - if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); + if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); + round++; if (n_frames==1) { printf("ULSCH in error in round %d\n",round); } } // ulsch error - } // round // printf("\n"); if ((errs[0]>=100) && (trials>(n_frames/2))) break; - if (xforms==1) - phy_scope_eNB(form_enb,eNB,0); - - /*calculate the total processing time for each packet, get the max, min, and number of packets that exceed t>3000us*/ - - double t_tx = (double)UE->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)UE->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)UE->ulsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)UE->ulsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + if (xforms==1) + phy_scope_eNB(form_enb,eNB,0); + double t_tx = inMicroS(UE->phy_proc_tx.p_time); + double t_tx_ifft = inMicroS(UE->ofdm_mod_stats.p_time); + double t_tx_mod = inMicroS(UE->ulsch_modulation_stats.p_time); + double t_tx_enc = inMicroS(UE->ulsch_encoding_stats.p_time); + double t_rx = inMicroS(eNB->phy_proc_rx.p_time); + double t_rx_fft = inMicroS(ru->ofdm_demod_stats.p_time); + double t_rx_demod = inMicroS(eNB->ulsch_demodulation_stats.p_time); + double t_rx_dec = inMicroS(eNB->ulsch_decoding_stats.p_time); - double t_rx = (double)eNB->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)ru->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)eNB->ulsch_demodulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)eNB->ulsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; - - if (t_tx > t_tx_max) - t_tx_max = t_tx; - - if (t_tx < t_tx_min) - t_tx_min = t_tx; - - if (t_rx > t_rx_max) - t_rx_max = t_rx; - - if (t_rx < t_rx_min) - t_rx_min = t_rx; - - if (t_tx > 2000) + if (t_tx > 2000 )// 2ms is too much time for a subframe n_tx_dropped++; - if (t_rx > 2000) + if (t_rx > 2000 ) n_rx_dropped++; - push_front(&time_vector_tx, t_tx); - push_front(&time_vector_tx_ifft, t_tx_ifft); - push_front(&time_vector_tx_mod, t_tx_mod); - push_front(&time_vector_tx_enc, t_tx_enc); - - push_front(&time_vector_rx, t_rx); - push_front(&time_vector_rx_fft, t_rx_fft); - push_front(&time_vector_rx_demod, t_rx_demod); - push_front(&time_vector_rx_dec, t_rx_dec); - - + appendVarArray(table_tx, &t_tx); + appendVarArray(table_tx_ifft, &t_tx_ifft); + appendVarArray(table_tx_mod, &t_tx_mod ); + appendVarArray(table_tx_enc, &t_tx_enc ); + appendVarArray(table_rx, &t_rx ); + appendVarArray(table_rx_fft, &t_rx_fft ); + appendVarArray(table_rx_demod, &t_rx_demod ); + appendVarArray(table_rx_dec, &t_rx_dec ); } //trials - double table_tx[time_vector_tx.size]; - totable(table_tx, &time_vector_tx); - double table_tx_ifft[time_vector_tx_ifft.size]; - totable(table_tx_ifft, &time_vector_tx_ifft); - double table_tx_mod[time_vector_tx_mod.size]; - totable(table_tx_mod, &time_vector_tx_mod); - double table_tx_enc[time_vector_tx_enc.size]; - totable(table_tx_enc, &time_vector_tx_enc); - - double table_rx[time_vector_rx.size]; - totable(table_rx, &time_vector_rx); - double table_rx_fft[time_vector_rx_fft.size]; - totable(table_rx_fft, &time_vector_rx_fft); - double table_rx_demod[time_vector_rx_demod.size]; - totable(table_rx_demod, &time_vector_rx_demod); - double table_rx_dec[time_vector_rx_dec.size]; - totable(table_rx_dec, &time_vector_rx_dec); - // sort table - qsort (table_tx, time_vector_tx.size, sizeof(double), &compare); - qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); + qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble); + qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble); + qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble); + qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble); + qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble); + qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble); + qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble); + qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble); if (dump_table == 1 ) { - int n; set_component_filelog(SIM); // file located in /tmp/usim.txt - LOG_F(SIM,"The transmitter raw data: \n"); - - for (n=0; n< time_vector_tx.size; n++) { - // printf("%f ", table_tx[n]); - LOG_F(SIM,"%f ", table_tx[n]); - } - - LOG_F(SIM,"\n"); - LOG_F(SIM,"The receiver raw data: \n"); - - for (n=0; n< time_vector_rx.size; n++) { - // printf("%f ", table_rx[n]); - LOG_F(SIM,"%f ", table_rx[n]); - } - - LOG_F(SIM,"\n"); + LOG_UDUMPMSG(SIM,dataArray(table_tx),table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n"); } - double tx_median = table_tx[time_vector_tx.size/2]; - double tx_q1 = table_tx[time_vector_tx.size/4]; - double tx_q3 = table_tx[3*time_vector_tx.size/4]; - - double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2]; - double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4]; - double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4]; - - double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2]; - double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4]; - double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4]; - - double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2]; - double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4]; - double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4]; - - double rx_median = table_rx[time_vector_rx.size/2]; - double rx_q1 = table_rx[time_vector_rx.size/4]; - double rx_q3 = table_rx[3*time_vector_rx.size/4]; - - double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2]; - double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4]; - double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4]; - - double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2]; - double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4]; - double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4]; - - double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2]; - double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4]; - double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4]; - - double std_phy_proc_tx=0; - double std_phy_proc_tx_ifft=0; - double std_phy_proc_tx_mod=0; - double std_phy_proc_tx_enc=0; - - double std_phy_proc_rx=0; - double std_phy_proc_rx_fft=0; - double std_phy_proc_rx_demod=0; - double std_phy_proc_rx_dec=0; - printf("\n**********rb: %d ***mcs : %d *********SNR = %f dB (%f): TX %d dB (gain %f dB), N0W %f dB, I0 %d dB, delta_IF %d [ (%d,%d) dB / (%d,%d) dB ]**************************\n", nb_rb,mcs,SNR,SNR2, tx_lev_dB, 20*log10(tx_gain), (double)N0, eNB->measurements.n0_power_tot_dB, - get_hundred_times_delta_IF(UE,eNB_id,harq_pid) , + get_hundred_times_delta_IF(UE,eNB_id,harq_pid), dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]), dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]), eNB->measurements.n0_power_dB[0], eNB->measurements.n0_power_dB[1]); - effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); - printf("Errors (%d/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e) => effective rate %f (%3.1f%%,%f,%f), normalized delay %f (%f)\n", errs[0], round_trials[0], @@ -1598,7 +1454,6 @@ int main(int argc, char **argv) if (eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0] > 0) printf("ACK/NAK errors %d/%d\n",ack_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]); - fprintf(bler_fd,"%f;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d\n", SNR, mcs, @@ -1613,112 +1468,53 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3]); - + double timeBase=1/(1000*cpu_freq_GHz); if (dump_perf==1) { printf("UE TX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_tx = sqrt((double)UE->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_tx.trials - pow((double)UE->phy_proc_tx.diff/UE->phy_proc_tx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc tx :%f us (%d trials)\n",(double)UE->phy_proc_tx.diff/UE->phy_proc_tx.trials/cpu_freq_GHz/1000.0,UE->phy_proc_tx.trials); - printf("|__ Statistics std: %f us max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, - n_tx_dropped); - std_phy_proc_tx_ifft = sqrt((double)UE->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ofdm_mod_stats.trials - pow((double)UE->ofdm_mod_stats.diff/UE->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_mod time :%f us (%d trials)\n",(double)UE->ofdm_mod_stats.diff/UE->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,UE->ofdm_mod_stats.trials); - printf("|__ Statistics std: %f us median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - std_phy_proc_tx_mod = sqrt((double)UE->ulsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ulsch_modulation_stats.trials - pow((double)UE->ulsch_modulation_stats.diff/UE->ulsch_modulation_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH modulation time :%f us (%d trials)\n",(double)UE->ulsch_modulation_stats.diff/UE->ulsch_modulation_stats.trials/cpu_freq_GHz/1000.0, - UE->ulsch_modulation_stats.trials); - printf("|__ Statistics std: %f us median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - std_phy_proc_tx_enc = sqrt((double)UE->ulsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ulsch_encoding_stats.trials - pow((double)UE->ulsch_encoding_stats.diff/UE->ulsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH encoding time :%f us (%d trials)\n",(double)UE->ulsch_encoding_stats.diff/UE->ulsch_encoding_stats.trials/cpu_freq_GHz/1000.0, - UE->ulsch_encoding_stats.trials); - printf("|__ Statistics std: %f us median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - printf("|__ ULSCH segmentation time :%f us (%d trials)\n",(double)UE->ulsch_segmentation_stats.diff/UE->ulsch_segmentation_stats.trials/cpu_freq_GHz/1000.0, - UE->ulsch_segmentation_stats.trials); - printf("|__ ULSCH turbo encoding time :%f us (%d trials)\n", - ((double)UE->ulsch_turbo_encoding_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_turbo_encoding_stats.diff/UE->ulsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_turbo_encoding_stats.trials); - printf("|__ ULSCH rate-matching time :%f us (%d trials)\n", - ((double)UE->ulsch_rate_matching_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_rate_matching_stats.diff/UE->ulsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_rate_matching_stats.trials); - printf("|__ ULSCH sub-block interleaving time :%f us (%d trials)\n", - ((double)UE->ulsch_interleaving_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_interleaving_stats.diff/UE->ulsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_interleaving_stats.trials); - printf("|__ ULSCH multiplexing time :%f us (%d trials)\n", - ((double)UE->ulsch_multiplexing_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_multiplexing_stats.diff/UE->ulsch_multiplexing_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_multiplexing_stats.trials); - - printf("\n\neNB RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)eNB->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->phy_proc_rx.trials - pow((double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_rx.trials); - printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, - n_rx_dropped); - std_phy_proc_rx_fft = sqrt((double)ru->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/ru->ofdm_demod_stats.trials - pow((double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_demod time :%f us (%d trials)\n",(double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - ru->ofdm_demod_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - std_phy_proc_rx_demod = sqrt((double)eNB->ulsch_demodulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ulsch_demodulation_stats.trials - pow((double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH demodulation time :%f us (%d trials)\n",(double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000.0, - eNB->ulsch_demodulation_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n", std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3); - std_phy_proc_rx_dec = sqrt((double)eNB->ulsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ulsch_decoding_stats.trials - pow((double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH Decoding time (%.2f Mbit/s, avg iter %f) :%f us (%d trials, max %f)\n", - UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,(double)avg_iter/iter_trials, - (double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_decoding_stats.trials, - (double)eNB->ulsch_decoding_stats.max/cpu_freq_GHz/1000.0); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - printf("|__ sub-block interleaving %f us (%d trials)\n", - (double)eNB->ulsch_deinterleaving_stats.diff/eNB->ulsch_deinterleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_deinterleaving_stats.trials); - printf("|__ demultiplexing %f us (%d trials)\n", - (double)eNB->ulsch_demultiplexing_stats.diff/eNB->ulsch_demultiplexing_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_demultiplexing_stats.trials); - printf("|__ rate-matching %f us (%d trials)\n", - (double)eNB->ulsch_rate_unmatching_stats.diff/eNB->ulsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_rate_unmatching_stats.trials); - printf("|__ turbo_decoder(%d bits) %f us (%d cycles, %d trials)\n", - eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : eNB->ulsch[0]->harq_processes[harq_pid]->Kplus, - (double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0, - (int)((double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials),eNB->ulsch_turbo_decoding_stats.trials); - printf(" |__ init %f us (cycles/iter %f, %d trials)\n", - (double)eNB->ulsch_tc_init_stats.diff/eNB->ulsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_init_stats.diff/eNB->ulsch_tc_init_stats.trials/((double)avg_iter/iter_trials), - eNB->ulsch_tc_init_stats.trials); - printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n", - (double)eNB->ulsch_tc_alpha_stats.diff/eNB->ulsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_alpha_stats.diff/eNB->ulsch_tc_alpha_stats.trials*2, - eNB->ulsch_tc_alpha_stats.trials); - printf(" |__ beta %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_beta_stats.diff/eNB->ulsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_beta_stats.diff/eNB->ulsch_tc_beta_stats.trials*2, - eNB->ulsch_tc_beta_stats.trials); - printf(" |__ gamma %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_gamma_stats.diff/eNB->ulsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_gamma_stats.diff/eNB->ulsch_tc_gamma_stats.trials*2, - eNB->ulsch_tc_gamma_stats.trials); - printf(" |__ ext %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_ext_stats.diff/eNB->ulsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_ext_stats.diff/eNB->ulsch_tc_ext_stats.trials*2, - eNB->ulsch_tc_ext_stats.trials); - printf(" |__ intl1 %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_intl1_stats.diff/eNB->ulsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_intl1_stats.diff/eNB->ulsch_tc_intl1_stats.trials, - eNB->ulsch_tc_intl1_stats.trials); - printf(" |__ intl2+HD+CRC %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_intl2_stats.diff/eNB->ulsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_intl2_stats.diff/eNB->ulsch_tc_intl2_stats.trials, - eNB->ulsch_tc_intl2_stats.trials); + printDistribution(&UE->phy_proc_tx,table_tx,"Total PHY proc tx"); + printDistribution(&UE->ofdm_mod_stats, table_tx_ifft, "OFDM_mod time"); + printDistribution(&UE->ulsch_modulation_stats,table_tx_mod, "ULSCH modulation time"); + printDistribution(&UE->ulsch_encoding_stats,table_tx_enc, "ULSCH encoding time"); + printStatIndent(&UE->ulsch_segmentation_stats,"ULSCH segmentation time"); + printStatIndent(&UE->ulsch_turbo_encoding_stats,"ULSCH turbo encoding time"); + printStatIndent(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time"); + printStatIndent(&UE->ulsch_interleaving_stats,"ULSCH sub-block interleaving"); + printStatIndent(&UE->ulsch_multiplexing_stats,"ULSCH multiplexing time"); + printDistribution(&eNB->phy_proc_rx,table_rx,"\nTotal PHY proc rx subframe"); + printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"OFDM_demod time"); + printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"ULSCH demodulation time"); + printf("ULSCH Decoding time (%.2f Mbit/s, avg iter %.2f) :%.2f us (%d trials, max %.2f)\n", + UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,(double)iter_trials, + (double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials*timeBase, + eNB->ulsch_decoding_stats.trials, + (double)eNB->ulsch_decoding_stats.max*timeBase); + printf("|__ Statistics std: %.2fus median %.2fus q1 %.2fus q3 %.2fus \n", + squareRoot(&eNB->ulsch_decoding_stats), + median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); + printStatIndent(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" ); + printStatIndent(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" ); + printStatIndent(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" ); + printf("|__ turbo_decoder(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? + eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : + eNB->ulsch[0]->harq_processes[harq_pid]->Kplus, + eNB->ulsch_tc_intl1_stats.trials/(double)eNB->ulsch_tc_init_stats.trials, + (double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials*timeBase, + (int)((double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials), + eNB->ulsch_turbo_decoding_stats.trials); + printStatIndent2(&eNB->ulsch_tc_init_stats,"init", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_alpha_stats,"alpha", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_beta_stats,"beta", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_gamma_stats,"gamma", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_ext_stats,"ext", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_intl1_stats,"turbo internal interleaver", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_intl2_stats,"intl2+HardDecode+CRC", eNB->ulsch_tc_init_stats.trials); } if(abstx) { //ABSTRACTION blerr= (double)errs[1]/(round_trials[1]); //printf("hata yok XX,"); - - blerr = (double)errs[0]/(round_trials[0]); if(saving_bler==0) @@ -1726,12 +1522,9 @@ int main(int argc, char **argv) // printf("hata yok XX,"); - if(blerr<1) saving_bler = 0; else saving_bler =1; - - } //ABStraction if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { @@ -1749,7 +1542,6 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3]); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3;ND;\n"); fprintf(time_meas_fd,"%f;%d;%d;%f;%2.1f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%f;%f;", SNR, @@ -1773,7 +1565,6 @@ int main(int argc, char **argv) (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->ulsch[0]->harq_processes[harq_pid]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); - //fprintf(time_meas_fd,"UE_PROC_TX(%d); OFDM_MOD(%d); UL_MOD(%d); UL_ENC(%d); eNB_PROC_RX(%d); OFDM_DEMOD(%d); UL_DEMOD(%d); UL_DECOD(%d);\n", fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d;", UE->phy_proc_tx.trials, @@ -1795,52 +1586,52 @@ int main(int argc, char **argv) get_time_meas_us(&eNB->ulsch_demodulation_stats), get_time_meas_us(&eNB->ulsch_decoding_stats) ); - //fprintf(time_meas_fd,"UE_PROC_TX_STD;UE_PROC_TX_MAX;UE_PROC_TX_MIN;UE_PROC_TX_MED;UE_PROC_TX_Q1;UE_PROC_TX_Q3;UE_PROC_TX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); //fprintf(time_meas_fd,"IFFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->ofdm_mod_stats), + median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft)); //fprintf(time_meas_fd,"MOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->ulsch_modulation_stats), + median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod)); //fprintf(time_meas_fd,"ENC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->ulsch_encoding_stats), + median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc)); //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(&eNB->phy_proc_rx), t_rx_max, t_rx_min, + median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&ru->ofdm_demod_stats), + median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft)); //fprintf(time_meas_fd,"DEMOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->ulsch_demodulation_stats), + median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod)); //fprintf(time_meas_fd,"DEC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - - + fprintf(time_meas_fd,"%f;%f;%f;%f\n", + squareRoot(&eNB->ulsch_decoding_stats), + median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); break; } else if (test_perf !=0 ) { printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); } - if (((double)errs[0]/(round_trials[0]))<1e-2) break; - } // SNR + } // SNR // - - //LOG_M("chestim_f.m","chestf",eNB->pusch_vars[0]->drs_ch_estimates[0][0],300*12,2,1); // LOG_M("chestim_t.m","chestt",eNB->pusch_vars[0]->drs_ch_estimates_time[0][0], (frame_parms->ofdm_symbol_size)*2,2,1); - }//ch realization - oai_exit=1; pthread_cond_signal(&ru->proc.cond_fep); @@ -1855,7 +1646,6 @@ int main(int argc, char **argv) fclose (time_meas_fd); return(0); - } diff --git a/openair1/SIMULATION/LTE_PHY/unitary_defs.h b/openair1/SIMULATION/LTE_PHY/unitary_defs.h index 133656a5626cdf920c4e1ae095ca2de83cf295c5..1f91df1306e0f71e0165bec462c482b9130703c3 100644 --- a/openair1/SIMULATION/LTE_PHY/unitary_defs.h +++ b/openair1/SIMULATION/LTE_PHY/unitary_defs.h @@ -22,10 +22,14 @@ openair0_device openair0; volatile int oai_exit=0; -void exit_fun(const char *s) { exit(-1); } +void exit_function(const char* file, const char* function, const int line,const char *s) { + const char * msg= s==NULL ? "no comment": s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); +} extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; extern unsigned char offset_mumimo_llr_drange_fix; -extern unsigned short dftsizes[33]; -extern short *ul_ref_sigs[30][2][33]; +extern unsigned short dftsizes[34]; +extern short *ul_ref_sigs[30][2][34]; diff --git a/common/utils/itti/signals.h b/openair2/COMMON/flexran_messages_def.h similarity index 84% rename from common/utils/itti/signals.h rename to openair2/COMMON/flexran_messages_def.h index 5277e216a3d4a19230991d2f8eafdb86abfd2d16..fdcdf698dc76b45c29f13a4d186b99d1fb931c2e 100644 --- a/common/utils/itti/signals.h +++ b/openair2/COMMON/flexran_messages_def.h @@ -19,11 +19,11 @@ * contact@openairinterface.org */ -#ifndef SIGNALS_H_ -#define SIGNALS_H_ - -int signal_mask(void); - -int signal_handle(int *end); +/* + * flexran_messages_def.h + * + * Created on: Apr 26, 2018 + * Author: R. Schmidt + */ -#endif /* SIGNALS_H_ */ +MESSAGE_DEF(SOFT_RESTART_MESSAGE, MESSAGE_PRIORITY_MED_PLUS, IttiMsgEmpty, soft_restart_message) diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h index 9cc41a70eaa3d456a512cf475f7dcfc828c80431..27723eec15937c7ce204bc4f4e6e9190b7505bfb 100644 --- a/openair2/COMMON/gtpv1_u_messages_def.h +++ b/openair2/COMMON/gtpv1_u_messages_def.h @@ -25,3 +25,4 @@ MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_del MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_enb_delete_tunnel_resp_t, Gtpv1uDeleteTunnelResp) MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_ind_t, Gtpv1uTunnelDataInd) MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_req_t, Gtpv1uTunnelDataReq) +MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 4d09062beb7b8dde6b29ed16fe7634eaacee2f1a..0118a78f6d9f43652414f7c298351c14018d1d96 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -33,6 +33,7 @@ #define GTPV1U_ENB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDeleteTunnelResp #define GTPV1U_ENB_TUNNEL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataInd #define GTPV1U_ENB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataReq +#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF @@ -98,4 +99,8 @@ typedef struct gtpv1u_enb_tunnel_data_req_s { rb_id_t rab_id; } gtpv1u_enb_tunnel_data_req_t; +typedef struct { + in_addr_t enb_ip_address_for_S1u_S12_S4_up; + tcp_udp_port_t enb_port_for_S1u_S12_S4_up; +} Gtpv1uS1Req; #endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h index 2434d157767bb2369c53eaf4aa2cb5fe07f5588b..f6e2dd0f4b0159defbbdc18c065957045972a3ec 100644 --- a/openair2/COMMON/messages_def.h +++ b/openair2/COMMON/messages_def.h @@ -38,4 +38,4 @@ #include "sctp_messages_def.h" #include "udp_messages_def.h" #include "gtpv1_u_messages_def.h" - +#include "flexran_messages_def.h" diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 3f736e5b3cf5406c1b22d930142320aa393282dc..843f6458164472eb52776c7b416682f46d069e4c 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -34,9 +34,6 @@ #include <stdint.h> #endif -#if defined(ENABLE_ITTI) -#include "itti_types.h" -#endif //----------------------------------------------------------------------------- // GENERIC TYPES //----------------------------------------------------------------------------- @@ -110,9 +107,15 @@ typedef enum { CR_HOL = 2, CR_LC = 3, CR_CQI = 4, - CR_NUM = 5 + CR_LCP = 5, + CR_NUM = 6 } sorting_criterion_t; +typedef enum { + POL_FAIR = 0, + POL_GREEDY = 1, + POL_NUM = 2 +} accounting_policy_t; //----------------------------------------------------------------------------- // PHY TYPES //----------------------------------------------------------------------------- @@ -288,4 +291,7 @@ typedef struct protocol_ctxt_s { (CTXT_Pp)->rnti #define CHECK_CTXT_ARGS(CTXT_Pp) + +#define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) +void exit_function(const char* file, const char* function, const int line, const char* s); #endif diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 4a0137d4b6e5ae560e0371663566adc493519d94..12a06f7c659838334b8ff87f175840810f16c0ef 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -97,9 +97,10 @@ typedef struct RrcConfigurationReq_s { uint16_t tac; - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; paging_drx_t default_drx; diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index 4a5f492b0baa3f4685c8de48f342ff6075e02d8f..f56a340cb24d7df4c9db45b4c6f6b156568c2817 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -325,12 +325,14 @@ typedef struct s1ap_register_enb_req_s { /* Tracking area code */ uint16_t tac; +#define PLMN_LIST_MAX_SIZE 6 /* Mobile Country Code * Mobile Network Code */ - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; /* Default Paging DRX of the eNB as defined in TS 36.304 */ paging_drx_t default_drx; @@ -342,6 +344,8 @@ typedef struct s1ap_register_enb_req_s { uint8_t nb_mme; /* List of MME to connect to */ net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS]; + uint8_t broadcast_plmn_num[S1AP_MAX_NB_MME_IP_ADDRESS]; + uint8_t broadcast_plmn_index[S1AP_MAX_NB_MME_IP_ADDRESS][PLMN_LIST_MAX_SIZE]; /* Number of SCTP streams used for a mme association */ uint16_t sctp_in_streams; @@ -372,6 +376,10 @@ typedef struct s1ap_nas_first_req_s { /* UE id for initial connection to S1AP */ uint16_t ue_initial_id; + /* the chosen PLMN identity as index, see TS 36.331 6.2.2 RRC Connection + * Setup Complete. This index here is zero-based, unlike the standard! */ + int selected_plmn_identity; + /* Establishment cause as sent by UE */ rrc_establishment_cause_t establishment_cause; diff --git a/openair2/COMMON/sctp_messages_def.h b/openair2/COMMON/sctp_messages_def.h index d4248b7bc342edc307081d61aa43c572ebe5e924..a7feb52a320a1efa211eca6cebfe29683f2cbe8a 100644 --- a/openair2/COMMON/sctp_messages_def.h +++ b/openair2/COMMON/sctp_messages_def.h @@ -19,11 +19,14 @@ * contact@openairinterface.org */ -MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ , MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req) -MESSAGE_DEF(SCTP_NEW_ASSOCIATION_RESP, MESSAGE_PRIORITY_MED, sctp_new_association_resp_t , sctp_new_association_resp) -MESSAGE_DEF(SCTP_NEW_ASSOCIATION_IND , MESSAGE_PRIORITY_MED, sctp_new_association_ind_t , sctp_new_association_ind) -MESSAGE_DEF(SCTP_REGISTER_UPPER_LAYER, MESSAGE_PRIORITY_MED, sctp_listener_register_upper_layer_t, sctp_listener_register_upper_layer) -MESSAGE_DEF(SCTP_DATA_REQ, MESSAGE_PRIORITY_MED, sctp_data_req_t , sctp_data_req) -MESSAGE_DEF(SCTP_DATA_IND, MESSAGE_PRIORITY_MED, sctp_data_ind_t , sctp_data_ind) -MESSAGE_DEF(SCTP_INIT_MSG, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init) -MESSAGE_DEF(SCTP_CLOSE_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_close_association_t , sctp_close_association) +MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ , MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req) +MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ_MULTI, MESSAGE_PRIORITY_MED, sctp_new_association_req_multi_t , sctp_new_association_req_multi) +MESSAGE_DEF(SCTP_NEW_ASSOCIATION_RESP, MESSAGE_PRIORITY_MED, sctp_new_association_resp_t , sctp_new_association_resp) +MESSAGE_DEF(SCTP_NEW_ASSOCIATION_IND , MESSAGE_PRIORITY_MED, sctp_new_association_ind_t , sctp_new_association_ind) +MESSAGE_DEF(SCTP_REGISTER_UPPER_LAYER, MESSAGE_PRIORITY_MED, sctp_listener_register_upper_layer_t , sctp_listener_register_upper_layer) +MESSAGE_DEF(SCTP_DATA_REQ, MESSAGE_PRIORITY_MED, sctp_data_req_t , sctp_data_req) +MESSAGE_DEF(SCTP_DATA_IND, MESSAGE_PRIORITY_MED, sctp_data_ind_t , sctp_data_ind) +MESSAGE_DEF(SCTP_INIT_MSG, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init) +MESSAGE_DEF(SCTP_INIT_MSG_MULTI_REQ, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init_multi) +MESSAGE_DEF(SCTP_INIT_MSG_MULTI_CNF, MESSAGE_PRIORITY_MED, sctp_init_msg_multi_cnf_t , sctp_init_msg_multi_cnf) +MESSAGE_DEF(SCTP_CLOSE_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_close_association_t , sctp_close_association) diff --git a/openair2/COMMON/sctp_messages_types.h b/openair2/COMMON/sctp_messages_types.h index 184e951acb3b8732c2e7b056d6204d20fddba0d8..9e363c0d8d993890b9c58ba3384b2a6370c6d70f 100644 --- a/openair2/COMMON/sctp_messages_types.h +++ b/openair2/COMMON/sctp_messages_types.h @@ -22,13 +22,16 @@ #ifndef SCTP_MESSAGES_TYPES_H_ #define SCTP_MESSAGES_TYPES_H_ -#define SCTP_NEW_ASSOCIATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req -#define SCTP_NEW_ASSOCIATION_RESP(mSGpTR)(mSGpTR)->ittiMsg.sctp_new_association_resp -#define SCTP_NEW_ASSOCIATION_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_ind -#define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind -#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req -#define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctp_init -#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association +#define SCTP_NEW_ASSOCIATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req +#define SCTP_NEW_ASSOCIATION_REQ_MULTI(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req_multi +#define SCTP_NEW_ASSOCIATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_resp +#define SCTP_NEW_ASSOCIATION_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_ind +#define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind +#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req +#define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctp_init +#define SCTP_INIT_MSG_MULTI_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_multi +#define SCTP_INIT_MSG_MULTI_CNF(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_msg_multi_cnf +#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association enum sctp_state_e { SCTP_STATE_CLOSED, @@ -56,6 +59,32 @@ typedef struct sctp_new_association_req_s { net_ip_address_t remote_address; } sctp_new_association_req_t; +typedef struct sctp_new_association_req_multi_s { + /* Upper layer connexion identifier */ + uint16_t ulp_cnx_id; + + /* The port to connect to */ + uint16_t port; + /* Payload Protocol Identifier to use */ + uint32_t ppid; + + /* Number of streams used for this association */ + uint16_t in_streams; + uint16_t out_streams; + + /* Local address to bind to */ + net_ip_address_t local_address; + /* Remote address to connect to */ + net_ip_address_t remote_address; + + /* Multi-socket descriptor */ + int multi_sd; +} sctp_new_association_req_multi_t; + +typedef struct sctp_init_msg_multi_cnf_s { + int multi_sd; +} sctp_init_msg_multi_cnf_t; + typedef struct sctp_new_association_ind_s { /* Assoc id of the new association */ int32_t assoc_id; diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index 4690bba42e5b91f4721d727b38d41da928e0c55a..d5555c183989b4573501e005620fba7b57302787 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -19,3 +19,24 @@ * contact@openairinterface.org */ +/* eNB application layer -> X2AP messages */ +/* ITTI LOG messages */ +/* ENCODER */ +MESSAGE_DEF(X2AP_RESET_REQUST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_reset_request_log) +MESSAGE_DEF(X2AP_RESOURCE_STATUS_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_resource_status_response_log) +MESSAGE_DEF(X2AP_RESOURCE_STATUS_FAILURE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_resource_status_failure_log) + +/* Messages for X2AP logging */ +MESSAGE_DEF(X2AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_setup_request_log) + + +/* eNB application layer -> X2AP messages */ +MESSAGE_DEF(X2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, x2ap_register_enb_req_t , x2ap_register_enb_req) + +/* X2AP -> eNB application layer messages */ +MESSAGE_DEF(X2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, x2ap_register_enb_cnf_t , x2ap_register_enb_cnf) +MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_deregistered_enb_ind_t , x2ap_deregistered_enb_ind) + +/* handover messages X2AP <-> RRC */ +MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req) +MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 4690bba42e5b91f4721d727b38d41da928e0c55a..c74a826ff84685c88ea9a36b6226ccbf58eee166 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -19,3 +19,162 @@ * contact@openairinterface.org */ +#ifndef X2AP_MESSAGES_TYPES_H_ +#define X2AP_MESSAGES_TYPES_H_ + +#include "PhysCellId.h" + +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. + +#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req +#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_MAX_NB_ENB_IP_ADDRESS 2 + +// eNB application layer -> X2AP messages +typedef struct x2ap_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; + + /* + * 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_x2_ip_address; + + /* Nb of MME to connect to */ + uint8_t nb_x2; + + /* List of target eNB to connect to for X2*/ + net_ip_address_t target_enb_x2_ip_address[X2AP_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 X2C*/ + uint32_t enb_port_for_X2C; +} x2ap_register_enb_req_t; + +//-------------------------------------------------------------------------------------------// +// X2AP -> eNB application layer messages +typedef struct x2ap_register_enb_cnf_s { + /* Nb of connected eNBs*/ + uint8_t nb_x2; +} x2ap_register_enb_cnf_t; + +typedef struct x2ap_deregistered_enb_ind_s { + /* Nb of connected eNBs */ + uint8_t nb_x2; +} x2ap_deregistered_enb_ind_t; + +//-------------------------------------------------------------------------------------------// +// X2AP <-> RRC +typedef struct x2ap_gummei_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_len; + uint8_t mme_code; + uint16_t mme_group_id; +} x2ap_gummei_t; + +typedef struct x2ap_lastvisitedcell_info_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_len; + PhysCellId_t target_physCellId; + cell_type_t cell_type; + uint64_t time_UE_StayedInCell; +}x2ap_lastvisitedcell_info_t; + +//used for src +typedef struct x2ap_handover_req_s { + int source_rnti; /* TODO: to be fixed/remove */ + int source_x2id; /* TODO: to be fixed/remove */ + + unsigned old_eNB_ue_s1ap_id:24; + + PhysCellId_t target_physCellId; + + x2ap_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]; + + /* ue_context_pP->ue_context.e_rab[i].param.sgw_addr; */ + + x2ap_lastvisitedcell_info_t lastvisitedcell_info; + + /* TODO: this parameter has to be removed */ + int target_mod_id; +} x2ap_handover_req_t; + +typedef struct x2ap_handover_req_ack_s { + int source_rnti; /* TODO: to be fixed/remove */ + int source_x2id; /* TODO: to be fixed/remove */ + /* TODO: this parameter has to be removed */ + int target_mod_id; + uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; + int rrc_buffer_size; + + uint32_t mme_ue_s1ap_id; +} x2ap_handover_req_ack_t; + +#endif /* X2AP_MESSAGES_TYPES_H_ */ 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 0545eeb3be11e59522aebcafb3161b4aaa61e60a..6cc3caced61a7f8324d0bf1fe2d7ccec01c6a25e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -38,7 +38,7 @@ #include "liblfds700.h" -#include "log.h" +#include "common/utils/LOG/log.h" /*Flags showing if a mac agent has already been registered*/ unsigned int mac_agent_registered[NUM_MAX_ENB]; @@ -52,6 +52,18 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; +/* the slice config as kept in the underlying system */ +Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; +/* a structure that keeps updates which will be reflected in slice_config later */ +Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; +/* indicates whether sc_update contains new data */ +int perform_slice_config_update_count = 1; +/* queue of incoming new UE<>slice association commands */ +Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; +int n_ue_slice_assoc_updates = 0; +/* mutex for sc_update: do not receive new config and write it at the same time */ +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, @@ -61,6 +73,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i, j, k; + int UE_id; int cc_id = 0; int enb_id = mod_id; @@ -70,6 +83,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, for (i = 0; i < report_config->nr_ue; i++) { + UE_id = flexran_get_ue_id(mod_id, i); + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; ue_report[i]->has_rnti = 1; @@ -91,7 +106,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) { - ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; + 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; } @@ -113,11 +128,11 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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, i, j + 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, i, j + 1); + 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; @@ -126,7 +141,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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 , i, j + 1); + 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; } @@ -140,7 +155,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) { // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + 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 @@ -161,7 +176,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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,i); + 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; @@ -178,7 +193,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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,i,j); + 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 @@ -197,7 +212,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; + 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; @@ -214,26 +229,26 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); csi11->n_wb_cqi = 1; - csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); + 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, i, 0); + 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, i, 0); + 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, i, 0); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, UE_id, 0); csi11->has_wb_pmi = 1; @@ -257,7 +272,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, goto error; protocol__flex_csi_p20__init(csi20); - csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); csi20->has_wb_cqi = 1; @@ -281,7 +296,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_p21__init(csi21); - // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside @@ -309,7 +324,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a12__init(csi12); - // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi12->sb_pmi = 1 ; //TODO inside @@ -324,17 +339,17 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a22__init(csi22); - // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // 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, i); + // 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, i); + // csi22->sb_list = flexran_get_ue_wcqi (enb_id, UE_id); } @@ -347,7 +362,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a20__init(csi20); - // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, UE_id); // csi20->has_wb_cqi = 1; // csi20>sb_cqi = 1 ; //TODO inside @@ -477,8 +492,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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,i, j) != -1){ - full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id,i,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; } } @@ -499,69 +514,69 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, protocol__flex_mac_stats__init(macstats); - macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i, cc_id); + 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, i); + 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, i, cc_id)); + mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, UE_id, cc_id)); if (mac_sdus == NULL) goto error; - macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); + 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++){ @@ -569,10 +584,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, 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, i, cc_id, 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, i, cc_id, mac_sdus[j]->lcid); + 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; @@ -882,7 +897,6 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle for (j = 0; j < 8; j++) { if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 1) { available_harq[i] = j; - sf_trigger_msg->n_dl_info++; break; } } @@ -891,10 +905,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10); - /*TODO: Fill in the number of dl HARQ related info, based on the number of currently - *transmitting UEs - */ - // sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id); + sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id); Protocol__FlexDlInfo **dl_info = NULL; @@ -904,33 +915,31 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle goto error; i = -1; //Fill the status of the current HARQ process for each UE - for(UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (available_harq[UE_id] < 0) { + for(i = 0; i < sf_trigger_msg->n_dl_info; i++) { + if (available_harq[i] < 0) continue; - } else { - i++; - } dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo)); if(dl_info[i] == NULL) goto error; + UE_id = flexran_get_ue_id(mod_id, i); protocol__flex_dl_info__init(dl_info[i]); dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); dl_info[i]->has_rnti = 1; /*Fill in the right id of this round's HARQ process for this UE*/ // uint8_t harq_id; //uint8_t harq_status; - // flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status); + // flexran_get_harq(mod_id, UE_PCCID(mod_id, UE_id), i, frame, subframe, &harq_id, &harq_status); dl_info[i]->harq_process_id = available_harq[UE_id]; if (RC.mac && RC.mac[mod_id]) - RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 0; + RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id, UE_id)][UE_id].harq_pid = 0; dl_info[i]->has_harq_process_id = 1; /* Fill in the status of the HARQ process (2 TBs)*/ dl_info[i]->n_harq_status = 2; dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status); for (j = 0; j < dl_info[i]->n_harq_status; j++) { - dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[i].round[UE_PCCID(mod_id,i)][j]; + dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[UE_id].round[UE_PCCID(mod_id, UE_id)][j]; // TODO: This should be different per TB } // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d and harq %d (round %d)\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10, dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]); @@ -938,7 +947,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Need to make a retransmission for harq %d (round %d)\n", flexran_get_current_frame(mod_id), flexran_get_current_subframe(mod_id), dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]); } /*Fill in the serving cell index for this UE */ - dl_info[i]->serv_cell_index = UE_PCCID(mod_id,i); + dl_info[i]->serv_cell_index = UE_PCCID(mod_id, UE_id); dl_info[i]->has_serv_cell_index = 1; } } @@ -962,18 +971,21 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle if(ul_info[i] == NULL) goto error; protocol__flex_ul_info__init(ul_info[i]); - ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, i); + + UE_id = flexran_get_ue_id(mod_id, i); + + ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); ul_info[i]->has_rnti = 1; /* Fill in the Tx power control command for this UE (if available), * primary carrier */ - if(flexran_get_tpc(mod_id, i, 0) != 1){ + if(flexran_get_tpc(mod_id, UE_id, 0) != 1){ /* assume primary carrier */ - ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); + ul_info[i]->tpc = flexran_get_tpc(mod_id, UE_id, 0); ul_info[i]->has_tpc = 1; } else{ /* assume primary carrier */ - ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); + ul_info[i]->tpc = flexran_get_tpc(mod_id, UE_id, 0); ul_info[i]->has_tpc = 0; } /*TODO: fill in the amount of data in bytes in the MAC SDU received in this subframe for the @@ -987,7 +999,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle ul_info[i]->reception_status = PROTOCOL__FLEX_RECEPTION_STATUS__FLRS_OK; ul_info[i]->has_reception_status = 1; /*Fill in the serving cell index for this UE */ - ul_info[i]->serv_cell_index = UE_PCCID(mod_id,i); + ul_info[i]->serv_cell_index = UE_PCCID(mod_id, UE_id); ul_info[i]->has_serv_cell_index = 1; } } @@ -1260,8 +1272,17 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { lfds700_misc_prng_init(&ps[mod_id]); int num_elements = RINGBUFFER_SIZE + 1; //Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time - dl_mac_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) * num_elements); - lfds700_ringbuffer_init_valid_on_current_logical_core( &ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL ); + /* lfds700_ringbuffer_init_valid_on_current_logical_core()'s second argument + * must be aligned to LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES. From the + * documentation: "Heap allocated variables however will by no means be + * correctly aligned and an aligned malloc must be used." Therefore, we use + * posix_memalign */ + i = posix_memalign((void **)&dl_mac_config_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, "posix_memalign(): could not allocate aligned memory for lfds library\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core(&ringbuffer_state[mod_id], + dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL); for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { for (j = 0; j < 8; j++) { if (RC.mac && RC.mac[mod_id]) @@ -1372,8 +1393,229 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { return 0; } +void flexran_create_config_structures(mid_t mod_id) +{ + int i; + int n_dl = flexran_get_num_dl_slices(mod_id); + int m_ul = flexran_get_num_ul_slices(mod_id); + slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); + sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); + if (!slice_config[mod_id] || !sc_update[mod_id]) return; + + flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); + flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); + for (i = 0; i < n_dl; i++) { + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); + } + for (i = 0; i < m_ul; i++) { + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); + } +} +void flexran_check_and_remove_slices(mid_t mod_id) +{ + Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl; + Protocol__FlexDlSlice **dlreal = slice_config[mod_id]->dl; + int i = 0; + while (i < sc_update[mod_id]->n_dl) { + /* remove slices whose percentage is zero */ + if (dl[i]->percentage > 0) { + ++i; + continue; + } + if (flexran_remove_dl_slice(mod_id, i) < 1) { + LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", + mod_id, i, dl[i]->id); + ++i; + continue; + } + LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", + mod_id, i, dl[i]->id); + if (dl[i]->n_sorting > 0) free(dl[i]->sorting); + free(dl[i]->scheduler_name); + if (dlreal[i]->n_sorting > 0) { + dlreal[i]->n_sorting = 0; + free(dlreal[i]->sorting); + } + free(dlreal[i]->scheduler_name); + --sc_update[mod_id]->n_dl; + --slice_config[mod_id]->n_dl; + const size_t last = sc_update[mod_id]->n_dl; + /* we need to memcpy the higher slice to the position we just deleted */ + memcpy(dl[i], dl[last], sizeof(*dl[last])); + memset(dl[last], 0, sizeof(*dl[last])); + memcpy(dlreal[i], dlreal[last], sizeof(*dlreal[last])); + memset(dlreal[last], 0, sizeof(*dlreal[last])); + /* dont increase i but recheck the slice which has been copied to here */ + } + Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul; + Protocol__FlexUlSlice **ulreal = slice_config[mod_id]->ul; + i = 0; + while (i < sc_update[mod_id]->n_ul) { + if (ul[i]->percentage > 0) { + ++i; + continue; + } + if (flexran_remove_ul_slice(mod_id, i) < 1) { + LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", + mod_id, i, ul[i]->id); + ++i; + continue; + } + LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", + mod_id, i, ul[i]->id); + free(ul[i]->scheduler_name); + free(ulreal[i]->scheduler_name); + --sc_update[mod_id]->n_ul; + --slice_config[mod_id]->n_ul; + const size_t last = sc_update[mod_id]->n_ul; + /* see DL remarks */ + memcpy(ul[i], ul[last], sizeof(*ul[last])); + memset(ul[last], 0, sizeof(*ul[last])); + memcpy(ulreal[i], ulreal[last], sizeof(*ulreal[last])); + memset(ulreal[last], 0, sizeof(*ulreal[last])); + /* dont increase i but recheck the slice which has been copied to here */ + } +} +void flexran_agent_slice_update(mid_t mod_id) +{ + int i; + int changes = 0; + if (perform_slice_config_update_count <= 0) return; + perform_slice_config_update_count--; + pthread_mutex_lock(&sc_update_mtx); + if (!slice_config[mod_id]) { + /* if the configuration does not exist for agent, create from eNB structure + * and exit */ + flexran_create_config_structures(mod_id); + pthread_mutex_unlock(&sc_update_mtx); + return; + } + + /********* read existing config *********/ + /* simply update slice_config all the time and write new config + * (apply_new_slice_dl_config() only updates if changes are necessary) */ + slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); + slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); + for (i = 0; i < slice_config[mod_id]->n_dl; i++) { + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + } + for (i = 0; i < slice_config[mod_id]->n_ul; i++) { + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + } + + /********* write new config *********/ + /* check for removal (sc_update[X]->dl[Y].percentage == 0) + * and update sc_update & slice_config accordingly */ + flexran_check_and_remove_slices(mod_id); + + /* create new DL and UL slices if necessary */ + for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { + flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id); + } + for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { + flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id); + } + slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); + slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); + changes += apply_new_slice_config(mod_id, slice_config[mod_id], sc_update[mod_id]); + for (i = 0; i < slice_config[mod_id]->n_dl; i++) { + changes += apply_new_slice_dl_config(mod_id, + slice_config[mod_id]->dl[i], + sc_update[mod_id]->dl[i]); + flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + } + for (i = 0; i < slice_config[mod_id]->n_ul; i++) { + changes += apply_new_slice_ul_config(mod_id, + slice_config[mod_id]->ul[i], + sc_update[mod_id]->ul[i]); + flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + } + flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); + if (n_ue_slice_assoc_updates > 0) { + changes += apply_ue_slice_assoc_update(mod_id); + } + if (changes > 0) + LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes); + + pthread_mutex_unlock(&sc_update_mtx); +} + +Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) +{ + if (!slice_config[mod_id]) return NULL; + Protocol__FlexSliceConfig *config = NULL; + + pthread_mutex_lock(&sc_update_mtx); + config = flexran_agent_create_slice_config(slice_config[mod_id]->n_dl, + slice_config[mod_id]->n_ul); + if (!config) { + pthread_mutex_unlock(&sc_update_mtx); + return NULL; + } + config->has_intraslice_share_active = 1; + config->intraslice_share_active = slice_config[mod_id]->intraslice_share_active; + config->has_interslice_share_active = 1; + config->interslice_share_active = slice_config[mod_id]->interslice_share_active; + for (int i = 0; i < slice_config[mod_id]->n_dl; ++i) { + if (!config->dl[i]) continue; + config->dl[i]->has_id = 1; + config->dl[i]->id = slice_config[mod_id]->dl[i]->id; + config->dl[i]->has_label = 1; + config->dl[i]->label = slice_config[mod_id]->dl[i]->label; + config->dl[i]->has_percentage = 1; + config->dl[i]->percentage = slice_config[mod_id]->dl[i]->percentage; + config->dl[i]->has_isolation = 1; + config->dl[i]->isolation = slice_config[mod_id]->dl[i]->isolation; + config->dl[i]->has_priority = 1; + config->dl[i]->priority = slice_config[mod_id]->dl[i]->priority; + config->dl[i]->has_position_low = 1; + config->dl[i]->position_low = slice_config[mod_id]->dl[i]->position_low; + config->dl[i]->has_position_high = 1; + config->dl[i]->position_high = slice_config[mod_id]->dl[i]->position_high; + config->dl[i]->has_maxmcs = 1; + config->dl[i]->maxmcs = slice_config[mod_id]->dl[i]->maxmcs; + config->dl[i]->n_sorting = slice_config[mod_id]->dl[i]->n_sorting; + config->dl[i]->sorting = calloc(config->dl[i]->n_sorting, sizeof(Protocol__FlexDlSorting)); + if (!config->dl[i]->sorting) config->dl[i]->n_sorting = 0; + for (int j = 0; j < config->dl[i]->n_sorting; ++j) + config->dl[i]->sorting[j] = slice_config[mod_id]->dl[i]->sorting[j]; + config->dl[i]->has_accounting = 1; + config->dl[i]->accounting = slice_config[mod_id]->dl[i]->accounting; + config->dl[i]->scheduler_name = strdup(slice_config[mod_id]->dl[i]->scheduler_name); + } + for (int i = 0; i < slice_config[mod_id]->n_ul; ++i) { + if (!config->ul[i]) continue; + config->ul[i]->has_id = 1; + config->ul[i]->id = slice_config[mod_id]->ul[i]->id; + config->ul[i]->has_label = 1; + config->ul[i]->label = slice_config[mod_id]->ul[i]->label; + config->ul[i]->has_percentage = 1; + config->ul[i]->percentage = slice_config[mod_id]->ul[i]->percentage; + config->ul[i]->has_isolation = 1; + config->ul[i]->isolation = slice_config[mod_id]->ul[i]->isolation; + config->ul[i]->has_priority = 1; + config->ul[i]->priority = slice_config[mod_id]->ul[i]->priority; + config->ul[i]->has_first_rb = 1; + config->ul[i]->first_rb = slice_config[mod_id]->ul[i]->first_rb; + config->ul[i]->has_maxmcs = 1; + config->ul[i]->maxmcs = slice_config[mod_id]->ul[i]->maxmcs; + config->ul[i]->n_sorting = slice_config[mod_id]->ul[i]->n_sorting; + config->ul[i]->sorting = calloc(config->ul[i]->n_sorting, sizeof(Protocol__FlexUlSorting)); + if (!config->ul[i]->sorting) config->ul[i]->n_sorting = 0; + for (int j = 0; j < config->ul[i]->n_sorting; ++j) + config->ul[i]->sorting[j] = slice_config[mod_id]->ul[i]->sorting[j]; + config->ul[i]->has_accounting = 1; + config->ul[i]->accounting = slice_config[mod_id]->ul[i]->accounting; + config->ul[i]->scheduler_name = strdup(slice_config[mod_id]->ul[i]->scheduler_name); + } + + pthread_mutex_unlock(&sc_update_mtx); + return config; +} 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 03e7def95e04610e57503917c38dbafe9e6fb3d4..0d686a53eed6fa5c13fc39129e0aff4508b86056 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -87,4 +87,14 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface); /*Unregister technology specific callbacks*/ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface*xface); +/*************************************** + * FlexRAN agent - slice configuration * + ***************************************/ + +/* Inform controller about possibility to update slice configuration */ +void flexran_agent_slice_update(mid_t mod_id); + +/* return a pointer to the current config */ +Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id); + #endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 2acee0686f62165881d256e96eb09500274d0a30..8e0dc5726979861f68ae8fc707447774059a86d9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -31,6 +31,15 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" +#include "flexran_agent_mac_slice_verification.h" + +/* from flexran_agent_mac.c */ +extern Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; +extern Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; +extern int perform_slice_config_update_count; +extern Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; +extern int n_ue_slice_assoc_updates; +extern pthread_mutex_t sc_update_mtx; Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message, Protocol__FlexranMessage *old_message) { @@ -899,3 +908,721 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { return -1; } + +Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) +{ + int i; + Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig)); + if (!fsc) return NULL; + protocol__flex_slice_config__init(fsc); + + /* say there are n_dl slices but reserve memory for up to MAX_NUM_SLICES so + * we don't need to reserve again later */ + fsc->n_dl = n_dl; + fsc->dl = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexDlSlice *)); + if (!fsc->dl) fsc->n_dl = 0; + for (i = 0; i < MAX_NUM_SLICES; i++) { + fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice)); + if (!fsc->dl[i]) continue; + protocol__flex_dl_slice__init(fsc->dl[i]); + } + + /* as above */ + fsc->n_ul = m_ul; + fsc->ul = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexUlSlice *)); + if (!fsc->ul) fsc->n_ul = 0; + for (i = 0; i < MAX_NUM_SLICES; i++) { + fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice)); + if (!fsc->ul[i]) continue; + protocol__flex_ul_slice__init(fsc->ul[i]); + } + return fsc; +} + +void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s) +{ + s->intraslice_share_active = flexran_get_intraslice_sharing_active(mod_id); + s->has_intraslice_share_active = 1; + s->interslice_share_active = flexran_get_interslice_sharing_active(mod_id); + s->has_interslice_share_active = 1; +} + +void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice) +{ + dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx); + dl_slice->has_id = 1; + /* read label from corresponding sc_update entry or give default */ + dl_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; + dl_slice->has_label = 1; + for (int i = 0; i < sc_update[mod_id]->n_dl; i++) { + if (sc_update[mod_id]->dl[i]->id == dl_slice->id + && sc_update[mod_id]->dl[i]->has_label) { + dl_slice->label = sc_update[mod_id]->dl[i]->label; + break; + } + } + dl_slice->percentage = flexran_get_dl_slice_percentage(mod_id, slice_idx); + dl_slice->has_percentage = 1; + dl_slice->isolation = flexran_get_dl_slice_isolation(mod_id, slice_idx); + dl_slice->has_isolation = 1; + dl_slice->priority = flexran_get_dl_slice_priority(mod_id, slice_idx); + dl_slice->has_priority = 1; + dl_slice->position_low = flexran_get_dl_slice_position_low(mod_id, slice_idx); + dl_slice->has_position_low = 1; + dl_slice->position_high = flexran_get_dl_slice_position_high(mod_id, slice_idx); + dl_slice->has_position_high = 1; + dl_slice->maxmcs = flexran_get_dl_slice_maxmcs(mod_id, slice_idx); + dl_slice->has_maxmcs = 1; + dl_slice->n_sorting = flexran_get_dl_slice_sorting(mod_id, slice_idx, &dl_slice->sorting); + if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL; + dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx); + dl_slice->has_accounting = 1; + const char *s_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx); + if (!dl_slice->scheduler_name + || strcmp(dl_slice->scheduler_name, s_name) != 0) { + dl_slice->scheduler_name = realloc(dl_slice->scheduler_name, strlen(s_name) + 1); + strcpy(dl_slice->scheduler_name, s_name); + } +} + +void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice) +{ + ul_slice->id = flexran_get_ul_slice_id(mod_id, slice_idx); + ul_slice->has_id = 1; + /* read label from corresponding sc_update entry or give default */ + ul_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; + ul_slice->has_label = 1; + for (int i = 0; i < sc_update[mod_id]->n_ul; i++) { + if (sc_update[mod_id]->ul[i]->id == ul_slice->id + && sc_update[mod_id]->ul[i]->has_label) { + ul_slice->label = sc_update[mod_id]->ul[i]->label; + break; + } + } + ul_slice->percentage = flexran_get_ul_slice_percentage(mod_id, slice_idx); + ul_slice->has_percentage = 1; + /*ul_slice->isolation = flexran_get_ul_slice_isolation(mod_id, slice_idx);*/ + ul_slice->has_isolation = 0; + /*ul_slice->priority = flexran_get_ul_slice_priority(mod_id, slice_idx);*/ + ul_slice->has_priority = 0; + ul_slice->first_rb = flexran_get_ul_slice_first_rb(mod_id, slice_idx); + ul_slice->has_first_rb = 1; + /*ul_slice-> = flexran_get_ul_slice_length_rb(mod_id, slice_idx); + ul_slice->has_length_rb = 0;*/ + ul_slice->maxmcs = flexran_get_ul_slice_maxmcs(mod_id, slice_idx); + ul_slice->has_maxmcs = 1; + ul_slice->n_sorting = 0; + /*if (ul_slice->sorting) { + free(ul_slice->sorting); + ul_slice->sorting = NULL; + } + ul_slice->n_sorting = flexran_get_ul_slice_sorting(mod_id, slice_idx, &ul_slice->sorting); + if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/ + /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/ + ul_slice->has_accounting = 0; + const char *s_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx); + if (!ul_slice->scheduler_name + || strcmp(ul_slice->scheduler_name, s_name) != 0) { + ul_slice->scheduler_name = realloc(ul_slice->scheduler_name, strlen(s_name) + 1); + strcpy(ul_slice->scheduler_name, s_name); + } +} + +int check_dl_sorting_update(Protocol__FlexDlSlice *old, Protocol__FlexDlSlice *new) +{ + /* sorting_update => true when old->n_sorting == 0 or different numbers of + * elements; otherwise will check * element-wise */ + int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); + for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { + sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); + } + return sorting_update; +} + +int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *new) +{ + /* sorting_update => true when old->n_sorting == 0 or different numbers of + * elements; otherwise will check * element-wise */ + int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); + for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { + sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); + } + return sorting_update; +} + +void overwrite_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *exist, Protocol__FlexSliceConfig *update) +{ + if (update->has_intraslice_share_active + && exist->intraslice_share_active != update->intraslice_share_active) { + LOG_I(FLEXRAN_AGENT, "[%d] update intraslice_share_active: %d -> %d\n", + mod_id, exist->intraslice_share_active, update->intraslice_share_active); + exist->intraslice_share_active = update->intraslice_share_active; + exist->has_intraslice_share_active = 1; + } + if (update->has_interslice_share_active + && exist->interslice_share_active != update->interslice_share_active) { + LOG_I(FLEXRAN_AGENT, "[%d] update interslice_share_active: %d -> %d\n", + mod_id, exist->interslice_share_active, update->interslice_share_active); + exist->interslice_share_active = update->interslice_share_active; + exist->has_interslice_share_active = 1; + } +} + +void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) +{ + if (update->label != exist->label) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update label: %d -> %d\n", + mod_id, update->id, exist->label, update->label); + exist->label = update->label; + exist->has_label = 1; + } + if (update->percentage != exist->percentage) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update percentage: %d -> %d\n", + mod_id, update->id, exist->percentage, update->percentage); + exist->percentage = update->percentage; + exist->has_percentage = 1; + } + if (update->isolation != exist->isolation) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update isolation: %d -> %d\n", + mod_id, update->id, exist->isolation, update->isolation); + exist->isolation = update->isolation; + exist->has_isolation = 1; + } + if (update->priority != exist->priority) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update priority: %d -> %d\n", + mod_id, update->id, exist->priority, update->priority); + exist->priority = update->priority; + exist->has_priority = 1; + } + if (update->position_low != exist->position_low) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_low: %d -> %d\n", + mod_id, update->id, exist->position_low, update->position_low); + exist->position_low = update->position_low; + exist->has_position_low = 1; + } + if (update->position_high != exist->position_high) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_high: %d -> %d\n", + mod_id, update->id, exist->position_high, update->position_high); + exist->position_high = update->position_high; + exist->has_position_high = 1; + } + if (update->maxmcs != exist->maxmcs) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update maxmcs: %d -> %d\n", + mod_id, update->id, exist->maxmcs, update->maxmcs); + exist->maxmcs = update->maxmcs; + exist->has_maxmcs = 1; + } + if (check_dl_sorting_update(exist, update)) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update sorting array\n", mod_id, update->id); + if (exist->n_sorting != update->n_sorting) { + exist->n_sorting = update->n_sorting; + exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting)); + if (!exist->sorting) exist->n_sorting = 0; + } + for (int i = 0; i < exist->n_sorting; i++) + exist->sorting[i] = update->sorting[i]; + } + if (update->accounting != exist->accounting) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update accounting: %d -> %d\n", + mod_id, update->id, exist->accounting, update->accounting); + exist->accounting = update->accounting; + exist->has_accounting = 1; + } + if (!exist->scheduler_name + || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { + LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update scheduler: %s -> %s\n", + mod_id, update->id, exist->scheduler_name, update->scheduler_name); + if (exist->scheduler_name) free(exist->scheduler_name); + exist->scheduler_name = strdup(update->scheduler_name); + } +} + +void overwrite_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) +{ + if (update->label != exist->label) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update label: %d -> %d\n", + mod_id, update->id, exist->label, update->label); + exist->label = update->label; + exist->has_label = 1; + } + if (update->percentage != exist->percentage) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update percentage: %d -> %d\n", + mod_id, update->id, exist->percentage, update->percentage); + exist->percentage = update->percentage; + exist->has_percentage = 1; + } + if (update->isolation != exist->isolation) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update isolation: %d -> %d\n", + mod_id, update->id, exist->isolation, update->isolation); + exist->isolation = update->isolation; + exist->has_isolation = 1; + } + if (update->priority != exist->priority) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update priority: %d -> %d\n", + mod_id, update->id, exist->priority, update->priority); + exist->priority = update->priority; + exist->has_priority = 1; + } + if (update->first_rb != exist->first_rb) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update first_rb: %d -> %d\n", + mod_id, update->id, exist->first_rb, update->first_rb); + exist->first_rb = update ->first_rb; + exist->has_first_rb = 1; + } + /*if (update->lenght_rb != exist->lenght_rb) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update lenght_rb: %d -> %d\n", + mod_id, update->id, exist->lenght_rb, update->lenght_rb); + exist->lenght_rb = update->lenght_rb; + }*/ + if (update->maxmcs != exist->maxmcs) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update maxmcs: %d -> %d\n", + mod_id, update->id, exist->maxmcs, update->maxmcs); + exist->maxmcs = update->maxmcs; + exist->has_maxmcs = 1; + } + /* TODO + int sorting_update = 0; + int n = min(exist->n_sorting, update->n_sorting); + int i = 0; + while (i < n && !sorting_update) { + sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); + i++; + } + if (sorting_update) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update sorting array\n", update->id, mod_id); + if (exist->n_sorting != update->n_sorting) + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] only writing %d elements\n", + mod_id, update->id, n); + for (i = 0; i < n; i++) + exist->sorting[i] = update->sorting[i]; + } + */ + if (update->accounting != exist->accounting) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update accounting: %d -> %d\n", + mod_id, update->id, exist->accounting, update->accounting); + exist->accounting = update->accounting; + exist->has_accounting = 1; + } + if (!exist->scheduler_name + || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { + LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update scheduler: %s -> %s\n", + mod_id, update->id, exist->scheduler_name, update->scheduler_name); + if (exist->scheduler_name) free(exist->scheduler_name); + exist->scheduler_name = strdup(update->scheduler_name); + } +} + +void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice *from) +{ + /* function fills slice with information from another slice or with default + * values (currently slice 0) if from is NULL */ + /* TODO fill the slice depending on the chosen label */ + if (!s->has_label) { + s->has_label = 1; + s->label = from ? from->label : sc_update[mod_id]->dl[0]->label; + } + if (!s->has_percentage) { + s->has_percentage = 1; + s->percentage = from ? from->percentage : sc_update[mod_id]->dl[0]->percentage; + } + if (!s->has_isolation) { + s->has_isolation = 1; + s->isolation = from ? from->isolation : sc_update[mod_id]->dl[0]->isolation; + } + if (!s->has_priority) { + s->has_priority = 1; + s->priority = from ? from->priority : sc_update[mod_id]->dl[0]->priority; + } + if (!s->has_position_low) { + s->has_position_low = 1; + s->position_low = from ? from->position_low : sc_update[mod_id]->dl[0]->position_low; + } + if (!s->has_position_high) { + s->has_position_high = 1; + s->position_high = from ? from->position_high : sc_update[mod_id]->dl[0]->position_high; + } + if (!s->has_maxmcs) { + s->has_maxmcs = 1; + s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->dl[0]->maxmcs; + } + if (s->n_sorting == 0) { + s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting; + s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexDlSorting)); + if (!s->sorting) s->n_sorting = 0; + for (int i = 0; i < s->n_sorting; ++i) + s->sorting[i] = from ? from->sorting[i] : sc_update[0]->dl[0]->sorting[i]; + } + if (!s->has_accounting) { + s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting; + } + if (!s->scheduler_name) { + s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name); + } +} + +Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id) +{ + for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) { + if (id == sc_update[mod_id]->dl[i]->id) { + return sc_update[mod_id]->dl[i]; + } + } + return NULL; +} + +Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) +{ + LOG_I(FLEXRAN_AGENT, + "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", + mod_id, id); + Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; + sc_update[mod_id]->n_dl++; + AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES, + "cannot create more than MAX_NUM_SLICES\n"); + to->id = id; + return to; +} + +void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice *from) +{ + /* function fills slice with information from another slice or with default + * values (currently slice 0) if from is NULL */ + /* TODO fill the slice depending on the chosen label */ + if (!s->has_label) { + s->has_label = 1; + s->label = from ? from->label : sc_update[mod_id]->ul[0]->label; + } + if (!s->has_percentage) { + s->has_percentage = 1; + s->percentage = from ? from->percentage : sc_update[mod_id]->ul[0]->percentage; + } + if (!s->has_isolation) { + s->has_isolation = 1; + s->isolation = from ? from->isolation : sc_update[mod_id]->ul[0]->isolation; + } + if (!s->has_priority) { + s->has_priority = 1; + s->priority = from ? from->priority : sc_update[mod_id]->ul[0]->priority; + } + if (!s->has_first_rb) { + s->has_first_rb = 1; + s->first_rb = from ? from->first_rb : sc_update[mod_id]->ul[0]->first_rb; + } + if (!s->has_maxmcs) { + s->has_maxmcs = 1; + s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->ul[0]->maxmcs; + } + if (s->n_sorting == 0) { + s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting; + s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexUlSorting)); + if (!s->sorting) s->n_sorting = 0; + for (int i = 0; i < s->n_sorting; ++i) + s->sorting[i] = from ? from->sorting[i] : sc_update[0]->ul[0]->sorting[i]; + } + if (!s->has_accounting) { + s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting; + } + if (!s->scheduler_name) { + s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name); + } +} + +Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id) +{ + for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) { + if (id == sc_update[mod_id]->ul[i]->id) { + return sc_update[mod_id]->ul[i]; + } + } + return NULL; +} + +Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id) +{ + LOG_I(FLEXRAN_AGENT, + "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", + mod_id, id); + Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; + sc_update[mod_id]->n_ul++; + AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES, + "cannot create more than MAX_NUM_SLICES\n"); + to->id = id; + return to; +} + +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) +{ + int verified = 1; + if (!sc_update[mod_id]) { + LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); + return; + } + + pthread_mutex_lock(&sc_update_mtx); + /* no need for tests in the current state as there are only two protobuf + * bools for intra-/interslice sharing. The function applies new values if + * applicable */ + overwrite_slice_config(mod_id, sc_update[mod_id], sup); + + if (sup->n_dl == 0) { + LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); + } else { + /* verify slice parameters */ + for (int i = 0; i < sup->n_dl; i++) { + if (!sup->dl[i]->has_id) { + verified = 0; + break; + } + Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); + /* fill up so that the slice is complete. This way, we don't need to + * worry about it later */ + fill_dl_slice(mod_id, sup->dl[i], dls); + verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]); + if (!verified) break; + } + + /* verify group-based parameters (e.g. sum percentage should not exceed + * 100%). Can be used to perform admission control */ + verified = verified && flexran_verify_group_dl_slices(mod_id, + sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl); + + if (verified) { + for (int i = 0; i < sup->n_dl; i++) { + /* if all verifications were successful, get existing slice for ID or + * create new one and overwrite with the update */ + Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); + if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id); + overwrite_slice_config_dl(mod_id, dls, sup->dl[i]); + } + } else { + LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id); + } + } + + verified = 1; + if (sup->n_ul == 0) { + LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id); + } else { + /* verify slice parameters */ + for (int i = 0; i < sup->n_ul; i++) { + if (!sup->ul[i]->has_id) { + verified = 0; + break; + } + Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); + /* fill up so that the slice is complete. This way, we don't need to + * worry about it later */ + fill_ul_slice(mod_id, sup->ul[i], uls); + verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]); + if (!verified) break; + } + + /* verify group-based parameters (e.g. sum percentage should not exceed + * 100%). Can be used to perform admission control */ + verified = verified && flexran_verify_group_ul_slices(mod_id, + sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul); + + if (verified) { + for (int i = 0; i < sup->n_ul; i++) { + /* if all verifications were successful, get existing slice for ID or + * create new one and overwrite with the update */ + Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); + if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id); + overwrite_slice_config_ul(mod_id, uls, sup->ul[i]); + } + } else { + LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id); + } + } + pthread_mutex_unlock(&sc_update_mtx); + + perform_slice_config_update_count = 1; +} + +int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news) +{ + /* not setting the old configuration is intentional, as it will be picked up + * later when reading the configuration. There is thus a direct feedback + * whether it has been set. */ + int changes = 0; + if (olds->intraslice_share_active != news->intraslice_share_active) { + flexran_set_intraslice_sharing_active(mod_id, news->intraslice_share_active); + changes++; + } + if (olds->interslice_share_active != news->interslice_share_active) { + flexran_set_interslice_sharing_active(mod_id, news->interslice_share_active); + changes++; + } + return changes; +} + +int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc) +{ + /* not setting the old configuration is intentional, as it will be picked up + * later when reading the configuration. There is thus a direct feedback + * whether it has been set. */ + int changes = 0; + int slice_idx = flexran_find_dl_slice(mod_id, newc->id); + if (slice_idx < 0) { + LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); + return 0; + } + if (oldc->percentage != newc->percentage) { + flexran_set_dl_slice_percentage(mod_id, slice_idx, newc->percentage); + changes++; + } + if (oldc->isolation != newc->isolation) { + flexran_set_dl_slice_isolation(mod_id, slice_idx, newc->isolation); + changes++; + } + if (oldc->priority != newc->priority) { + flexran_set_dl_slice_priority(mod_id, slice_idx, newc->priority); + changes++; + } + if (oldc->position_low != newc->position_low) { + flexran_set_dl_slice_position_low(mod_id, slice_idx, newc->position_low); + changes++; + } + if (oldc->position_high != newc->position_high) { + flexran_set_dl_slice_position_high(mod_id, slice_idx, newc->position_high); + changes++; + } + if (oldc->maxmcs != newc->maxmcs) { + flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); + changes++; + } + if (check_dl_sorting_update(oldc, newc)) { + flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, newc->n_sorting); + changes++; + } + if (oldc->accounting != newc->accounting) { + flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); + changes++; + } + if (!oldc->scheduler_name + || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { + int ret = flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", + newc->id, slice_idx); + changes++; + } + return changes; +} + +int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc) +{ + /* not setting the old configuration is intentional, as it will be picked up + * later when reading the configuration. There is thus a direct feedback + * whether it has been set. */ + int changes = 0; + int slice_idx = flexran_find_ul_slice(mod_id, newc->id); + if (slice_idx < 0) { + LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); + return 0; + } + if (oldc->percentage != newc->percentage) { + flexran_set_ul_slice_percentage(mod_id, slice_idx, newc->percentage); + changes++; + } + if (oldc->isolation != newc->isolation) { + /*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation); + *changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n", + mod_id, newc->id); + } + if (oldc->priority != newc->priority) { + /*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority); + *changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n", + mod_id, newc->id); + } + if (oldc->first_rb != newc->first_rb) { + flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb); + changes++; + } + /*if (oldc->length_rb != newc->length_rb) { + flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb); + changes++; + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n", + mod_id, newc->id); + }*/ + if (oldc->maxmcs != newc->maxmcs) { + flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); + changes++; + } + /*if (check_ul_sorting_update(oldc, newc)) { + flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); + changes++; + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", + mod_id, newc->id); + }*/ + if (oldc->accounting != newc->accounting) { + /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); + *changes++;*/ + LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", + mod_id, newc->id); + } + if (!oldc->scheduler_name + || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { + int ret = flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); + AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", + newc->id, slice_idx); + changes++; + } + return changes; +} + +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) +{ + if (n_ue_slice_assoc_updates == MAX_NUM_SLICES) { + LOG_E(FLEXRAN_AGENT, + "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", + mod_id); + return; + } + if (!ue_config->has_rnti) { + LOG_E(FLEXRAN_AGENT, + "[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n", + mod_id); + return; + } + if (ue_config->has_dl_slice_id) + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to DL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->dl_slice_id); + if (ue_config->has_ul_slice_id) + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to UL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->ul_slice_id); + ue_slice_assoc_update[n_ue_slice_assoc_updates++] = ue_config; + perform_slice_config_update_count = 2; +} + +int apply_ue_slice_assoc_update(mid_t mod_id) +{ + int i; + int changes = 0; + for (i = 0; i < n_ue_slice_assoc_updates; i++) { + int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti); + if (ue_slice_assoc_update[i]->has_dl_slice_id) { + int slice_idx = flexran_find_dl_slice(mod_id, ue_slice_assoc_update[i]->dl_slice_id); + if (flexran_dl_slice_exists(mod_id, slice_idx)) { + flexran_set_ue_dl_slice_idx(mod_id, ue_id, slice_idx); + changes++; + } else { + LOG_W(FLEXRAN_AGENT, "[%d] DL slice %d does not exist, refusing change\n", + mod_id, ue_slice_assoc_update[i]->dl_slice_id); + } + } + if (ue_slice_assoc_update[i]->has_ul_slice_id) { + int slice_idx = flexran_find_ul_slice(mod_id, ue_slice_assoc_update[i]->ul_slice_id); + if (flexran_ul_slice_exists(mod_id, slice_idx)) { + flexran_set_ue_ul_slice_idx(mod_id, ue_id, slice_idx); + changes++; + } else { + LOG_W(FLEXRAN_AGENT, "[%d] UL slice %d does not exist, refusing change\n", + mod_id, ue_slice_assoc_update[i]->ul_slice_id); + } + } + } + n_ue_slice_assoc_updates = 0; + return changes; +} 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 f69e2cde4098ad5d035a522c9815632bffb37312..01fc51f6a6c9200def3d6df20e1c7554088a622f 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 @@ -107,4 +107,45 @@ int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); int load_dl_scheduler_function(mid_t mod_id, const char *function_name); +/*** Functions for handling a slice config ***/ + +/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice + * configs and m_ul UL slice configs */ +Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul); + +/* read the general slice parameters via RAN into the given + * Protocol__FlexSliceConfig struct */ +void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s); + +/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice + * struct */ +void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice); + +/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice + * struct */ +void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice); + +/* reads content of slice over the sc_update structure, so that it can be + * applied later by performing a diff between slice_config and sc_update */ +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); + +/* apply generic slice parameters (e.g. intra-/interslice sharing activated or + * not) if there are changes. Returns the number of changed parameters. */ +int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news); + +/* apply new configuration of slice in DL if there are changes between the + * parameters. Returns the number of changed parameters. */ +int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc); + +/* apply new configuration of slice in UL if there are changes between the + * parameters. Returns the number of changed parameters. */ +int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc); + +/* inserts a new ue_config into the structure keeping ue to slice association + * updates and marks so it can be applied */ +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); + +/* apply a new association between a UE and a slice (both DL and UL) */ +int apply_ue_slice_assoc_update(mid_t mod_id); + #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c new file mode 100644 index 0000000000000000000000000000000000000000..67329e91be0d9508c5943dd527dfb990ef654201 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -0,0 +1,373 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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_mac_slice_verification.c + * \brief MAC Agent slice verification helper functions + * \author Robert Schmidt + * \date 2018 + * \version 0.1 + */ + + +#include "flexran_agent_mac_slice_verification.h" + +/* overlap check for UL slices, helper type */ +struct sregion_s { + int start; + int length; +}; + +/* forward declaration of locally-used verification functions */ +int flexran_dl_slice_verify_pct(int pct); +int flexran_dl_slice_verify_priority(int prio); +int flexran_dl_slice_verify_position(int pos_low, int pos_high); +int flexran_dl_slice_verify_maxmcs(int maxmcs); +int flexran_ul_slice_verify_pct(int pct); +int flexran_ul_slice_verify_priority(int prio); +int flexran_ul_slice_verify_first_rb(int first_rb); +int flexran_ul_slice_verify_maxmcs(int maxmcs); +int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n); + +int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls) +{ + /* check mandatory parameters */ + if (!dls->has_id) { + LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); + return 0; + } + + /* verify parameters individualy */ + /* label is enum */ + if (!flexran_dl_slice_verify_pct(dls->percentage)) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice percentage (%d)\n", + mod_id, dls->id, dls->percentage); + return 0; + } + /* isolation is a protobuf bool */ + if (!flexran_dl_slice_verify_priority(dls->priority)) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice priority (%d)\n", + mod_id, dls->id, dls->priority); + return 0; + } + if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) { + LOG_E(FLEXRAN_AGENT, + "[%d][DL slice %d] illegal DL slice position low (%d) and/or high (%d)\n", + mod_id, dls->id, dls->position_low, dls->position_high); + return 0; + } + if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice max mcs %d\n", + mod_id, dls->id, dls->maxmcs); + return 0; + } + if (dls->n_sorting == 0) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting in DL slice\n", + mod_id, dls->id); + return 0; + } + if (!dls->sorting) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting found in DL slice\n", + mod_id, dls->id); + return 0; + } + /* sorting is an enum */ + /* accounting is an enum */ + if (!dls->scheduler_name) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no scheduler name found\n", + mod_id, dls->id); + return 0; + } + if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) { + LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the scheduler to something " + "different than schedule_ue_spec is currently not allowed\n", + mod_id, dls->id); + return 0; + } + + return 1; +} + +int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, + int n_ex, Protocol__FlexDlSlice **update, int n_up) +{ + int i, j, n; + int pct, pct_orig; + /* for every update, array points to existing slice, or NULL if update + * creates new slice */ + Protocol__FlexDlSlice *s[n_up]; + for (i = 0; i < n_up; i++) { + s[i] = NULL; + for (j = 0; j < n_ex; j++) { + if (existing[j]->id == update[i]->id) + s[i] = existing[j]; + } + } + + /* check that number of created and number of added slices in total matches + * [1,10] */ + n = n_ex; + for (i = 0; i < n_up; i++) { + /* new slice */ + if (!s[i]) n += 1; + /* slice will be deleted */ + else if (s[i]->percentage == 0) n -= 1; + /* else "only" an update */ + } + + if (n < 1 || n > MAX_NUM_SLICES) { + LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n", + mod_id, n_ex, n); + return 0; + } + + /* check that the sum of all slices percentages (including removed/added + * slices) matches [1,100] */ + pct = 0; + for (i = 0; i < n_ex; i++) { + pct += existing[i]->percentage; + } + pct_orig = pct; + for (i = 0; i < n_up; i++) { + /* if there is an existing slice, subtract its percentage and add the + * update's percentage */ + if (s[i]) + pct -= s[i]->percentage; + pct += update[i]->percentage; + } + if (pct < 1 || pct > 100) { + LOG_E(FLEXRAN_AGENT, + "[%d] invalid total RB share for DL slices (%d%% -> %d%%)\n", + mod_id, pct_orig, pct); + return 0; + } + + return 1; +} + +int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) +{ + /* check mandatory parameters */ + if (!uls->has_id) { + LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); + return 0; + } + + /* verify parameters individually */ + /* label is enum */ + if (!flexran_ul_slice_verify_pct(uls->percentage)) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", + mod_id, uls->id, uls->percentage); + return 0; + } + /* isolation is a protobuf bool */ + if (!flexran_ul_slice_verify_priority(uls->priority)) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", + mod_id, uls->id, uls->priority); + return 0; + } + if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice first RB (%d)\n", + mod_id, uls->id, uls->first_rb); + return 0; + } + if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice max mcs (%d)\n", + mod_id, uls->id, uls->maxmcs); + return 0; + } + /* TODO + if (uls->n_sorting == 0) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting in UL slice\n", + mod_id, uls->id); + return 0; + } + if (!uls->sorting) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting found in UL slice\n", + mod_id, uls->id); + return 0; + } + */ + /* sorting is an enum */ + /* accounting is an enum */ + if (!uls->scheduler_name) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no scheduler name found\n", + mod_id, uls->id); + return 0; + } + if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) { + LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the scheduler to something " + "different than schedule_ulsch_rnti is currently not allowed\n", + mod_id, uls->id); + return 0; + } + + return 1; +} + +int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, + int n_ex, Protocol__FlexUlSlice **update, int n_up) +{ + int i, j, n; + int pct, pct_orig; + /* for every update, array "s" points to existing slice, or NULL if update + * creates new slice; array "offs" gives the offset of this slice */ + Protocol__FlexUlSlice *s[n_up]; + int offs[n_up]; + for (i = 0; i < n_up; i++) { + s[i] = NULL; + offs[i] = 0; + for (j = 0; j < n_ex; j++) { + if (existing[j]->id == update[i]->id) { + s[i] = existing[j]; + offs[i] = j; + } + } + } + + /* check that number of created and number of added slices in total matches + * [1,10] */ + n = n_ex; + for (i = 0; i < n_up; i++) { + /* new slice */ + if (!s[i]) n += 1; + /* slice will be deleted */ + else if (s[i]->percentage == 0) n -= 1; + /* else "only" an update */ + } + + if (n < 1 || n > MAX_NUM_SLICES) { + LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n", + mod_id, n_ex, n); + return 0; + } + + /* check that the sum of all slices percentages (including removed/added + * slices) matches [1,100] */ + pct = 0; + for (i = 0; i < n_ex; i++) { + pct += existing[i]->percentage; + } + pct_orig = pct; + for (i = 0; i < n_up; i++) { + /* if there is an existing slice, subtract its percentage and add the + * update's percentage */ + if (s[i]) + pct -= s[i]->percentage; + pct += update[i]->percentage; + } + if (pct < 1 || pct > 100) { + LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", + mod_id, pct_orig, pct); + return 0; + } + + /* check that there is no overlap in slices resulting as the combination of + * first_rb and percentage */ + struct sregion_s sregion[n]; + const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ + int k = n_ex; + for (i = 0; i < n_ex; i++) { + sregion[i].start = existing[i]->first_rb; + sregion[i].length = existing[i]->percentage * N_RB / 100; + } + for (i = 0; i < n_up; i++) { + ptrdiff_t d = s[i] ? offs[i] : k++; + AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k); + sregion[d].start = update[i]->first_rb; + sregion[d].length = update[i]->percentage * N_RB / 100; + } + AssertFatal(k == n, "illegal number of slices while calculating overlap\n"); + if (!check_ul_slice_overlap(mod_id, sregion, k)) { + LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id); + return 0; + } + + return 1; +} + +int flexran_dl_slice_verify_pct(int pct) +{ + return pct >= 0 && pct <= 100; +} + +int flexran_dl_slice_verify_priority(int prio) +{ + return prio >= 0; +} + +int flexran_dl_slice_verify_position(int pos_low, int pos_high) +{ + return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX; +} + +int flexran_dl_slice_verify_maxmcs(int maxmcs) +{ + return maxmcs >= 0 && maxmcs <= 28; +} + +int flexran_ul_slice_verify_pct(int pct) +{ + return pct >= 0 && pct <= 100; +} + +int flexran_ul_slice_verify_priority(int prio) +{ + return prio >= 0; +} + +int flexran_ul_slice_verify_first_rb(int first_rb) +{ + return first_rb >= 0 && first_rb < 100; +} + +int flexran_ul_slice_verify_maxmcs(int maxmcs) +{ + return maxmcs >= 0 && maxmcs <= 20; +} + +int sregion_compare(const void *_a, const void *_b) +{ + const struct sregion_s *a = (const struct sregion_s *)_a; + const struct sregion_s *b = (const struct sregion_s *)_b; + const int res = a->start - b->start; + if (res < 0) return -1; + else if (res == 0) return 0; + else return 1; +} + +int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n) +{ + int i; + int overlap, op, u; + const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ + qsort(sr, n, sizeof(sr[0]), sregion_compare); + for (i = 0; i < n; i++) { + u = i == n-1 ? N_RB : sr[i+1].start; + AssertFatal(sr[i].start <= u, "unsorted slice list\n"); + overlap = sr[i].start + sr[i].length - u; + if (overlap <= 0) continue; + op = overlap * 100 / sr[i].length; + LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op); + if (op >= 10) /* more than 10% overlap -> refuse */ + return 0; + } + return 1; +} diff --git a/common/utils/itti/intertask_messages_types.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h similarity index 61% rename from common/utils/itti/intertask_messages_types.h rename to openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h index 145f57648ffcd62288d501ac49182652465ea72d..a8f4030d3664be1e1388d8d42cae8feed9a4dd90 100644 --- a/common/utils/itti/intertask_messages_types.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h @@ -19,22 +19,19 @@ * contact@openairinterface.org */ -/* - * intertask_messages_types.h - * - * Created on: Jan 14, 2014 - * Author: laurent winckel +/*! \file flexran_agent_mac_slice_verification.h + * \brief MAC Agent slice verification helper functions + * \author Robert Schmidt + * \date 2018 + * \version 0.1 */ -#ifndef INTERTASK_MESSAGES_TYPES_H_ -#define INTERTASK_MESSAGES_TYPES_H_ - -typedef struct IttiMsgEmpty_s { -} IttiMsgEmpty; - -typedef struct IttiMsgText_s { - uint32_t size; - char text[]; -} IttiMsgText; +#include "flexran_agent_common_internal.h" +#include "flexran_agent_mac_internal.h" -#endif /* INTERTASK_MESSAGES_TYPES_H_ */ +int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls); +int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, + int n_ex, Protocol__FlexDlSlice **update, int n_up); +int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls); +int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, + int n_ex, Protocol__FlexUlSlice **update, int n_up); 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 b2723f718126973f96d972a3284b995c5e99c3e2..7cb39fb7239a17af935fa026ab0d20c12b866dbb 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -78,6 +78,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i; + int UE_id; // int cc_id = 0; @@ -85,6 +86,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, if (report_config->nr_ue > 0) { for (i = 0; i < report_config->nr_ue; i++) { + UE_id = flexran_get_ue_id(mod_id, i); /* 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) { @@ -95,7 +97,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, goto error; protocol__flex_pdcp_stats__init(pdcp_aggr_stats); - flexran_agent_pdcp_aggregate_stats(mod_id, i, pdcp_aggr_stats); + flexran_agent_pdcp_aggregate_stats(mod_id, UE_id, pdcp_aggr_stats); pdcp_aggr_stats->has_pkt_tx=1; pdcp_aggr_stats->has_pkt_tx_bytes =1; @@ -104,7 +106,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_tx_aiat =1; pdcp_aggr_stats->has_pkt_tx_aiat_w =1; - pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, UE_id, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_tx_sn =1; pdcp_aggr_stats->has_pkt_rx =1; @@ -115,7 +117,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_rx_aiat_w =1; pdcp_aggr_stats->has_pkt_rx_oo =1; - pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, UE_id, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_rx_sn =1; pdcp_aggr_stats->sfn = flexran_get_pdcp_sfn(mod_id); 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 e5e242232ced64c83f8d021fd99c0a4c16aba3cb..b79ad8841715dfcfb227f52ba9f58b9c8c30725f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -31,7 +31,7 @@ #include "liblfds700.h" -#include "log.h" +#include "common/utils/LOG/log.h" /*Trigger boolean for RRC measurement*/ bool triggered_rrc = false; @@ -76,147 +76,147 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch config->has_rnti = 1; config->rnti = rnti; } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED - || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { - int i = find_UE_id(mod_id, rnti); - config->has_rnti = 1; - config->rnti = rnti; - if(flexran_get_time_alignment_timer(mod_id,i) != -1) { - config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - config->has_time_alignment_timer = 1; - } - if(flexran_get_meas_gap_config(mod_id,i) != -1){ - config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - config->has_meas_gap_config_pattern = 1; - } - if(config->has_meas_gap_config_pattern == 1 && - config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); - config->has_meas_gap_config_sf_offset = 1; - } - //TODO: Set the SPS configuration (Optional) - //Not supported for now, so we do not set it - - //TODO: Set the SR configuration (Optional) - //We do not set it for now - - //TODO: Set the CQI configuration (Optional) - //We do not set it for now - - if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { - config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); - config->has_transmission_mode = 1; - } - - config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); - config->has_ue_aggregated_max_bitrate_ul = 1; - - config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); - config->has_ue_aggregated_max_bitrate_dl = 1; - - //TODO: Set the UE capabilities - Protocol__FlexUeCapabilities *c_capabilities; - c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); - protocol__flex_ue_capabilities__init(c_capabilities); - //TODO: Set half duplex (FDD operation) - c_capabilities->has_half_duplex = 0; - c_capabilities->half_duplex = 1;//flexran_get_half_duplex(i); - //TODO: Set intra-frame hopping flag - c_capabilities->has_intra_sf_hopping = 0; - c_capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); - //TODO: Set support for type 2 hopping with n_sb > 1 - c_capabilities->has_type2_sb_1 = 0; - c_capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); - //TODO: Set ue category - c_capabilities->has_ue_category = 0; - c_capabilities->ue_category = 1;//flexran_get_ue_category(i); - //TODO: Set UE support for resource allocation type 1 - c_capabilities->has_res_alloc_type1 = 0; - c_capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); - //Set the capabilites to the message - config->capabilities = c_capabilities; - - if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { - config->has_ue_transmission_antenna = 1; - config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); - } - - if(flexran_get_tti_bundling(mod_id,i) != -1) { - config->has_tti_bundling = 1; - config->tti_bundling = flexran_get_tti_bundling(mod_id,i); - } - - if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ - config->has_max_harq_tx = 1; - config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); - } - - if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - config->has_beta_offset_ack_index = 1; - config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); - } - - if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { - config->has_beta_offset_ri_index = 1; - config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); - } - - if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { - config->has_beta_offset_cqi_index = 1; - config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); - } - - /* assume primary carrier */ - if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { - config->has_ack_nack_simultaneous_trans = 1; - config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); - } - - if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { - config->has_simultaneous_ack_nack_cqi = 1; - config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); - } - - if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { - config->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); - if (mode > 4) { - config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } else { - config->aperiodic_cqi_rep_mode = mode; - } - } - - if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { - config->has_tdd_ack_nack_feedback = 1; - config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); - } - - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { - config->has_ack_nack_repetition_factor = 1; - config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); - } - - if(flexran_get_extended_bsr_size(mod_id, i) != -1) { - config->has_extended_bsr_size = 1; - config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); - } - - config->has_pcell_carrier_index = 1; - config->pcell_carrier_index = UE_PCCID(mod_id, i); - //TODO: Set carrier aggregation support (boolean) - config->has_ca_support = 0; - config->ca_support = 0; - if(config->has_ca_support){ - //TODO: Set cross carrier scheduling support (boolean) - config->has_cross_carrier_sched_support = 1; - config->cross_carrier_sched_support = 0; - //TODO: Set secondary cells configuration - // We do not set it for now. No carrier aggregation support - - //TODO: Set deactivation timer for secondary cell - config->has_scell_deactivation_timer = 0; - config->scell_deactivation_timer = 0; - } + || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { + int i = find_UE_id(mod_id, rnti); + config->has_rnti = 1; + config->rnti = rnti; + config->imsi = flexran_get_ue_imsi(mod_id, i); + config->has_imsi = 1; + config->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, i); + config->has_dl_slice_id = 1; + config->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, i); + config->has_ul_slice_id = 1; + if(flexran_get_time_alignment_timer(mod_id,i) != -1) { + config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); + config->has_time_alignment_timer = 1; + } + if(flexran_get_meas_gap_config(mod_id,i) != -1){ + config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); + config->has_meas_gap_config_pattern = 1; + } + if(config->has_meas_gap_config_pattern == 1 && + config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); + config->has_meas_gap_config_sf_offset = 1; + } + //TODO: Set the SPS configuration (Optional) + //Not supported for now, so we do not set it + + //TODO: Set the SR configuration (Optional) + //We do not set it for now + + //TODO: Set the CQI configuration (Optional) + //We do not set it for now + + if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { + config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); + config->has_transmission_mode = 1; + } + + config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); + config->has_ue_aggregated_max_bitrate_ul = 1; + + config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); + config->has_ue_aggregated_max_bitrate_dl = 1; + + Protocol__FlexUeCapabilities *c_capabilities; + c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); + protocol__flex_ue_capabilities__init(c_capabilities); + c_capabilities->has_half_duplex = 1; + c_capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); + c_capabilities->has_intra_sf_hopping = 1; + c_capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); + c_capabilities->has_type2_sb_1 = 1; + c_capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); + c_capabilities->has_ue_category = 1; + c_capabilities->ue_category = flexran_get_ue_category(mod_id, i); + c_capabilities->has_res_alloc_type1 = 1; + c_capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); + //Set the capabilites to the message + config->capabilities = c_capabilities; + + if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { + config->has_ue_transmission_antenna = 1; + config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); + } + + if(flexran_get_tti_bundling(mod_id,i) != -1) { + config->has_tti_bundling = 1; + config->tti_bundling = flexran_get_tti_bundling(mod_id,i); + } + + if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ + config->has_max_harq_tx = 1; + config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); + } + + if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { + config->has_beta_offset_ack_index = 1; + config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); + } + + if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { + config->has_beta_offset_ri_index = 1; + config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); + } + + if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { + config->has_beta_offset_cqi_index = 1; + config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); + } + + /* assume primary carrier */ + if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { + config->has_ack_nack_simultaneous_trans = 1; + config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); + } + + if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { + config->has_simultaneous_ack_nack_cqi = 1; + config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); + } + + if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { + config->has_aperiodic_cqi_rep_mode = 1; + int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); + if (mode > 4) { + config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; + } else { + config->aperiodic_cqi_rep_mode = mode; + } + } + + if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { + config->has_tdd_ack_nack_feedback = 1; + config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); + } + + if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { + config->has_ack_nack_repetition_factor = 1; + config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); + } + + if(flexran_get_extended_bsr_size(mod_id, i) != -1) { + config->has_extended_bsr_size = 1; + config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); + } + + config->has_pcell_carrier_index = 1; + config->pcell_carrier_index = UE_PCCID(mod_id, i); + //TODO: Set carrier aggregation support (boolean) + config->has_ca_support = 0; + config->ca_support = 0; + if(config->has_ca_support){ + //TODO: Set cross carrier scheduling support (boolean) + config->has_cross_carrier_sched_support = 1; + config->cross_carrier_sched_support = 0; + //TODO: Set secondary cells configuration + // We do not set it for now. No carrier aggregation support + + //TODO: Set deactivation timer for secondary cell + config->has_scell_deactivation_timer = 0; + config->scell_deactivation_timer = 0; + } } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { // TODO: Not supported for now. Leave blank } @@ -264,27 +264,31 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { - int i; + //int i; // int priority = 0; // Warning Preventing // void *data; // int size; // err_code_t err_code = -100; triggered_rrc = true; - int num; + //int num; + /* TODO do we need this at the current state? meas_stats is never put into a + * protobuf message?! num = flexran_get_num_ues (mod_id); meas_stats = malloc(sizeof(rrc_meas_stats) * num); for (i = 0; i < num; i++){ - meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, i); - meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id,i); - meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140; + UE_id = flexran_get_ue_id(mod_id, i); + meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, UE_id); + meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id, UE_id); + meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id) - 140; // measResults->measResultPCell.rsrpResult - 140; - meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20; + meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id)/2 - 20; // (measResults->measResultPCell.rsrqResult)/2 - 20; } + */ // repl->neigh_meas = NULL; // if (meas->measResultNeighCells != NULL) { @@ -495,11 +499,14 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i,j; + int UE_id; /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { for (i = 0; i < report_config->nr_ue; i++) { + + UE_id = flexran_get_ue_id(mod_id, i); /* 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) { @@ -511,14 +518,14 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, goto error; protocol__flex_rrc_measurements__init(rrc_measurements); - rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i); - rrc_measurements->has_measid = 1; - - rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i); - rrc_measurements->has_pcell_rsrp = 1; - - rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i); - rrc_measurements->has_pcell_rsrq = 1 ; + rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id, UE_id); + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id); + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id); + rrc_measurements->has_pcell_rsrq = 1 ; /* Target Cell, Neghibouring*/ @@ -529,7 +536,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_neigh_cells_measurements__init(neigh_meas); - neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, i); + neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, UE_id); Protocol__FlexEutraMeasurements **eutra_meas = NULL; @@ -547,7 +554,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_eutra_measurements__init(eutra_meas[j]); - eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, i, j); + eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, UE_id, j); eutra_meas[j]->has_phys_cell_id = 1; @@ -558,10 +565,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_eutra_ref_signal_meas__init(meas_result); - meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, UE_id, eutra_meas[j]->phys_cell_id); meas_result->has_rsrp = 1; - meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, UE_id, eutra_meas[j]->phys_cell_id); meas_result->has_rsrq = 1; eutra_meas[j]->meas_result = meas_result; @@ -625,8 +632,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, for (i = 0; i < report_config->nr_ue; i++){ + UE_id = flexran_get_ue_id(mod_id, i); + if (ue_report[i]->rrc_measurements->neigh_meas != NULL){ - for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, i); j++){ + for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, UE_id); j++){ free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); } diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index 7b392b6b3bbc7a89049fc5ae5708026d68064dc4..3af59c1537691b5ac40104cfab714106a770a257 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -58,6 +58,87 @@ enum flex_qam { FLEQ_MOD_64QAM = 1; } +// +// Slice config related structures and enums +// +enum flex_dl_sorting { + + CR_ROUND = 0; // Highest HARQ first + CR_SRB12 = 1; // Highest SRB1+2 first + CR_HOL = 2; // Highest HOL first + CR_LC = 3; // Greatest RLC buffer first + CR_CQI = 4; // Highest CQI first + CR_LCP = 5; // Highest LC priority first +} + +enum flex_ul_sorting { + CRU_ROUND = 0; // Highest HARQ first + CRU_BUF = 1; // Highest BSR first + CRU_BTS = 2; // More bytes to schedule first + CRU_MCS = 3; // Highest MCS first + CRU_LCP = 4; // Highest LC priority first + CRU_HOL = 5; // Highest HOL first +} + +enum flex_dl_accounting_policy { + POL_FAIR = 0; + POL_GREEDY = 1; + POL_NUM = 2; +} + +enum flex_ul_accounting_policy { + POLU_FAIR = 0; + POLU_GREEDY = 1; + POLU_NUM = 2; +} + +enum flex_slice_label { + xMBB = 0; + URLLC = 1; + mMTC = 2; + xMTC = 3; + Other = 4; +} + +message flex_dl_slice { + optional uint32 id = 1; + optional flex_slice_label label = 2; + // should be between 0 and 100 + optional uint32 percentage = 3; + // whether this slice should be exempted form interslice sharing + optional bool isolation = 4; + // increasing value means increasing prio + optional uint32 priority = 5; + // min and max RB to use (in frequency) in the range [0, N_RBG_MAX] + optional uint32 position_low = 6; + optional uint32 position_high = 7; + // maximum MCS to be allowed in this slice + optional uint32 maxmcs = 8; + repeated flex_dl_sorting sorting = 9; + optional flex_dl_accounting_policy accounting = 10; + optional string scheduler_name = 11; +} + +message flex_ul_slice { + optional uint32 id = 1; + optional flex_slice_label label = 2; + // should be between 0 and 100 + optional uint32 percentage = 3; + // whether this slice should be exempted form interslice sharing + optional bool isolation = 4; + // increasing value means increasing prio + optional uint32 priority = 5; + // RB start to use (in frequency) in the range [0, N_RB_MAX] + optional uint32 first_rb = 6; + // TODO RB number + //optional uint32 length_rb = 7; + // maximum MCS to be allowed in this slice + optional uint32 maxmcs = 8; + repeated flex_ul_sorting sorting = 9; + optional flex_ul_accounting_policy accounting = 10; + optional string scheduler_name = 11; +} + // // UE config related structures and enums // @@ -177,4 +258,4 @@ enum flex_ue_state_change_type { FLUESC_ACTIVATED = 1; FLUESC_DEACTIVATED = 2; FLUESC_MOVED = 3; -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index f734686f011dcb1899a3bb95a52a92f4c6076572..1d5da8dd2abc0e756615096aee666e54125053dc 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -43,6 +43,19 @@ message flex_cell_config { optional uint32 eutra_band= 37; // operating band optional int32 dl_pdsch_power = 38; // operating downlink power optional int32 ul_pusch_power = 39; // operating uplink power + + optional flex_slice_config slice_config = 42; +} + +message flex_slice_config { + // whether remaining RBs after first intra-slice allocation will + // be allocated to UEs of the same slice + optional bool intraslice_share_active = 3; + // whether remaining RBs after slice allocation will be allocated + // to UEs of another slice. Isolated slices will be ignored. + optional bool interslice_share_active = 4; + repeated flex_dl_slice dl = 1; + repeated flex_ul_slice ul = 2; } message flex_ue_config { @@ -82,6 +95,8 @@ message flex_ue_config { repeated flex_scell_config scell_config = 28; // Secondary cells configuration optional uint32 scell_deactivation_timer = 29;// Deactivation timer for secondary cell optional uint64 imsi = 30; + optional uint32 dl_slice_id = 31; + optional uint32 ul_slice_id = 32; } message flex_lc_ue_config { diff --git a/openair2/ENB_APP/NB_IoT_interface.c b/openair2/ENB_APP/NB_IoT_interface.c index c4884453c2e9cc03d62f5c4e454bd3a3dd3f57fb..7355233d71d766e033efac6efa2a1ab08e81aed3 100644 --- a/openair2/ENB_APP/NB_IoT_interface.c +++ b/openair2/ENB_APP/NB_IoT_interface.c @@ -43,7 +43,7 @@ int load_NB_IoT(void) { RCConfig_NbIoT_f_t RCConfig; loader_shlibfunc_t shlib_fdesc[]=NBIOT_INTERFACE_FLIST; - ret=load_module_shlib(NBIOT_MODULENAME,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t)); + ret=load_module_shlib(NBIOT_MODULENAME,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); if (ret) { return ret; } diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 40c6aeac447c98206d23b82da6fcb64579cbd0d2..37bcd366533a5ef57333b0e8b5a0a55969984ce2 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -35,17 +35,22 @@ #include "assertions.h" #include "common/ran_context.h" -#include "log.h" +#include "common/utils/LOG/log.h" #if defined(ENABLE_ITTI) # include "intertask_interface.h" -# include "timer.h" # if defined(ENABLE_USE_MME) # include "s1ap_eNB.h" # include "sctp_eNB_task.h" # include "gtpv1u_eNB_task.h" +# else +# define EPC_MODE_ENABLED 0 # endif +# include "x2ap_eNB.h" +# include "x2ap_messages_types.h" +# define X2AP_ENB_REGISTER_RETRY_DELAY 10 + #include "openair1/PHY/INIT/phy_init.h" extern unsigned char NB_eNB_INST; #endif @@ -59,6 +64,8 @@ extern RAN_CONTEXT_t RC; # define ENB_REGISTER_RETRY_DELAY 10 # endif +#include "targets/RT/USER/lte-softmodem.h" + /*------------------------------------------------------------------------------*/ /* @@ -135,6 +142,30 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, # endif #endif +/*------------------------------------------------------------------------------*/ +static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end) +{ + uint32_t enb_id; + MessageDef *msg_p; + uint32_t register_enb_x2_pending = 0; + + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + + { + + msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); + + RCconfig_X2(msg_p, enb_id); + + itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + + register_enb_x2_pending++; + } + } + + return register_enb_x2_pending; +} + /*------------------------------------------------------------------------------*/ void *eNB_app_task(void *args_p) { @@ -143,10 +174,13 @@ void *eNB_app_task(void *args_p) uint32_t enb_id_start = 0; uint32_t enb_id_end = enb_id_start + enb_nb; # if defined(ENABLE_USE_MME) - uint32_t register_enb_pending; + uint32_t register_enb_pending=0; uint32_t registered_enb; long enb_register_retry_timer_id; # endif + uint32_t x2_register_enb_pending; + uint32_t x2_registered_enb; + long x2_enb_register_retry_timer_id; uint32_t enb_id; MessageDef *msg_p = NULL; instance_t instance; @@ -184,13 +218,17 @@ void *eNB_app_task(void *args_p) # if defined(ENABLE_USE_MME) /* Try to register each eNB */ - registered_enb = 0; - register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); -# else + registered_enb = 0; + register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); +#else /* Start L2L1 task */ - msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE); - itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); -# endif + msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE); + itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); +#endif + + /* Try to register each eNB with each other */ + x2_registered_enb = 0; + x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); do { // Wait for a message @@ -208,66 +246,123 @@ void *eNB_app_task(void *args_p) LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p)); break; -# if defined(ENABLE_USE_MME) + case SOFT_RESTART_MESSAGE: + handle_reconfiguration(instance); + break; case S1AP_REGISTER_ENB_CNF: - LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), - S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); +# if defined(ENABLE_USE_MME) + LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); + + DevAssert(register_enb_pending > 0); + register_enb_pending--; + + /* Check if at least eNB is registered with one MME */ + if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 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 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 (enb_id_start, enb_id_end);//, enb_properties_p); + } + } + } +#endif + break; - DevAssert(register_enb_pending > 0); - register_enb_pending--; + case S1AP_DEREGISTERED_ENB_IND: + if (EPC_MODE_ENABLED) { + LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme); - /* Check if at least eNB is registered with one MME */ - if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { - registered_enb++; + /* TODO handle recovering of registration */ } + break; - /* Check if all register eNB requests have been processed */ - if (register_enb_pending == 0) { - if (registered_enb == enb_nb) { - /* If all eNB 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"); + case TIMER_HAS_EXPIRED: +# if defined(ENABLE_USE_MME) + LOG_I(ENB_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); - sleep(ENB_REGISTER_RETRY_DELAY); - /* Restart the registration process */ - registered_enb = 0; - register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); - } - } + if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) { + /* Restart the registration process */ + registered_enb = 0; + register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); } + if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_enb_register_retry_timer_id) { + /* Restart the registration process */ + x2_registered_enb = 0; + x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); + } +# endif break; - case S1AP_DEREGISTERED_ENB_IND: - LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), - S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme); + case X2AP_DEREGISTERED_ENB_IND: + LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2); /* TODO handle recovering of registration */ break; - case TIMER_HAS_EXPIRED: - LOG_I(ENB_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); + case X2AP_REGISTER_ENB_CNF: + LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + X2AP_REGISTER_ENB_CNF(msg_p).nb_x2); - if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) { - /* Restart the registration process */ - registered_enb = 0; - register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); + DevAssert(x2_register_enb_pending > 0); + x2_register_enb_pending--; + + /* Check if at least eNB is registered with one target eNB */ + if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) { + x2_registered_enb++; + } + + /* Check if all register eNB requests have been processed */ + if (x2_register_enb_pending == 0) { + if (x2_registered_enb == enb_nb) { + /* If all eNB are registered, start RRC HO task */ + + }else { + uint32_t x2_not_associated = enb_nb - x2_registered_enb; + + LOG_W(ENB_APP, " %d eNB %s not associated with the target\n", + x2_not_associated, x2_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; -# endif default: LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); @@ -283,3 +378,53 @@ void *eNB_app_task(void *args_p) 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, " * eNB %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/ENB_APP/enb_app.h b/openair2/ENB_APP/enb_app.h index 4dfea72eefbbbf6bc951f562b17f91b869e3ed4a..9eb5ea2400fee9a964fbd8a3fc2d026b612d437f 100644 --- a/openair2/ENB_APP/enb_app.h +++ b/openair2/ENB_APP/enb_app.h @@ -31,11 +31,11 @@ #define ENB_APP_H_ #include <stdint.h> +#include "platform_types.h" void *eNB_app_task(void *args_p); -/* needed for flexran: start PHY and RRC when restarting */ -void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end); +void handle_reconfiguration(module_id_t mod_id); #endif /* ENB_APP_H_ */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 737397d8d497f1b99252427ccb84c6a42d1a02f1..2675e4454c8d549a6a6bcf38da84f6f2bf88f518 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -36,11 +36,13 @@ #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 +#include "intertask_interface.h" +#if defined(ENABLE_USE_MME) +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" +#else +#define EPC_MODE_ENABLED 0 +#endif #endif #include "sctp_default_values.h" #include "SystemInformationBlockType2.h" @@ -59,108 +61,104 @@ #include "enb_paramdef.h" extern uint16_t sf_ahead; - -void RCconfig_flexran() -{ +extern void set_parallel_conf(char *parallel_conf); +extern void set_worker_conf(char *worker_conf); +extern PARALLEL_CONF_t get_thread_parallel_conf(void); +extern WORKER_CONF_t get_thread_worker_conf(void); +extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); +extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); + +void RCconfig_flexran() { uint16_t i; uint16_t num_enbs; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; /* this will possibly truncate the cell id (RRC assumes int32_t). - * Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for - * the bitshifting to work properly */ + Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for + the bitshifting to work properly */ int32_t Nid_cell = 0; uint16_t Nid_cell_tr = 0; uint32_t enb_id = 0; - /* - * the only reason for all these variables is, that they are "hard-encoded" - * into the CCPARAMS_DESC macro and we need it for the Nid_cell variable ... - */ + the only reason for all these variables is, that they are "hard-encoded" + into the CCPARAMS_DESC macro and we need it for the Nid_cell variable ... + */ char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed, - *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled, - *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource, - *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha, - *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2, - *pucch_deltaF_Format2a, *pucch_deltaF_Format2b, - *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB; + *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled, + *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource, + *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha, + *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2, + *pucch_deltaF_Format2a, *pucch_deltaF_Format2b, + *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB; long long int downlink_frequency; int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset, - Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index, - prach_zero_correlation, prach_freq_offset, pucch_delta_shift, - pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower, - pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment, - pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal, - pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles, - rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA, - rach_powerRampingStep, rach_preambleInitialReceivedTargetPower, - rach_preambleTransMax, rach_raResponseWindowSize, - rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx, - pcch_defaultPagingCycle, bcch_modificationPeriodCoeff, - ue_TimersAndConstants_t300, ue_TimersAndConstants_t301, - ue_TimersAndConstants_t310, ue_TimersAndConstants_t311, - ue_TimersAndConstants_n310, ue_TimersAndConstants_n311, - ue_TransmissionMode; - - int32_t ue_multiple_max = 0; - - e_SL_CP_Len_r12 rxPool_sc_CP_Len; - e_SL_PeriodComm_r12 rxPool_sc_Period; - e_SL_CP_Len_r12 rxPool_data_CP_Len; - long rxPool_ResourceConfig_prb_Num; - long rxPool_ResourceConfig_prb_Start; - long rxPool_ResourceConfig_prb_End; - SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present; - long rxPool_ResourceConfig_offsetIndicator_choice; - SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present; - char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; - long rxPool_ResourceConfig_subframeBitmap_choice_bs_size; - long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - - //SIB19 - //for discRxPool - SL_CP_Len_r12_t discRxPool_cp_Len; - e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod; - long discRxPool_numRetx; - long discRxPool_numRepetition; - long discRxPool_ResourceConfig_prb_Num; - long discRxPool_ResourceConfig_prb_Start; - long discRxPool_ResourceConfig_prb_End; - SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present; - long discRxPool_ResourceConfig_offsetIndicator_choice; - SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present; - char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; - long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; - long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - //for discRxPoolPS - SL_CP_Len_r12_t discRxPoolPS_cp_Len; - e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPoolPS_discPeriod; - long discRxPoolPS_numRetx; - long discRxPoolPS_numRepetition; - long discRxPoolPS_ResourceConfig_prb_Num; - long discRxPoolPS_ResourceConfig_prb_Start; - long discRxPoolPS_ResourceConfig_prb_End; - SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present; - long discRxPoolPS_ResourceConfig_offsetIndicator_choice; - SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present; - char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; - long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; - long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - - - + Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index, + prach_zero_correlation, prach_freq_offset, pucch_delta_shift, + pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower, + pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment, + pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal, + pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles, + rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA, + rach_powerRampingStep, rach_preambleInitialReceivedTargetPower, + rach_preambleTransMax, rach_raResponseWindowSize, + rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx, + pcch_defaultPagingCycle, bcch_modificationPeriodCoeff, + ue_TimersAndConstants_t300, ue_TimersAndConstants_t301, + ue_TimersAndConstants_t310, ue_TimersAndConstants_t311, + ue_TimersAndConstants_n310, ue_TimersAndConstants_n311, + ue_TransmissionMode, ue_multiple_max; + const char *rxPool_sc_CP_Len; + const char *rxPool_sc_Period; + const char *rxPool_data_CP_Len; + libconfig_int rxPool_ResourceConfig_prb_Num; + libconfig_int rxPool_ResourceConfig_prb_Start; + libconfig_int rxPool_ResourceConfig_prb_End; + const char *rxPool_ResourceConfig_offsetIndicator_present; + libconfig_int rxPool_ResourceConfig_offsetIndicator_choice; + const char *rxPool_ResourceConfig_subframeBitmap_present; + char *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //SIB19 + //for discRxPool + const char *discRxPool_cp_Len; + const char *discRxPool_discPeriod; + libconfig_int discRxPool_numRetx; + libconfig_int discRxPool_numRepetition; + libconfig_int discRxPool_ResourceConfig_prb_Num; + libconfig_int discRxPool_ResourceConfig_prb_Start; + libconfig_int discRxPool_ResourceConfig_prb_End; + const char *discRxPool_ResourceConfig_offsetIndicator_present; + libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice; + const char *discRxPool_ResourceConfig_subframeBitmap_present; + char *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //for discRxPoolPS + const char *discRxPoolPS_cp_Len; + const char *discRxPoolPS_discPeriod; + libconfig_int discRxPoolPS_numRetx; + libconfig_int discRxPoolPS_numRepetition; + libconfig_int discRxPoolPS_ResourceConfig_prb_Num; + libconfig_int discRxPoolPS_ResourceConfig_prb_Start; + libconfig_int discRxPoolPS_ResourceConfig_prb_End; + const char *discRxPoolPS_ResourceConfig_offsetIndicator_present; + libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice; + const char *discRxPoolPS_ResourceConfig_subframeBitmap_present; + char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; /* get number of eNBs */ paramdef_t ENBSParams[] = ENBSPARAMS_DESC; config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL); num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; - /* for eNB ID */ paramdef_t ENBParams[] = ENBPARAMS_DESC; paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0}; - /* for Nid_cell */ checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC; paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { CCsParams[I].chkPptr = &(config_check_CCparams[I]); @@ -170,11 +168,11 @@ void RCconfig_flexran() config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); if (!RC.flexran) { - RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t*)); + RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t *)); AssertFatal(RC.flexran, "can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n", - num_enbs * sizeof(flexran_agent_info_t*), - num_enbs, sizeof(flexran_agent_info_t*)); + num_enbs * sizeof(flexran_agent_info_t *), + num_enbs, sizeof(flexran_agent_info_t *)); } for (i = 0; i < num_enbs; i++) { @@ -184,32 +182,34 @@ void RCconfig_flexran() sizeof(flexran_agent_info_t), i + 1, num_enbs); /* if config says "yes", enable Agent, in all other cases it's like "no" */ RC.flexran[i]->enabled = strcasecmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0; + /* if not enabled, simply skip the rest, it is not needed anyway */ if (!RC.flexran[i]->enabled) continue; + RC.flexran[i]->interface_name = strdup(*(flexranParams[FLEXRAN_INTERFACE_NAME_IDX].strptr)); //inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN); RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr)); RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); RC.flexran[i]->node_ctrl_state = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION; - config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL); + /* eNB ID from configuration, as read in by RCconfig_RRC() */ if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) { // Calculate a default eNB ID -# if defined(ENABLE_USE_MME) - enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8); -# else - enb_id = i; -# endif + if (EPC_MODE_ENABLED) + enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8); + else + enb_id = i; } else { - enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); + enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); } /* cell ID */ sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i); config_getlist(&CCsParamList, NULL, 0, aprefix); + if (CCsParamList.numelt > 0) { sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0); config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); @@ -218,13 +218,12 @@ void RCconfig_flexran() RC.flexran[i]->mod_id = i; RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr); - /* assume for the moment the monolithic case, i.e. agent can provide - * information for all layers */ + information for all layers */ RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY - | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC - | FLEXRAN_CAP_RLC | FLEXRAN_CAP_PDCP - | FLEXRAN_CAP_SDAP | FLEXRAN_CAP_RRC; + | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC + | FLEXRAN_CAP_RLC | FLEXRAN_CAP_PDCP + | FLEXRAN_CAP_SDAP | FLEXRAN_CAP_RRC; } } @@ -234,29 +233,29 @@ void RCconfig_L1(void) { paramdef_t L1_Params[] = L1PARAMS_DESC; paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0}; - if (RC.eNB == NULL) { - RC.eNB = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB**)); + RC.eNB = (PHY_VARS_eNB ** *)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **)); LOG_I(PHY,"RC.eNB = %p\n",RC.eNB); - memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB**)); + memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **)); RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); } config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); + if (L1_ParamList.numelt > 0) { for (j = 0; j < RC.nb_L1_inst; j++) { RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); if (RC.eNB[j] == NULL) { - RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB*)); - LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); - memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB*)); + RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *)); + LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); + memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *)); } - for (i=0;i<RC.nb_L1_CC[j];i++) { + for (i=0; i<RC.nb_L1_CC[j]; i++) { if (RC.eNB[j][i] == NULL) { RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB)); - memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); + memset((void *)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]); RC.eNB[j][i]->Mod_id = j; RC.eNB[j][i]->CC_id = i; @@ -264,63 +263,51 @@ void RCconfig_L1(void) { } if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { - sf_ahead = 4; // Need 4 subframe gap between RX and TX - } - else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + } else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { RC.eNB[j][0]->eth_params_n.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); - RC.eNB[j][0]->eth_params_n.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); - RC.eNB[j][0]->eth_params_n.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); - RC.eNB[j][0]->eth_params_n.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); - RC.eNB[j][0]->eth_params_n.remote_portc = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); - RC.eNB[j][0]->eth_params_n.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); - RC.eNB[j][0]->eth_params_n.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); - RC.eNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE; - + RC.eNB[j][0]->eth_params_n.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + RC.eNB[j][0]->eth_params_n.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + RC.eNB[j][0]->eth_params_n.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + RC.eNB[j][0]->eth_params_n.remote_portc = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + RC.eNB[j][0]->eth_params_n.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + RC.eNB[j][0]->eth_params_n.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + RC.eNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE; sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 - RC.nb_macrlc_inst = 1; // This is used by mac_top_init_eNB() - // This is used by init_eNB_afterRU() RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int)); RC.nb_CC[0]=1; - RC.nb_inst =1; // DJP - feptx_prec uses num_eNB but phy_init_RU uses nb_inst - LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_inst=1 this is because phy_init_RU() uses that to index and not RC.num_eNB - why the 2 similar variables?\n", __FUNCTION__); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst); - - mac_top_init_eNB(); - - configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n .remote_portd); + //mac_top_init_eNB(); + configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, + RC.eNB[j][0]->eth_params_n .remote_portd); + } else { // other midhaul } - else { // other midhaul - } }// j=0..num_inst + printf("Initializing northbound interface for L1\n"); l1_north_init_eNB(); } else { - LOG_I(PHY,"No " CONFIG_STRING_L1_LIST " configuration found"); - + LOG_I(PHY,"No " CONFIG_STRING_L1_LIST " configuration found"); // DJP need to create some structures for VNF - j = 0; - RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); // DJP - 1 lot then??? - RC.nb_L1_CC[j]=1; // DJP - hmmm if (RC.eNB[j] == NULL) { - RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**)); + RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB **)); LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); - memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***)); + memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB ** *)); } - for (i=0;i<RC.nb_L1_CC[j];i++) { + for (i=0; i<RC.nb_L1_CC[j]; i++) { if (RC.eNB[j][i] == NULL) { RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB)); - memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); + memset((void *)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]); RC.eNB[j][i]->Mod_id = j; RC.eNB[j][i]->CC_id = i; @@ -331,20 +318,16 @@ void RCconfig_L1(void) { void RCconfig_macrlc() { int j; - - paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; + config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); - config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); - if ( MacRLC_ParamList.numelt > 0) { + RC.nb_macrlc_inst=MacRLC_ParamList.numelt; + mac_top_init_eNB(); + RC.nb_mac_CC = (int *)malloc(RC.nb_macrlc_inst*sizeof(int)); - RC.nb_macrlc_inst=MacRLC_ParamList.numelt; - mac_top_init_eNB(); - RC.nb_mac_CC = (int*)malloc(RC.nb_macrlc_inst*sizeof(int)); - - for (j=0;j<RC.nb_macrlc_inst;j++) { + for (j=0; j<RC.nb_macrlc_inst; j++) { RC.mac[j]->puSch10xSnr = *(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); @@ -352,75 +335,65 @@ void RCconfig_macrlc() { //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 - + // check number of instances is same as RRC/PDCP } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) { - RC.mac[j]->eth_params_n.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); - RC.mac[j]->eth_params_n.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); - RC.mac[j]->eth_params_n.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); - RC.mac[j]->eth_params_n.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); - RC.mac[j]->eth_params_n.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); - RC.mac[j]->eth_params_n.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); - RC.mac[j]->eth_params_n.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; - RC.mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + RC.mac[j]->eth_params_n.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); + RC.mac[j]->eth_params_n.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); + RC.mac[j]->eth_params_n.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); + RC.mac[j]->eth_params_n.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); + RC.mac[j]->eth_params_n.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); + RC.mac[j]->eth_params_n.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); + RC.mac[j]->eth_params_n.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; + RC.mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; } else { // other midhaul - AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); - } + AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); + } if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) { - - } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) { - RC.mac[j]->eth_params_s.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); - RC.mac[j]->eth_params_s.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); - RC.mac[j]->eth_params_s.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); - RC.mac[j]->eth_params_s.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); - RC.mac[j]->eth_params_s.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); - RC.mac[j]->eth_params_s.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); - RC.mac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); - RC.mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; - + RC.mac[j]->eth_params_s.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); + RC.mac[j]->eth_params_s.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); + RC.mac[j]->eth_params_s.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); + RC.mac[j]->eth_params_s.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); + RC.mac[j]->eth_params_s.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); + RC.mac[j]->eth_params_s.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); + RC.mac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); + RC.mac[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 - printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc); printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); } else { // other midhaul - AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); + AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } - if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "default") == 0){ - global_scheduler_mode=SCHED_MODE_DEFAULT; - printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); - }else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "fairRR") == 0){ - global_scheduler_mode=SCHED_MODE_FAIR_RR; - printf("sched mode = fairRR %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); - }else{ - global_scheduler_mode=SCHED_MODE_DEFAULT; - printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); + + if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "default") == 0) { + global_scheduler_mode=SCHED_MODE_DEFAULT; + printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); + } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "fairRR") == 0) { + global_scheduler_mode=SCHED_MODE_FAIR_RR; + printf("sched mode = fairRR %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); + } else { + global_scheduler_mode=SCHED_MODE_DEFAULT; + printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); } }// j=0..num_inst } else {// MacRLC_ParamList.numelt > 0 - AssertFatal (0, - "No " CONFIG_STRING_MACRLC_LIST " configuration found"); + AssertFatal (0, + "No " CONFIG_STRING_MACRLC_LIST " configuration found"); } } - -int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { +int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int num_enbs = 0; - int j,k = 0; int32_t enb_id = 0; int nb_cc = 0; - - - char* frame_type = NULL; + char *frame_type = NULL; int32_t tdd_config = 0; int32_t tdd_config_s = 0; - - char* prefix_type = NULL; - char* pbch_repetition = NULL; - + char *prefix_type = NULL; + char *pbch_repetition = NULL; int32_t eutra_band = 0; long long int downlink_frequency = 0; int32_t uplink_frequency_offset = 0; @@ -428,51 +401,50 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t Nid_cell_mbsfn = 0; int32_t N_RB_DL = 0; int32_t nb_antenna_ports = 0; - int32_t prach_root = 0; int32_t prach_config_index = 0; - char* prach_high_speed = NULL; + char *prach_high_speed = NULL; int32_t prach_zero_correlation = 0; int32_t prach_freq_offset = 0; int32_t pucch_delta_shift = 0; int32_t pucch_nRB_CQI = 0; int32_t pucch_nCS_AN = 0; -//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int32_t pucch_n1_AN = 0; -//#endif + //#endif int32_t pdsch_referenceSignalPower = 0; int32_t pdsch_p_b = 0; int32_t pusch_n_SB = 0; - char * pusch_hoppingMode = NULL; + char *pusch_hoppingMode = NULL; int32_t pusch_hoppingOffset = 0; - char* pusch_enable64QAM = NULL; - char* pusch_groupHoppingEnabled = NULL; + char *pusch_enable64QAM = NULL; + char *pusch_groupHoppingEnabled = NULL; int32_t pusch_groupAssignment = 0; - char* pusch_sequenceHoppingEnabled = NULL; + char *pusch_sequenceHoppingEnabled = NULL; int32_t pusch_nDMRS1 = 0; - char* phich_duration = NULL; - char* phich_resource = NULL; - char* srs_enable = NULL; + char *phich_duration = NULL; + char *phich_resource = NULL; + char *srs_enable = NULL; int32_t srs_BandwidthConfig = 0; int32_t srs_SubframeConfig = 0; - char* srs_ackNackST = NULL; - char* srs_MaxUpPts = NULL; + char *srs_ackNackST = NULL; + char *srs_MaxUpPts = NULL; int32_t pusch_p0_Nominal = 0; - char* pusch_alpha = NULL; + char *pusch_alpha = NULL; int32_t pucch_p0_Nominal = 0; int32_t msg3_delta_Preamble = 0; //int32_t ul_CyclicPrefixLength = 0; - char* pucch_deltaF_Format1 = NULL; + char *pucch_deltaF_Format1 = NULL; //const char* pucch_deltaF_Format1a = NULL; - char* pucch_deltaF_Format1b = NULL; - char* pucch_deltaF_Format2 = NULL; - char* pucch_deltaF_Format2a = NULL; - char* pucch_deltaF_Format2b = NULL; + char *pucch_deltaF_Format1b = NULL; + char *pucch_deltaF_Format2 = NULL; + char *pucch_deltaF_Format2a = NULL; + char *pucch_deltaF_Format2b = NULL; int32_t rach_numberOfRA_Preambles = 0; - char* rach_preamblesGroupAConfig = NULL; + char *rach_preamblesGroupAConfig = NULL; int32_t rach_sizeOfRA_PreamblesGroupA = 0; int32_t rach_messageSizeGroupA = 0; - char* rach_messagePowerOffsetGroupB = NULL; + char *rach_messagePowerOffsetGroupB = NULL; int32_t rach_powerRampingStep = 0; int32_t rach_preambleInitialReceivedTargetPower = 0; int32_t rach_preambleTransMax = 0; @@ -480,7 +452,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t rach_macContentionResolutionTimer = 0; int32_t rach_maxHARQ_Msg3Tx = 0; int32_t pcch_defaultPagingCycle = 0; - char* pcch_nB = NULL; + char *pcch_nB = NULL; int32_t bcch_modificationPeriodCoeff = 0; int32_t ue_TimersAndConstants_t300 = 0; int32_t ue_TimersAndConstants_t301 = 0; @@ -489,1976 +461,2099 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t ue_TimersAndConstants_n310 = 0; int32_t ue_TimersAndConstants_n311 = 0; int32_t ue_TransmissionMode = 0; - int32_t ue_multiple_max = 0; - //TTN - for D2D //SIB18 - const char* rxPool_sc_CP_Len = NULL; - const char* rxPool_sc_Period = NULL; - const char* rxPool_data_CP_Len = NULL; + const char *rxPool_sc_CP_Len = NULL; + const char *rxPool_sc_Period = NULL; + const char *rxPool_data_CP_Len = NULL; libconfig_int rxPool_ResourceConfig_prb_Num = 0; libconfig_int rxPool_ResourceConfig_prb_Start = 0; libconfig_int rxPool_ResourceConfig_prb_End = 0; - const char* rxPool_ResourceConfig_offsetIndicator_present = NULL; + const char *rxPool_ResourceConfig_offsetIndicator_present = NULL; libconfig_int rxPool_ResourceConfig_offsetIndicator_choice = 0; - const char* rxPool_ResourceConfig_subframeBitmap_present = NULL; - char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + const char *rxPool_ResourceConfig_subframeBitmap_present = NULL; + char *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0; libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; //SIB19 //For discRxPool - const char* discRxPool_cp_Len = NULL; - const char* discRxPool_discPeriod = NULL; + const char *discRxPool_cp_Len = NULL; + const char *discRxPool_discPeriod = NULL; libconfig_int discRxPool_numRetx = 0; libconfig_int discRxPool_numRepetition = 0; - libconfig_int discRxPool_ResourceConfig_prb_Num = 0; libconfig_int discRxPool_ResourceConfig_prb_Start = 0; libconfig_int discRxPool_ResourceConfig_prb_End = 0; - const char* discRxPool_ResourceConfig_offsetIndicator_present = NULL; + const char *discRxPool_ResourceConfig_offsetIndicator_present = NULL; libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice = 0; - const char* discRxPool_ResourceConfig_subframeBitmap_present = NULL; - char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + const char *discRxPool_ResourceConfig_subframeBitmap_present = NULL; + char *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0; libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; //For discRxPoolPS - const char* discRxPoolPS_cp_Len = NULL; - const char* discRxPoolPS_discPeriod = NULL; + const char *discRxPoolPS_cp_Len = NULL; + const char *discRxPoolPS_discPeriod = NULL; libconfig_int discRxPoolPS_numRetx = 0; libconfig_int discRxPoolPS_numRepetition = 0; - libconfig_int discRxPoolPS_ResourceConfig_prb_Num = 0; libconfig_int discRxPoolPS_ResourceConfig_prb_Start = 0; libconfig_int discRxPoolPS_ResourceConfig_prb_End = 0; - const char* discRxPoolPS_ResourceConfig_offsetIndicator_present = NULL; + const char *discRxPoolPS_ResourceConfig_offsetIndicator_present = NULL; libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice = 0; - const char* discRxPoolPS_ResourceConfig_subframeBitmap_present = NULL; - char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + const char *discRxPoolPS_ResourceConfig_subframeBitmap_present = NULL; + char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size = 0; libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; - int32_t srb1_timer_poll_retransmit = 0; int32_t srb1_timer_reordering = 0; int32_t srb1_timer_status_prohibit = 0; int32_t srb1_poll_pdu = 0; int32_t srb1_poll_byte = 0; int32_t srb1_max_retx_threshold = 0; - int32_t my_int; - - - -/* - int32_t otg_ue_id = 0; - char* otg_app_type = NULL; - char* otg_bg_traffic = NULL; - char* glog_level = NULL; - char* glog_verbosity = NULL; - char* hw_log_level = NULL; - char* hw_log_verbosity = NULL; - char* phy_log_level = NULL; - char* phy_log_verbosity = NULL; - char* mac_log_level = NULL; - char* mac_log_verbosity = NULL; - char* rlc_log_level = NULL; - char* rlc_log_verbosity = NULL; - char* pdcp_log_level = NULL; - char* pdcp_log_verbosity = NULL; - char* rrc_log_level = NULL; - char* rrc_log_verbosity = NULL; - char* udp_log_verbosity = NULL; - char* osa_log_level = NULL; - char* osa_log_verbosity = NULL; -*/ - - - // for no gcc warnings + // for no gcc warnings (void)my_int; paramdef_t ENBSParams[] = ENBSPARAMS_DESC; - paramdef_t ENBParams[] = ENBPARAMS_DESC; - paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; - + paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC; paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0}; - - paramdef_t SRB1Params[] = SRB1PARAMS_DESC; + paramdef_t SRB1Params[] = SRB1PARAMS_DESC; -/* map parameter checking array instances to parameter definition array instances */ + /* map parameter checking array instances to parameter definition array instances */ for (int I=0; I< ( sizeof(CCsParams)/ sizeof(paramdef_t) ) ; I++) { - CCsParams[I].chkPptr = &(config_check_CCparams[I]); + CCsParams[I].chkPptr = &(config_check_CCparams[I]); } -/* get global parameters, defined outside any section in the config file */ - - config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + + /* get global parameters, defined outside any section in the config file */ + config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; AssertFatal (i<num_enbs, - "Failed to parse config file no %ith element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS); - -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - - - if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { - asn_debug = 0; - asn1_xer_print = 0; - } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) { - asn_debug = 1; - asn1_xer_print = 1; - } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) { - asn_debug = 1; - asn1_xer_print = 2; - } else { - asn_debug = 0; - asn1_xer_print = 0; - } - + "Failed to parse config file no %ith element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS); -#endif - - - if (num_enbs>0) { // Output a list of all eNBs. - config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); - - - - - if (ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr == NULL) { - // Calculate a default eNB ID -# if defined(ENABLE_USE_MME) - uint32_t hash; - - hash = s1ap_generate_eNB_id (); - enb_id = i + (hash & 0xFFFF8); -# else - enb_id = i; -# endif + config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); + + if (ENBParamList.paramarray[i][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 = i + (hash & 0xFFFF8); } else { - enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); + enb_id = i; } + } else { + enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); + } - - printf("RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr)); - - if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { + printf("RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr)); + + if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { + } else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) { + rrc->eth_params_s.local_if_name = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr)); + rrc->eth_params_s.my_addr = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr)); + rrc->eth_params_s.remote_addr = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr)); + rrc->eth_params_s.my_portc = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTC_IDX].uptr); + rrc->eth_params_s.remote_portc = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTC_IDX].uptr); + rrc->eth_params_s.my_portd = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr); + rrc->eth_params_s.remote_portd = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr); + rrc->eth_params_s.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + } + // search if in active list + + for (k=0; k <num_enbs ; k++) { + if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) { + char enbpath[MAX_OPTNAME_SIZE + 8]; + sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + 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]); + + RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; + RRC_CONFIGURATION_REQ(msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr + && !ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, + "It seems that you use an old configuration file. Please change the existing\n" + " tracking_area_code = \"1\";\n" + " mobile_country_code = \"208\";\n" + " mobile_network_code = \"93\";\n" + "to\n" + " tracking_area_code = 1; // no string!!\n" + " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), enbpath); + + 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); + + RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt; + + for (int l = 0; l < PLMNParamList.numelt; ++l) { + RRC_CONFIGURATION_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + RRC_CONFIGURATION_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] == 3 + || RRC_CONFIGURATION_REQ(msg_p).mnc[l] < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + RRC_CONFIGURATION_REQ(msg_p).mnc[l]); + } + + // Parse optional physical parameters + config_getlist( &CCsParamList,NULL,0,enbpath); + LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt); + + if ( CCsParamList.numelt> 0) { + char ccspath[MAX_OPTNAME_SIZE*2 + 16]; + + for (j = 0; j < CCsParamList.numelt ; j++) { + sprintf(ccspath,"%s.%s.[%i]",enbpath,ENB_CONFIG_STRING_COMPONENT_CARRIERS,j); + LOG_I(RRC, "enb_config::RCconfig_RRC() parameter number: %d, total number of parameters: %zd, ccspath: %s \n \n", j, sizeof(CCsParams)/sizeof(paramdef_t), ccspath); + config_get( CCsParams,sizeof(CCsParams)/sizeof(paramdef_t),ccspath); + //printf("Component carrier %d\n",component_carrier); + nb_cc++; + RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; + AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6, + "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", + RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6); + RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s; + AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8, + "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", + RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8); + + if (!prefix_type) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); + else if (strcmp(prefix_type, "NORMAL") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; + } else if (strcmp(prefix_type, "EXTENDED") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", + RC.config_file_name, i, prefix_type); + } - } - else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) { - rrc->eth_params_s.local_if_name = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr)); - rrc->eth_params_s.my_addr = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr)); - rrc->eth_params_s.remote_addr = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr)); - rrc->eth_params_s.my_portc = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTC_IDX].uptr); - rrc->eth_params_s.remote_portc = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTC_IDX].uptr); - rrc->eth_params_s.my_portd = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr); - rrc->eth_params_s.remote_portd = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr); - rrc->eth_params_s.transp_preference = ETH_UDP_MODE; - } - - else { // other midhaul - } - - // search if in active list - - - - - - - for (k=0; k <num_enbs ; k++) { - if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) { - char enbpath[MAX_OPTNAME_SIZE + 8]; - - - RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; - - /* - if (strcmp(*(ENBParamList.paramarray[i][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_MACRO_ENB; - } else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->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", - lib_config_file_name_pP, i, cell_type); - } - - enb_properties_loc.properties[enb_properties_loc_index]->eNB_name = strdup(enb_name); - */ - RRC_CONFIGURATION_REQ (msg_p).tac = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].strptr) ); - RRC_CONFIGURATION_REQ (msg_p).mcc = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX].strptr) ); - RRC_CONFIGURATION_REQ (msg_p).mnc = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr) ); - RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - AssertFatal((RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 2) || - (RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 3), - "BAD MNC DIGIT LENGTH %d", - RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length); - - - // Parse optional physical parameters - sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k), - config_getlist( &CCsParamList,NULL,0,enbpath); - - LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt); - if ( CCsParamList.numelt> 0) { - char ccspath[MAX_OPTNAME_SIZE*2 + 16]; - - for (j = 0; j < CCsParamList.numelt ;j++) { - - sprintf(ccspath,"%s.%s.[%i]",enbpath,ENB_CONFIG_STRING_COMPONENT_CARRIERS,j); - LOG_I(RRC, "enb_config::RCconfig_RRC() parameter number: %d, total number of parameters: %zd, ccspath: %s \n \n", j, sizeof(CCsParams)/sizeof(paramdef_t), ccspath); - config_get( CCsParams,sizeof(CCsParams)/sizeof(paramdef_t),ccspath); - - - //printf("Component carrier %d\n",component_carrier); - - - - nb_cc++; - - - RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; - - AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", - RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6); - - RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s; - AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", - RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8); - - if (!prefix_type) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); - else if (strcmp(prefix_type, "NORMAL") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; - } else if (strcmp(prefix_type, "EXTENDED") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", - RC.config_file_name, i, prefix_type); - } #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (!pbch_repetition) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION); - else if (strcmp(pbch_repetition, "TRUE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1; - } else if (strcmp(pbch_repetition, "FALSE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n", - RC.config_file_name, i, pbch_repetition); - } -#endif - - RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = eutra_band; - RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) downlink_frequency; - RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; - RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= Nid_cell; - - 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, i, Nid_cell); - } - - RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= N_RB_DL; - - 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)) { - 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, i, N_RB_DL); - } - - if (strcmp(frame_type, "FDD") == 0) { - RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD; - } else if (strcmp(frame_type, "TDD") == 0) { - RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", - RC.config_file_name, i, frame_type); - } - - - RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; - AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", - RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6); - - - RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s; - AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", - RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8); - - - - if (!prefix_type) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); - else if (strcmp(prefix_type, "NORMAL") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; - } else if (strcmp(prefix_type, "EXTENDED") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", - RC.config_file_name, i, prefix_type); - } - - - - RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = eutra_band; - // printf( "\teutra band:\t%d\n",RRC_CONFIGURATION_REQ (msg_p).eutra_band); - - - - RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) downlink_frequency; - //printf( "\tdownlink freq:\t%u\n",RRC_CONFIGURATION_REQ (msg_p).downlink_frequency); - - - RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; - - if (config_check_band_frequencies(j, - RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], - RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], - RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], - RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) { - AssertFatal(0, "error calling enb_check_band_frequencies\n"); - } - - if ((nb_antenna_ports <1) || (nb_antenna_ports > 2)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n", - RC.config_file_name, i, nb_antenna_ports); - - RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = nb_antenna_ports; - - - RRC_CONFIGURATION_REQ (msg_p).prach_root[j] = prach_root; - - if ((prach_root <0) || (prach_root > 1023)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n", - RC.config_file_name, i, prach_root); - - RRC_CONFIGURATION_REQ (msg_p).prach_config_index[j] = prach_config_index; - - if ((prach_config_index <0) || (prach_config_index > 63)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", - RC.config_file_name, i, prach_config_index); - - if (!prach_high_speed) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); - else if (strcmp(prach_high_speed, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[j] = TRUE; - } else if (strcmp(prach_high_speed, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, prach_high_speed); - - RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[j] =prach_zero_correlation; - - if ((prach_zero_correlation <0) || (prach_zero_correlation > 15)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", - RC.config_file_name, i, prach_zero_correlation); - - RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[j] = prach_freq_offset; - if ((prach_freq_offset <0) || (prach_freq_offset > 94)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", - RC.config_file_name, i, prach_freq_offset); - - RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[j] = pucch_delta_shift-1; - - if ((pucch_delta_shift <1) || (pucch_delta_shift > 3)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", - RC.config_file_name, i, pucch_delta_shift); - - RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[j] = pucch_nRB_CQI; - - if ((pucch_nRB_CQI <0) || (pucch_nRB_CQI > 98)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", - RC.config_file_name, i, pucch_nRB_CQI); - - RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[j] = pucch_nCS_AN; - - if ((pucch_nCS_AN <0) || (pucch_nCS_AN > 7)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", - RC.config_file_name, i, pucch_nCS_AN); - -//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) - RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[j] = pucch_n1_AN; - - if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", - RC.config_file_name, i, pucch_n1_AN); - -//#endif - RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[j] = pdsch_referenceSignalPower; - - if ((pdsch_referenceSignalPower <-60) || (pdsch_referenceSignalPower > 50)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", - RC.config_file_name, i, pdsch_referenceSignalPower); - - RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[j] = pdsch_p_b; - - if ((pdsch_p_b <0) || (pdsch_p_b > 3)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", - RC.config_file_name, i, pdsch_p_b); - - RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[j] = pusch_n_SB; - - if ((pusch_n_SB <1) || (pusch_n_SB > 4)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", - RC.config_file_name, i, pusch_n_SB); - - if (!pusch_hoppingMode) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE); - else if (strcmp(pusch_hoppingMode,"interSubFrame")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; - } else if (strcmp(pusch_hoppingMode,"intraAndInterSubFrame")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", - RC.config_file_name, i, pusch_hoppingMode); - - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[j] = pusch_hoppingOffset; - - if ((pusch_hoppingOffset<0) || (pusch_hoppingOffset>98)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", - RC.config_file_name, i, pusch_hoppingMode); - - if (!pusch_enable64QAM) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); - else if (strcmp(pusch_enable64QAM, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[j] = TRUE; - } else if (strcmp(pusch_enable64QAM, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", - RC.config_file_name, i, pusch_enable64QAM); - - if (!pusch_groupHoppingEnabled) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); - else if (strcmp(pusch_groupHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[j] = TRUE; - } else if (strcmp(pusch_groupHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", - RC.config_file_name, i, pusch_groupHoppingEnabled); - - - RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[j] = pusch_groupAssignment; - - if ((pusch_groupAssignment<0)||(pusch_groupAssignment>29)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", - RC.config_file_name, i, pusch_groupAssignment); - - if (!pusch_sequenceHoppingEnabled) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); - else if (strcmp(pusch_sequenceHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[j] = TRUE; - } else if (strcmp(pusch_sequenceHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", - RC.config_file_name, i, pusch_sequenceHoppingEnabled); - - RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[j] = pusch_nDMRS1; //cyclic_shift in RRC! - - if ((pusch_nDMRS1 <0) || (pusch_nDMRS1>7)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", - RC.config_file_name, i, pusch_nDMRS1); - - if (strcmp(phich_duration,"NORMAL")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_normal; - } else if (strcmp(phich_duration,"EXTENDED")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_extended; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", - RC.config_file_name, i, phich_duration); - - if (strcmp(phich_resource,"ONESIXTH")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_oneSixth ; - } else if (strcmp(phich_resource,"HALF")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_half; - } else if (strcmp(phich_resource,"ONE")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_one; - } else if (strcmp(phich_resource,"TWO")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_two; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", - RC.config_file_name, i, phich_resource); - - printf("phich.resource %ld (%s), phich.duration %ld (%s)\n", - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j],phich_resource, - RRC_CONFIGURATION_REQ (msg_p).phich_duration[j],phich_duration); - - if (strcmp(srs_enable, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] = TRUE; - } else if (strcmp(srs_enable, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, srs_enable); - - if (RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] == TRUE) { - - RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[j] = srs_BandwidthConfig; - - if ((srs_BandwidthConfig < 0) || (srs_BandwidthConfig >7)) - AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n", - RC.config_file_name, i, srs_BandwidthConfig); - - RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[j] = srs_SubframeConfig; - - if ((srs_SubframeConfig<0) || (srs_SubframeConfig>15)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", - RC.config_file_name, i, srs_SubframeConfig); - - if (strcmp(srs_ackNackST, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[j] = TRUE; - } else if (strcmp(srs_ackNackST, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, srs_ackNackST); - - if (strcmp(srs_MaxUpPts, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[j] = TRUE; - } else if (strcmp(srs_MaxUpPts, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, srs_MaxUpPts); - } - - RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[j] = pusch_p0_Nominal; - - if ((pusch_p0_Nominal<-126) || (pusch_p0_Nominal>24)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", - RC.config_file_name, i, pusch_p0_Nominal); -#if (RRC_VERSION <= MAKE_VERSION(12, 0, 0)) - if (strcmp(pusch_alpha,"AL0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al0; - } else if (strcmp(pusch_alpha,"AL04")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al04; - } else if (strcmp(pusch_alpha,"AL05")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al05; - } else if (strcmp(pusch_alpha,"AL06")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al06; - } else if (strcmp(pusch_alpha,"AL07")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al07; - } else if (strcmp(pusch_alpha,"AL08")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al08; - } else if (strcmp(pusch_alpha,"AL09")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al09; - } else if (strcmp(pusch_alpha,"AL1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al1; - } -#endif + if (!pbch_repetition) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION); + else if (strcmp(pbch_repetition, "TRUE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1; + } else if (strcmp(pbch_repetition, "FALSE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n", + RC.config_file_name, i, pbch_repetition); + } -#if (RRC_VERSION >= MAKE_VERSION(12, 0, 0)) - if (strcmp(pusch_alpha,"AL0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al0; - } else if (strcmp(pusch_alpha,"AL04")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al04; - } else if (strcmp(pusch_alpha,"AL05")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al05; - } else if (strcmp(pusch_alpha,"AL06")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al06; - } else if (strcmp(pusch_alpha,"AL07")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al07; - } else if (strcmp(pusch_alpha,"AL08")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al08; - } else if (strcmp(pusch_alpha,"AL09")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al09; - } else if (strcmp(pusch_alpha,"AL1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al1; - } #endif - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", - RC.config_file_name, i, pusch_alpha); - - RRC_CONFIGURATION_REQ (msg_p).pucch_p0_Nominal[j] = pucch_p0_Nominal; - - if ((pucch_p0_Nominal<-127) || (pucch_p0_Nominal>-96)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", - RC.config_file_name, i, pucch_p0_Nominal); - - RRC_CONFIGURATION_REQ (msg_p).msg3_delta_Preamble[j] = msg3_delta_Preamble; - - if ((msg3_delta_Preamble<-1) || (msg3_delta_Preamble>6)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", - RC.config_file_name, i, msg3_delta_Preamble); - - - if (strcmp(pucch_deltaF_Format1,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; - } else if (strcmp(pucch_deltaF_Format1,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0; - } else if (strcmp(pucch_deltaF_Format1,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", - RC.config_file_name, i, pucch_deltaF_Format1); - - if (strcmp(pucch_deltaF_Format1b,"deltaF1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; - } else if (strcmp(pucch_deltaF_Format1b,"deltaF3")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; - } else if (strcmp(pucch_deltaF_Format1b,"deltaF5")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", - RC.config_file_name, i, pucch_deltaF_Format1b); - - - if (strcmp(pucch_deltaF_Format2,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; - } else if (strcmp(pucch_deltaF_Format2,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; - } else if (strcmp(pucch_deltaF_Format2,"deltaF1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1; - } else if (strcmp(pucch_deltaF_Format2,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", - RC.config_file_name, i, pucch_deltaF_Format2); - - if (strcmp(pucch_deltaF_Format2a,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; - } else if (strcmp(pucch_deltaF_Format2a,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; - } else if (strcmp(pucch_deltaF_Format2a,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", - RC.config_file_name, i, pucch_deltaF_Format2a); - - if (strcmp(pucch_deltaF_Format2b,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; - } else if (strcmp(pucch_deltaF_Format2b,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; - } else if (strcmp(pucch_deltaF_Format2b,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", - RC.config_file_name, i, pucch_deltaF_Format2b); - - - - - RRC_CONFIGURATION_REQ (msg_p).rach_numberOfRA_Preambles[j] = (rach_numberOfRA_Preambles/4)-1; - - if ((rach_numberOfRA_Preambles <4) || (rach_numberOfRA_Preambles>64) || ((rach_numberOfRA_Preambles&3)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", - RC.config_file_name, i, rach_numberOfRA_Preambles); - - if (strcmp(rach_preamblesGroupAConfig, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[j] = TRUE; - - - RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[j] = (rach_sizeOfRA_PreamblesGroupA/4)-1; - - if ((rach_numberOfRA_Preambles <4) || (rach_numberOfRA_Preambles>60) || ((rach_numberOfRA_Preambles&3)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", - RC.config_file_name, i, rach_sizeOfRA_PreamblesGroupA); - - - switch (rach_messageSizeGroupA) { - case 56: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; - break; - - case 144: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; - break; - - case 208: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; - break; - - case 256: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", - RC.config_file_name, i, rach_messageSizeGroupA); - break; - } - - if (strcmp(rach_messagePowerOffsetGroupB,"minusinfinity")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; - } - - else if (strcmp(rach_messagePowerOffsetGroupB,"dB0")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0; - } - - else if (strcmp(rach_messagePowerOffsetGroupB,"dB5")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5; - } - - else if (strcmp(rach_messagePowerOffsetGroupB,"dB8")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8; - } + RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = eutra_band; + RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) downlink_frequency; + RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; + RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= Nid_cell; + + 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, i, Nid_cell); + } + + RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= N_RB_DL; + + 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)) { + 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, i, N_RB_DL); + } + + if (strcmp(frame_type, "FDD") == 0) { + RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD; + } else if (strcmp(frame_type, "TDD") == 0) { + RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", + RC.config_file_name, i, frame_type); + } + + RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; + AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6, + "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", + RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6); + RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s; + AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8, + "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", + RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8); + + if (!prefix_type) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); + else if (strcmp(prefix_type, "NORMAL") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; + } else if (strcmp(prefix_type, "EXTENDED") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", + RC.config_file_name, i, prefix_type); + } + + RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = eutra_band; + // printf( "\teutra band:\t%d\n",RRC_CONFIGURATION_REQ (msg_p).eutra_band); + RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) downlink_frequency; + //printf( "\tdownlink freq:\t%u\n",RRC_CONFIGURATION_REQ (msg_p).downlink_frequency); + RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; + + if (config_check_band_frequencies(j, + RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], + RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], + RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], + RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) { + AssertFatal(0, "error calling enb_check_band_frequencies\n"); + } + + if ((nb_antenna_ports <1) || (nb_antenna_ports > 2)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n", + RC.config_file_name, i, nb_antenna_ports); + + RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = nb_antenna_ports; + RRC_CONFIGURATION_REQ (msg_p).prach_root[j] = prach_root; + + if ((prach_root <0) || (prach_root > 1023)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n", + RC.config_file_name, i, prach_root); + + RRC_CONFIGURATION_REQ (msg_p).prach_config_index[j] = prach_config_index; + + if ((prach_config_index <0) || (prach_config_index > 63)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", + RC.config_file_name, i, prach_config_index); + + if (!prach_high_speed) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); + else if (strcmp(prach_high_speed, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[j] = TRUE; + } else if (strcmp(prach_high_speed, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, prach_high_speed); + + RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[j] =prach_zero_correlation; + + if ((prach_zero_correlation <0) || (prach_zero_correlation > 15)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", + RC.config_file_name, i, prach_zero_correlation); + + RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[j] = prach_freq_offset; + + if ((prach_freq_offset <0) || (prach_freq_offset > 94)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", + RC.config_file_name, i, prach_freq_offset); + + RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[j] = pucch_delta_shift-1; + + if ((pucch_delta_shift <1) || (pucch_delta_shift > 3)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", + RC.config_file_name, i, pucch_delta_shift); + + RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[j] = pucch_nRB_CQI; + + if ((pucch_nRB_CQI <0) || (pucch_nRB_CQI > 98)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", + RC.config_file_name, i, pucch_nRB_CQI); + + RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[j] = pucch_nCS_AN; + + if ((pucch_nCS_AN <0) || (pucch_nCS_AN > 7)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", + RC.config_file_name, i, pucch_nCS_AN); + + //#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) + RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[j] = pucch_n1_AN; + + if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", + RC.config_file_name, i, pucch_n1_AN); + + //#endif + RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[j] = pdsch_referenceSignalPower; + + if ((pdsch_referenceSignalPower <-60) || (pdsch_referenceSignalPower > 50)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", + RC.config_file_name, i, pdsch_referenceSignalPower); + + RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[j] = pdsch_p_b; + + if ((pdsch_p_b <0) || (pdsch_p_b > 3)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", + RC.config_file_name, i, pdsch_p_b); + + RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[j] = pusch_n_SB; + + if ((pusch_n_SB <1) || (pusch_n_SB > 4)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", + RC.config_file_name, i, pusch_n_SB); + + if (!pusch_hoppingMode) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE); + else if (strcmp(pusch_hoppingMode,"interSubFrame")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; + } else if (strcmp(pusch_hoppingMode,"intraAndInterSubFrame")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", + RC.config_file_name, i, pusch_hoppingMode); + + RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[j] = pusch_hoppingOffset; + + if ((pusch_hoppingOffset<0) || (pusch_hoppingOffset>98)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", + RC.config_file_name, i, pusch_hoppingMode); + + if (!pusch_enable64QAM) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); + else if (strcmp(pusch_enable64QAM, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[j] = TRUE; + } else if (strcmp(pusch_enable64QAM, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", + RC.config_file_name, i, pusch_enable64QAM); + + if (!pusch_groupHoppingEnabled) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); + else if (strcmp(pusch_groupHoppingEnabled, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[j] = TRUE; + } else if (strcmp(pusch_groupHoppingEnabled, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", + RC.config_file_name, i, pusch_groupHoppingEnabled); + + RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[j] = pusch_groupAssignment; + + if ((pusch_groupAssignment<0)||(pusch_groupAssignment>29)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", + RC.config_file_name, i, pusch_groupAssignment); + + if (!pusch_sequenceHoppingEnabled) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); + else if (strcmp(pusch_sequenceHoppingEnabled, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[j] = TRUE; + } else if (strcmp(pusch_sequenceHoppingEnabled, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", + RC.config_file_name, i, pusch_sequenceHoppingEnabled); + + RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[j] = pusch_nDMRS1; //cyclic_shift in RRC! + + if ((pusch_nDMRS1 <0) || (pusch_nDMRS1>7)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", + RC.config_file_name, i, pusch_nDMRS1); + + if (strcmp(phich_duration,"NORMAL")==0) { + RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_normal; + } else if (strcmp(phich_duration,"EXTENDED")==0) { + RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", + RC.config_file_name, i, phich_duration); + + if (strcmp(phich_resource,"ONESIXTH")==0) { + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_oneSixth ; + } else if (strcmp(phich_resource,"HALF")==0) { + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_half; + } else if (strcmp(phich_resource,"ONE")==0) { + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_one; + } else if (strcmp(phich_resource,"TWO")==0) { + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_two; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", + RC.config_file_name, i, phich_resource); + + printf("phich.resource %ld (%s), phich.duration %ld (%s)\n", + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j],phich_resource, + RRC_CONFIGURATION_REQ (msg_p).phich_duration[j],phich_duration); + + if (strcmp(srs_enable, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] = TRUE; + } else if (strcmp(srs_enable, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, srs_enable); + + if (RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] == TRUE) { + RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[j] = srs_BandwidthConfig; + + if ((srs_BandwidthConfig < 0) || (srs_BandwidthConfig >7)) + AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n", + RC.config_file_name, i, srs_BandwidthConfig); + + RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[j] = srs_SubframeConfig; + + if ((srs_SubframeConfig<0) || (srs_SubframeConfig>15)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", + RC.config_file_name, i, srs_SubframeConfig); + + if (strcmp(srs_ackNackST, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[j] = TRUE; + } else if (strcmp(srs_ackNackST, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, srs_ackNackST); + + if (strcmp(srs_MaxUpPts, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[j] = TRUE; + } else if (strcmp(srs_MaxUpPts, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, srs_MaxUpPts); + } + + RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[j] = pusch_p0_Nominal; + + if ((pusch_p0_Nominal<-126) || (pusch_p0_Nominal>24)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", + RC.config_file_name, i, pusch_p0_Nominal); - else if (strcmp(rach_messagePowerOffsetGroupB,"dB10")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10; - } - - else if (strcmp(rach_messagePowerOffsetGroupB,"dB12")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12; - } +#if (RRC_VERSION <= MAKE_VERSION(12, 0, 0)) - else if (strcmp(rach_messagePowerOffsetGroupB,"dB15")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15; - } + if (strcmp(pusch_alpha,"AL0")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al0; + } else if (strcmp(pusch_alpha,"AL04")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al04; + } else if (strcmp(pusch_alpha,"AL05")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al05; + } else if (strcmp(pusch_alpha,"AL06")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al06; + } else if (strcmp(pusch_alpha,"AL07")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al07; + } else if (strcmp(pusch_alpha,"AL08")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al08; + } else if (strcmp(pusch_alpha,"AL09")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al09; + } else if (strcmp(pusch_alpha,"AL1")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al1; + } - else if (strcmp(rach_messagePowerOffsetGroupB,"dB18")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", - RC.config_file_name, i, rach_messagePowerOffsetGroupB); +#endif +#if (RRC_VERSION >= MAKE_VERSION(12, 0, 0)) - } else if (strcmp(rach_preamblesGroupAConfig, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[j] = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, rach_preamblesGroupAConfig); + if (strcmp(pusch_alpha,"AL0")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al0; + } else if (strcmp(pusch_alpha,"AL04")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al04; + } else if (strcmp(pusch_alpha,"AL05")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al05; + } else if (strcmp(pusch_alpha,"AL06")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al06; + } else if (strcmp(pusch_alpha,"AL07")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al07; + } else if (strcmp(pusch_alpha,"AL08")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al08; + } else if (strcmp(pusch_alpha,"AL09")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al09; + } else if (strcmp(pusch_alpha,"AL1")==0) { + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al1; + } - RRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower[j] = (rach_preambleInitialReceivedTargetPower+120)/2; +#endif + else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", + RC.config_file_name, i, pusch_alpha); + + RRC_CONFIGURATION_REQ (msg_p).pucch_p0_Nominal[j] = pucch_p0_Nominal; + + if ((pucch_p0_Nominal<-127) || (pucch_p0_Nominal>-96)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", + RC.config_file_name, i, pucch_p0_Nominal); + + RRC_CONFIGURATION_REQ (msg_p).msg3_delta_Preamble[j] = msg3_delta_Preamble; + + if ((msg3_delta_Preamble<-1) || (msg3_delta_Preamble>6)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", + RC.config_file_name, i, msg3_delta_Preamble); + + if (strcmp(pucch_deltaF_Format1,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; + } else if (strcmp(pucch_deltaF_Format1,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0; + } else if (strcmp(pucch_deltaF_Format1,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", + RC.config_file_name, i, pucch_deltaF_Format1); + + if (strcmp(pucch_deltaF_Format1b,"deltaF1")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; + } else if (strcmp(pucch_deltaF_Format1b,"deltaF3")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; + } else if (strcmp(pucch_deltaF_Format1b,"deltaF5")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", + RC.config_file_name, i, pucch_deltaF_Format1b); + + if (strcmp(pucch_deltaF_Format2,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; + } else if (strcmp(pucch_deltaF_Format2,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; + } else if (strcmp(pucch_deltaF_Format2,"deltaF1")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1; + } else if (strcmp(pucch_deltaF_Format2,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", + RC.config_file_name, i, pucch_deltaF_Format2); + + if (strcmp(pucch_deltaF_Format2a,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; + } else if (strcmp(pucch_deltaF_Format2a,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; + } else if (strcmp(pucch_deltaF_Format2a,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", + RC.config_file_name, i, pucch_deltaF_Format2a); + + if (strcmp(pucch_deltaF_Format2b,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; + } else if (strcmp(pucch_deltaF_Format2b,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; + } else if (strcmp(pucch_deltaF_Format2b,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", + RC.config_file_name, i, pucch_deltaF_Format2b); + + RRC_CONFIGURATION_REQ (msg_p).rach_numberOfRA_Preambles[j] = (rach_numberOfRA_Preambles/4)-1; + + if ((rach_numberOfRA_Preambles <4) || (rach_numberOfRA_Preambles>64) || ((rach_numberOfRA_Preambles&3)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", + RC.config_file_name, i, rach_numberOfRA_Preambles); + + if (strcmp(rach_preamblesGroupAConfig, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[j] = TRUE; + RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[j] = (rach_sizeOfRA_PreamblesGroupA/4)-1; + + if ((rach_numberOfRA_Preambles <4) || (rach_numberOfRA_Preambles>60) || ((rach_numberOfRA_Preambles&3)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", + RC.config_file_name, i, rach_sizeOfRA_PreamblesGroupA); + + switch (rach_messageSizeGroupA) { + case 56: + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; + break; + + case 144: + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; + break; + + case 208: + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; + break; + + case 256: + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", + RC.config_file_name, i, rach_messageSizeGroupA); + break; + } + + if (strcmp(rach_messagePowerOffsetGroupB,"minusinfinity")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB0")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB5")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB8")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB10")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB12")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB15")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15; + } else if (strcmp(rach_messagePowerOffsetGroupB,"dB18")==0) { + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", + RC.config_file_name, i, rach_messagePowerOffsetGroupB); + } else if (strcmp(rach_preamblesGroupAConfig, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[j] = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, rach_preamblesGroupAConfig); + + RRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower[j] = (rach_preambleInitialReceivedTargetPower+120)/2; + + if ((rach_preambleInitialReceivedTargetPower<-120) || (rach_preambleInitialReceivedTargetPower>-90) || ((rach_preambleInitialReceivedTargetPower&1)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", + RC.config_file_name, i, rach_preambleInitialReceivedTargetPower); + + RRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep[j] = rach_powerRampingStep/2; + + if ((rach_powerRampingStep<0) || (rach_powerRampingStep>6) || ((rach_powerRampingStep&1)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", + RC.config_file_name, i, rach_powerRampingStep); + + switch (rach_preambleTransMax) { +#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) - if ((rach_preambleInitialReceivedTargetPower<-120) || (rach_preambleInitialReceivedTargetPower>-90) || ((rach_preambleInitialReceivedTargetPower&1)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", - RC.config_file_name, i, rach_preambleInitialReceivedTargetPower); + case 3: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; + break; + case 4: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; + break; - RRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep[j] = rach_powerRampingStep/2; + case 5: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; + break; - if ((rach_powerRampingStep<0) || (rach_powerRampingStep>6) || ((rach_powerRampingStep&1)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", - RC.config_file_name, i, rach_powerRampingStep); + case 6: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; + break; + case 7: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; + break; + case 8: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; + break; - switch (rach_preambleTransMax) { -#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) - case 3: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; - break; + case 10: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; + break; - case 4: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; - break; + case 20: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; + break; - case 5: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; - break; + case 50: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; + break; - case 6: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; - break; + case 100: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; + break; - case 7: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; - break; + case 200: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; + break; +#else - case 8: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; - break; + case 3: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n3; + break; - case 10: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; - break; + case 4: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n4; + break; - case 20: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; - break; + case 5: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n5; + break; - case 50: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; - break; + case 6: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n6; + break; - case 100: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; - break; + case 7: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n7; + break; - case 200: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; - break; + case 8: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n8; + break; -#else + case 10: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n10; + break; - case 3: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n3; - break; + case 20: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n20; + break; - case 4: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n4; - break; + case 50: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n50; + break; - case 5: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n5; - break; + case 100: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n100; + break; - case 6: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n6; - break; + case 200: + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n200; + break; +#endif - case 7: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n7; - break; + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", + RC.config_file_name, i, rach_preambleTransMax); + break; + } + + RRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize[j] = (rach_raResponseWindowSize==10)?7:rach_raResponseWindowSize-2; + + if ((rach_raResponseWindowSize<0)||(rach_raResponseWindowSize==9)||(rach_raResponseWindowSize>10)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", + RC.config_file_name, i, rach_preambleTransMax); + + RRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer[j] = (rach_macContentionResolutionTimer/8)-1; + + if ((rach_macContentionResolutionTimer<8) || (rach_macContentionResolutionTimer>64) || ((rach_macContentionResolutionTimer&7)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", + RC.config_file_name, i, rach_preambleTransMax); + + RRC_CONFIGURATION_REQ (msg_p).rach_maxHARQ_Msg3Tx[j] = rach_maxHARQ_Msg3Tx; + + if ((rach_maxHARQ_Msg3Tx<0) || (rach_maxHARQ_Msg3Tx>8)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", + RC.config_file_name, i, rach_preambleTransMax); + + switch (pcch_defaultPagingCycle) { + case 32: + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf32; + break; + + case 64: + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf64; + break; + + case 128: + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf128; + break; + + case 256: + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf256; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", + RC.config_file_name, i, pcch_defaultPagingCycle); + break; + } + + if (strcmp(pcch_nB, "fourT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_fourT; + } else if (strcmp(pcch_nB, "twoT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_twoT; + } else if (strcmp(pcch_nB, "oneT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneT; + } else if (strcmp(pcch_nB, "halfT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_halfT; + } else if (strcmp(pcch_nB, "quarterT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_quarterT; + } else if (strcmp(pcch_nB, "oneEighthT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneEighthT; + } else if (strcmp(pcch_nB, "oneSixteenthT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneSixteenthT; + } else if (strcmp(pcch_nB, "oneThirtySecondT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneThirtySecondT; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", + RC.config_file_name, i, pcch_defaultPagingCycle); + + switch (bcch_modificationPeriodCoeff) { + case 2: + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n2; + break; + + case 4: + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n4; + break; + + case 8: + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n8; + break; + + case 16: + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n16; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", + RC.config_file_name, i, bcch_modificationPeriodCoeff); + break; + } + + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = ue_TimersAndConstants_t300; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = ue_TimersAndConstants_t301; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = ue_TimersAndConstants_t310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = ue_TimersAndConstants_t311; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = ue_TimersAndConstants_n310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = ue_TimersAndConstants_n311; + + switch (ue_TransmissionMode) { + case 1: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm1; + break; + + case 2: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm2; + break; + + case 3: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm3; + break; + + case 4: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm4; + break; + + case 5: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm5; + break; + + case 6: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm6; + break; + + case 7: + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm7; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", + RC.config_file_name, i, ue_TransmissionMode); + break; + } + + RRC_CONFIGURATION_REQ (msg_p).ue_multiple_max[j] = ue_multiple_max; + + switch (N_RB_DL) { + case 25: + if ((ue_multiple_max < 1) || (ue_multiple_max > 4)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", + RC.config_file_name, i, ue_multiple_max); + + break; + + case 50: + if ((ue_multiple_max < 1) || (ue_multiple_max > 8)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", + RC.config_file_name, i, ue_multiple_max); + + break; + + case 100: + if ((ue_multiple_max < 1) || (ue_multiple_max > 16)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", + RC.config_file_name, i, ue_multiple_max); + + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", + RC.config_file_name, i, N_RB_DL); + break; + } + + //TTN - for D2D + //SIB18 + if (strcmp(rxPool_sc_CP_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(rxPool_sc_CP_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_CP_Len choice: normal,extended!\n", + RC.config_file_name, i, rxPool_sc_CP_Len); + + if (strcmp(rxPool_sc_Period,"sf40")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf40; + } else if (strcmp(rxPool_sc_Period,"sf60")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf60; + } else if (strcmp(rxPool_sc_Period,"sf70")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf70; + } else if (strcmp(rxPool_sc_Period,"sf80")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf80; + } else if (strcmp(rxPool_sc_Period,"sf120")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf120; + } else if (strcmp(rxPool_sc_Period,"sf140")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf140; + } else if (strcmp(rxPool_sc_Period,"sf160")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf160; + } else if (strcmp(rxPool_sc_Period,"sf240")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf240; + } else if (strcmp(rxPool_sc_Period,"sf280")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf280; + } else if (strcmp(rxPool_sc_Period,"sf320")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf320; + } else if (strcmp(rxPool_sc_Period,"spare6")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare6; + } else if (strcmp(rxPool_sc_Period,"spare5")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare5; + } else if (strcmp(rxPool_sc_Period,"spare4")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare4; + } else if (strcmp(rxPool_sc_Period,"spare3")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare3; + } else if (strcmp(rxPool_sc_Period,"spare2")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare2; + } else if (strcmp(rxPool_sc_Period,"spare")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_Period choice: sf40,sf60,sf70,sf80,sf120,sf140,sf160,sf240,sf280,sf320,spare6,spare5,spare4,spare3,spare2,spare!\n", + RC.config_file_name, i, rxPool_sc_Period); + + if (strcmp(rxPool_data_CP_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(rxPool_data_CP_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_data_CP_Len choice: normal,extended!\n", + RC.config_file_name, i, rxPool_data_CP_Len); + + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Num[j] = rxPool_ResourceConfig_prb_Num; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Start[j] = rxPool_ResourceConfig_prb_Start; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_End[j] = rxPool_ResourceConfig_prb_End; + + if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", + RC.config_file_name, i, rxPool_ResourceConfig_offsetIndicator_present); + + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_choice[j] = rxPool_ResourceConfig_offsetIndicator_choice; + + if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", + RC.config_file_name, i, rxPool_ResourceConfig_subframeBitmap_present); + + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_size[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_size; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + //SIB19 - for discRxPool + if (strcmp(discRxPool_cp_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(discRxPool_cp_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_cp_Len choice: normal,extended!\n", + RC.config_file_name, i, discRxPool_cp_Len); + + if (strcmp(discRxPool_discPeriod,"rf32")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; + } else if (strcmp(discRxPool_discPeriod,"rf64")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; + } else if (strcmp(discRxPool_discPeriod,"rf128")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; + } else if (strcmp(discRxPool_discPeriod,"rf256")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; + } else if (strcmp(discRxPool_discPeriod,"rf512")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; + } else if (strcmp(discRxPool_discPeriod,"rf1024")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; + } else if (strcmp(discRxPool_discPeriod,"rf16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; + } else if (strcmp(discRxPool_discPeriod,"spare")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", + RC.config_file_name, i, discRxPool_discPeriod); + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRetx[j] = discRxPool_numRetx; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRepetition[j] = discRxPool_numRepetition; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Num[j] = discRxPool_ResourceConfig_prb_Num; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Start[j] = discRxPool_ResourceConfig_prb_Start; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_End[j] = discRxPool_ResourceConfig_prb_End; + + if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", + RC.config_file_name, i, discRxPool_ResourceConfig_offsetIndicator_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_choice[j] = discRxPool_ResourceConfig_offsetIndicator_choice; + + if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", + RC.config_file_name, i, discRxPool_ResourceConfig_subframeBitmap_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + + //SIB19 - For discRxPoolPS + if (strcmp(discRxPoolPS_cp_Len,"normal")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_normal; + } else if (strcmp(discRxPoolPS_cp_Len,"extended")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_cp_Len choice: normal,extended!\n", + RC.config_file_name, i, discRxPoolPS_cp_Len); + + if (strcmp(discRxPoolPS_discPeriod,"rf32")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; + } else if (strcmp(discRxPoolPS_discPeriod,"rf64")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; + } else if (strcmp(discRxPoolPS_discPeriod,"rf128")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; + } else if (strcmp(discRxPoolPS_discPeriod,"rf256")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; + } else if (strcmp(discRxPoolPS_discPeriod,"rf512")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; + } else if (strcmp(discRxPoolPS_discPeriod,"rf1024")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; + } else if (strcmp(discRxPoolPS_discPeriod,"rf16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; + } else if (strcmp(discRxPoolPS_discPeriod,"spare")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", + RC.config_file_name, i, discRxPoolPS_discPeriod); + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRetx[j] = discRxPoolPS_numRetx; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRepetition[j] = discRxPoolPS_numRepetition; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Num[j] = discRxPoolPS_ResourceConfig_prb_Num; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Start[j] = discRxPoolPS_ResourceConfig_prb_Start; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_End[j] = discRxPoolPS_ResourceConfig_prb_End; + + if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prSmall")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prLarge")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", + RC.config_file_name, i, discRxPoolPS_ResourceConfig_offsetIndicator_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_choice[j] = discRxPoolPS_ResourceConfig_offsetIndicator_choice; + + if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prNothing")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs4")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs8")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs12")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs16")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs30")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs40")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs42")==0) { + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", + RC.config_file_name, i, discRxPoolPS_ResourceConfig_subframeBitmap_present); + + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + } + } - case 8: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n8; - break; + char srb1path[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1); + int npar = config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path); + + if (npar == sizeof(SRB1Params)/sizeof(paramdef_t)) { + switch (srb1_max_retx_threshold) { + case 1: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t1; + break; + + case 2: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t2; + break; + + case 3: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t3; + break; + + case 4: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t4; + break; + + case 6: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t6; + break; + + case 8: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; + break; + + case 16: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t16; + break; + + case 32: + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t32; + break; + + default: + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_max_retx_threshold %u!\n", + RC.config_file_name, i, srb1_max_retx_threshold); + } + + switch (srb1_poll_pdu) { + case 4: + rrc->srb1_poll_pdu = PollPDU_p4; + break; + + case 8: + rrc->srb1_poll_pdu = PollPDU_p8; + break; + + case 16: + rrc->srb1_poll_pdu = PollPDU_p16; + break; + + case 32: + rrc->srb1_poll_pdu = PollPDU_p32; + break; + + case 64: + rrc->srb1_poll_pdu = PollPDU_p64; + break; + + case 128: + rrc->srb1_poll_pdu = PollPDU_p128; + break; + + case 256: + rrc->srb1_poll_pdu = PollPDU_p256; + break; + + default: + if (srb1_poll_pdu >= 10000) + rrc->srb1_poll_pdu = PollPDU_pInfinity; + else + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_pdu %u!\n", + RC.config_file_name, i, srb1_poll_pdu); + } + + rrc->srb1_poll_byte = srb1_poll_byte; + + switch (srb1_poll_byte) { + case 25: + rrc->srb1_poll_byte = PollByte_kB25; + break; + + case 50: + rrc->srb1_poll_byte = PollByte_kB50; + break; + + case 75: + rrc->srb1_poll_byte = PollByte_kB75; + break; + + case 100: + rrc->srb1_poll_byte = PollByte_kB100; + break; + + case 125: + rrc->srb1_poll_byte = PollByte_kB125; + break; + + case 250: + rrc->srb1_poll_byte = PollByte_kB250; + break; + + case 375: + rrc->srb1_poll_byte = PollByte_kB375; + break; + + case 500: + rrc->srb1_poll_byte = PollByte_kB500; + break; + + case 750: + rrc->srb1_poll_byte = PollByte_kB750; + break; + + case 1000: + rrc->srb1_poll_byte = PollByte_kB1000; + break; + + case 1250: + rrc->srb1_poll_byte = PollByte_kB1250; + break; + + case 1500: + rrc->srb1_poll_byte = PollByte_kB1500; + break; + + case 2000: + rrc->srb1_poll_byte = PollByte_kB2000; + break; + + case 3000: + rrc->srb1_poll_byte = PollByte_kB3000; + break; + + default: + if (srb1_poll_byte >= 10000) + rrc->srb1_poll_byte = PollByte_kBinfinity; + else + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_byte %u!\n", + RC.config_file_name, i, srb1_poll_byte); + } + + if (srb1_timer_poll_retransmit <= 250) { + rrc->srb1_timer_poll_retransmit = (srb1_timer_poll_retransmit - 5)/5; + } else if (srb1_timer_poll_retransmit <= 500) { + rrc->srb1_timer_poll_retransmit = (srb1_timer_poll_retransmit - 300)/50 + 50; + } else { + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_poll_retransmit %u!\n", + RC.config_file_name, i, srb1_timer_poll_retransmit); + } + + if (srb1_timer_status_prohibit <= 250) { + rrc->srb1_timer_status_prohibit = srb1_timer_status_prohibit/5; + } else if ((srb1_timer_poll_retransmit >= 300) && (srb1_timer_poll_retransmit <= 500)) { + rrc->srb1_timer_status_prohibit = (srb1_timer_status_prohibit - 300)/50 + 51; + } else { + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_status_prohibit %u!\n", + RC.config_file_name, i, srb1_timer_status_prohibit); + } + + switch (srb1_timer_reordering) { + case 0: + rrc->srb1_timer_reordering = T_Reordering_ms0; + break; - case 10: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n10; - break; + case 5: + rrc->srb1_timer_reordering = T_Reordering_ms5; + break; - case 20: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n20; - break; + case 10: + rrc->srb1_timer_reordering = T_Reordering_ms10; + break; - case 50: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n50; - break; + case 15: + rrc->srb1_timer_reordering = T_Reordering_ms15; + break; - case 100: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n100; - break; + case 20: + rrc->srb1_timer_reordering = T_Reordering_ms20; + break; - case 200: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n200; - break; -#endif + case 25: + rrc->srb1_timer_reordering = T_Reordering_ms25; + break; - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", - RC.config_file_name, i, rach_preambleTransMax); - break; - } - - RRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize[j] = (rach_raResponseWindowSize==10)?7:rach_raResponseWindowSize-2; - - if ((rach_raResponseWindowSize<0)||(rach_raResponseWindowSize==9)||(rach_raResponseWindowSize>10)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", - RC.config_file_name, i, rach_preambleTransMax); - - - RRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer[j] = (rach_macContentionResolutionTimer/8)-1; - - if ((rach_macContentionResolutionTimer<8) || (rach_macContentionResolutionTimer>64) || ((rach_macContentionResolutionTimer&7)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", - RC.config_file_name, i, rach_preambleTransMax); - - RRC_CONFIGURATION_REQ (msg_p).rach_maxHARQ_Msg3Tx[j] = rach_maxHARQ_Msg3Tx; - - if ((rach_maxHARQ_Msg3Tx<0) || (rach_maxHARQ_Msg3Tx>8)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", - RC.config_file_name, i, rach_preambleTransMax); - - - switch (pcch_defaultPagingCycle) { - case 32: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf32; - break; - - case 64: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf64; - break; - - case 128: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf128; - break; - - case 256: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf256; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", - RC.config_file_name, i, pcch_defaultPagingCycle); - break; - } - - if (strcmp(pcch_nB, "fourT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_fourT; - } else if (strcmp(pcch_nB, "twoT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_twoT; - } else if (strcmp(pcch_nB, "oneT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneT; - } else if (strcmp(pcch_nB, "halfT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_halfT; - } else if (strcmp(pcch_nB, "quarterT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_quarterT; - } else if (strcmp(pcch_nB, "oneEighthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneEighthT; - } else if (strcmp(pcch_nB, "oneSixteenthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneSixteenthT; - } else if (strcmp(pcch_nB, "oneThirtySecondT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneThirtySecondT; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", - RC.config_file_name, i, pcch_defaultPagingCycle); - - - - switch (bcch_modificationPeriodCoeff) { - case 2: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n2; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n4; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n8; - break; - - case 16: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n16; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", - RC.config_file_name, i, bcch_modificationPeriodCoeff); - - break; - } - - - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = ue_TimersAndConstants_t300; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = ue_TimersAndConstants_t301; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = ue_TimersAndConstants_t310; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = ue_TimersAndConstants_t311; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = ue_TimersAndConstants_n310; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = ue_TimersAndConstants_n311; - - switch (ue_TransmissionMode) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm1; - break; - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm2; - break; - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm3; - break; - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm4; - break; - case 5: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm5; - break; - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm6; - break; - case 7: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm7; - break; - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", - RC.config_file_name, i, ue_TransmissionMode); - break; - } - - RRC_CONFIGURATION_REQ (msg_p).ue_multiple_max[j] = ue_multiple_max; - - switch (N_RB_DL) { - case 25: - if ((ue_multiple_max < 1) || (ue_multiple_max > 4)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", - RC.config_file_name, i, ue_multiple_max); - break; - case 50: - if ((ue_multiple_max < 1) || (ue_multiple_max > 8)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", - RC.config_file_name, i, ue_multiple_max); - break; - case 100: - if ((ue_multiple_max < 1) || (ue_multiple_max > 16)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", - RC.config_file_name, i, ue_multiple_max); - break; - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", - RC.config_file_name, i, N_RB_DL); - break; + case 30: + rrc->srb1_timer_reordering = T_Reordering_ms30; + break; + + case 35: + rrc->srb1_timer_reordering = T_Reordering_ms35; + break; + + case 40: + rrc->srb1_timer_reordering = T_Reordering_ms40; + break; + + case 45: + rrc->srb1_timer_reordering = T_Reordering_ms45; + break; + + case 50: + rrc->srb1_timer_reordering = T_Reordering_ms50; + break; + + case 55: + rrc->srb1_timer_reordering = T_Reordering_ms55; + break; + + case 60: + rrc->srb1_timer_reordering = T_Reordering_ms60; + break; + + case 65: + rrc->srb1_timer_reordering = T_Reordering_ms65; + break; + + case 70: + rrc->srb1_timer_reordering = T_Reordering_ms70; + break; + + case 75: + rrc->srb1_timer_reordering = T_Reordering_ms75; + break; + + case 80: + rrc->srb1_timer_reordering = T_Reordering_ms80; + break; + + case 85: + rrc->srb1_timer_reordering = T_Reordering_ms85; + break; + + case 90: + rrc->srb1_timer_reordering = T_Reordering_ms90; + break; + + case 95: + rrc->srb1_timer_reordering = T_Reordering_ms95; + break; + + case 100: + rrc->srb1_timer_reordering = T_Reordering_ms100; + break; + + case 110: + rrc->srb1_timer_reordering = T_Reordering_ms110; + break; + + case 120: + rrc->srb1_timer_reordering = T_Reordering_ms120; + break; + + case 130: + rrc->srb1_timer_reordering = T_Reordering_ms130; + break; + + case 140: + rrc->srb1_timer_reordering = T_Reordering_ms140; + break; + + case 150: + rrc->srb1_timer_reordering = T_Reordering_ms150; + break; + + case 160: + rrc->srb1_timer_reordering = T_Reordering_ms160; + break; + + case 170: + rrc->srb1_timer_reordering = T_Reordering_ms170; + break; + + case 180: + rrc->srb1_timer_reordering = T_Reordering_ms180; + break; + + case 190: + rrc->srb1_timer_reordering = T_Reordering_ms190; + break; + + case 200: + rrc->srb1_timer_reordering = T_Reordering_ms200; + break; + + default: + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_reordering %u!\n", + RC.config_file_name, i, srb1_timer_reordering); + } + } else { + rrc->srb1_timer_poll_retransmit = T_PollRetransmit_ms80; + rrc->srb1_timer_reordering = T_Reordering_ms35; + rrc->srb1_timer_status_prohibit = T_StatusProhibit_ms0; + rrc->srb1_poll_pdu = PollPDU_p4; + rrc->srb1_poll_byte = PollByte_kBinfinity; + rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; } - //TTN - for D2D - //SIB18 - if (strcmp(rxPool_sc_CP_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_normal; - } else if (strcmp(rxPool_sc_CP_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_extended; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_CP_Len choice: normal,extended!\n", - RC.config_file_name, i, rxPool_sc_CP_Len); - - if (strcmp(rxPool_sc_Period,"sf40")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf40; - } else if (strcmp(rxPool_sc_Period,"sf60")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf60; - } else if (strcmp(rxPool_sc_Period,"sf70")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf70; - } else if (strcmp(rxPool_sc_Period,"sf80")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf80; - } else if (strcmp(rxPool_sc_Period,"sf120")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf120; - } else if (strcmp(rxPool_sc_Period,"sf140")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf140; - } else if (strcmp(rxPool_sc_Period,"sf160")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf160; - } else if (strcmp(rxPool_sc_Period,"sf240")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf240; - } else if (strcmp(rxPool_sc_Period,"sf280")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf280; - } else if (strcmp(rxPool_sc_Period,"sf320")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf320; - } else if (strcmp(rxPool_sc_Period,"spare6")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare6; - } else if (strcmp(rxPool_sc_Period,"spare5")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare5; - } else if (strcmp(rxPool_sc_Period,"spare4")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare4; - } else if (strcmp(rxPool_sc_Period,"spare3")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare3; - } else if (strcmp(rxPool_sc_Period,"spare2")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare2; - } else if (strcmp(rxPool_sc_Period,"spare")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_Period choice: sf40,sf60,sf70,sf80,sf120,sf140,sf160,sf240,sf280,sf320,spare6,spare5,spare4,spare3,spare2,spare!\n", - RC.config_file_name, i, rxPool_sc_Period); - - if (strcmp(rxPool_data_CP_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_normal; - } else if (strcmp(rxPool_data_CP_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_extended; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_data_CP_Len choice: normal,extended!\n", - RC.config_file_name, i, rxPool_data_CP_Len); - - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Num[j] = rxPool_ResourceConfig_prb_Num; - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Start[j] = rxPool_ResourceConfig_prb_Start; - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_End[j] = rxPool_ResourceConfig_prb_End; - - if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; - } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; - } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", - RC.config_file_name, i, rxPool_ResourceConfig_offsetIndicator_present); - - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_choice[j] = rxPool_ResourceConfig_offsetIndicator_choice; - - if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; - } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", - RC.config_file_name, i, rxPool_ResourceConfig_subframeBitmap_present); - - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_size[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_size; - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - - //SIB19 - for discRxPool - if (strcmp(discRxPool_cp_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_normal; - } else if (strcmp(discRxPool_cp_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_extended; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_cp_Len choice: normal,extended!\n", - RC.config_file_name, i, discRxPool_cp_Len); - - - if (strcmp(discRxPool_discPeriod,"rf32")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; - } else if (strcmp(discRxPool_discPeriod,"rf64")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; - } else if (strcmp(discRxPool_discPeriod,"rf128")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; - } else if (strcmp(discRxPool_discPeriod,"rf256")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; - } else if (strcmp(discRxPool_discPeriod,"rf512")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; - } else if (strcmp(discRxPool_discPeriod,"rf1024")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; - } else if (strcmp(discRxPool_discPeriod,"rf16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; - } else if (strcmp(discRxPool_discPeriod,"spare")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", - RC.config_file_name, i, discRxPool_discPeriod); - - - - RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRetx[j] = discRxPool_numRetx; - RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRepetition[j] = discRxPool_numRepetition; - - - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Num[j] = discRxPool_ResourceConfig_prb_Num; - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Start[j] = discRxPool_ResourceConfig_prb_Start; - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_End[j] = discRxPool_ResourceConfig_prb_End; - - if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; - } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; - } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", - RC.config_file_name, i, discRxPool_ResourceConfig_offsetIndicator_present); - - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_choice[j] = discRxPool_ResourceConfig_offsetIndicator_choice; - - if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; - } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", - RC.config_file_name, i, discRxPool_ResourceConfig_subframeBitmap_present); - - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - - //SIB19 - For discRxPoolPS - if (strcmp(discRxPoolPS_cp_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_normal; - } else if (strcmp(discRxPoolPS_cp_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_extended; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_cp_Len choice: normal,extended!\n", - RC.config_file_name, i, discRxPoolPS_cp_Len); - - - if (strcmp(discRxPoolPS_discPeriod,"rf32")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; - } else if (strcmp(discRxPoolPS_discPeriod,"rf64")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; - } else if (strcmp(discRxPoolPS_discPeriod,"rf128")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; - } else if (strcmp(discRxPoolPS_discPeriod,"rf256")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; - } else if (strcmp(discRxPoolPS_discPeriod,"rf512")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; - } else if (strcmp(discRxPoolPS_discPeriod,"rf1024")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; - } else if (strcmp(discRxPoolPS_discPeriod,"rf16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; - } else if (strcmp(discRxPoolPS_discPeriod,"spare")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", - RC.config_file_name, i, discRxPoolPS_discPeriod); - - - - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRetx[j] = discRxPoolPS_numRetx; - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRepetition[j] = discRxPoolPS_numRepetition; - - - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Num[j] = discRxPoolPS_ResourceConfig_prb_Num; - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Start[j] = discRxPoolPS_ResourceConfig_prb_Start; - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_End[j] = discRxPoolPS_ResourceConfig_prb_End; - - if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; - } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prSmall")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prLarge")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", - RC.config_file_name, i, discRxPoolPS_ResourceConfig_offsetIndicator_present); - - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_choice[j] = discRxPoolPS_ResourceConfig_offsetIndicator_choice; - - if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs4")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs8")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs12")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs30")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs40")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; - } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs42")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", - RC.config_file_name, i, discRxPoolPS_ResourceConfig_subframeBitmap_present); - - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[j] = discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - - - } - } - char srb1path[MAX_OPTNAME_SIZE*2 + 8]; - sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1); - int npar = config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path); - if (npar == sizeof(SRB1Params)/sizeof(paramdef_t)) { - switch (srb1_max_retx_threshold) { - case 1: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t1; - break; - - case 2: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t2; - break; - - case 3: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t3; - break; - - case 4: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t4; - break; - - case 6: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t6; - break; - - case 8: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; - break; - - case 16: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t16; - break; - - case 32: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t32; - break; - - default: - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_max_retx_threshold %u!\n", - RC.config_file_name, i, srb1_max_retx_threshold); - } - - - switch (srb1_poll_pdu) { - case 4: - rrc->srb1_poll_pdu = PollPDU_p4; - break; - - case 8: - rrc->srb1_poll_pdu = PollPDU_p8; - break; - - case 16: - rrc->srb1_poll_pdu = PollPDU_p16; - break; - - case 32: - rrc->srb1_poll_pdu = PollPDU_p32; - break; - - case 64: - rrc->srb1_poll_pdu = PollPDU_p64; - break; - - case 128: - rrc->srb1_poll_pdu = PollPDU_p128; - break; - - case 256: - rrc->srb1_poll_pdu = PollPDU_p256; - break; - - default: - if (srb1_poll_pdu >= 10000) - rrc->srb1_poll_pdu = PollPDU_pInfinity; - else - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_pdu %u!\n", - RC.config_file_name, i, srb1_poll_pdu); - } - - rrc->srb1_poll_byte = srb1_poll_byte; - - switch (srb1_poll_byte) { - case 25: - rrc->srb1_poll_byte = PollByte_kB25; - break; - - case 50: - rrc->srb1_poll_byte = PollByte_kB50; - break; - - case 75: - rrc->srb1_poll_byte = PollByte_kB75; - break; - - case 100: - rrc->srb1_poll_byte = PollByte_kB100; - break; - - case 125: - rrc->srb1_poll_byte = PollByte_kB125; - break; - - case 250: - rrc->srb1_poll_byte = PollByte_kB250; - break; - - case 375: - rrc->srb1_poll_byte = PollByte_kB375; - break; - - case 500: - rrc->srb1_poll_byte = PollByte_kB500; - break; - - case 750: - rrc->srb1_poll_byte = PollByte_kB750; - break; - - case 1000: - rrc->srb1_poll_byte = PollByte_kB1000; - break; - - case 1250: - rrc->srb1_poll_byte = PollByte_kB1250; - break; - - case 1500: - rrc->srb1_poll_byte = PollByte_kB1500; - break; - - case 2000: - rrc->srb1_poll_byte = PollByte_kB2000; - break; - - case 3000: - rrc->srb1_poll_byte = PollByte_kB3000; - break; - - default: - if (srb1_poll_byte >= 10000) - rrc->srb1_poll_byte = PollByte_kBinfinity; - else - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_byte %u!\n", - RC.config_file_name, i, srb1_poll_byte); - } - - if (srb1_timer_poll_retransmit <= 250) { - rrc->srb1_timer_poll_retransmit = (srb1_timer_poll_retransmit - 5)/5; - } else if (srb1_timer_poll_retransmit <= 500) { - rrc->srb1_timer_poll_retransmit = (srb1_timer_poll_retransmit - 300)/50 + 50; - } else { - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_poll_retransmit %u!\n", - RC.config_file_name, i, srb1_timer_poll_retransmit); - } - - if (srb1_timer_status_prohibit <= 250) { - rrc->srb1_timer_status_prohibit = srb1_timer_status_prohibit/5; - } else if ((srb1_timer_poll_retransmit >= 300) && (srb1_timer_poll_retransmit <= 500)) { - rrc->srb1_timer_status_prohibit = (srb1_timer_status_prohibit - 300)/50 + 51; - } else { - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_status_prohibit %u!\n", - RC.config_file_name, i, srb1_timer_status_prohibit); - } - - switch (srb1_timer_reordering) { - case 0: - rrc->srb1_timer_reordering = T_Reordering_ms0; - break; - - case 5: - rrc->srb1_timer_reordering = T_Reordering_ms5; - break; - - case 10: - rrc->srb1_timer_reordering = T_Reordering_ms10; - break; - - case 15: - rrc->srb1_timer_reordering = T_Reordering_ms15; - break; - - case 20: - rrc->srb1_timer_reordering = T_Reordering_ms20; - break; - - case 25: - rrc->srb1_timer_reordering = T_Reordering_ms25; - break; - - case 30: - rrc->srb1_timer_reordering = T_Reordering_ms30; - break; - - case 35: - rrc->srb1_timer_reordering = T_Reordering_ms35; - break; - - case 40: - rrc->srb1_timer_reordering = T_Reordering_ms40; - break; - - case 45: - rrc->srb1_timer_reordering = T_Reordering_ms45; - break; - - case 50: - rrc->srb1_timer_reordering = T_Reordering_ms50; - break; - - case 55: - rrc->srb1_timer_reordering = T_Reordering_ms55; - break; - - case 60: - rrc->srb1_timer_reordering = T_Reordering_ms60; - break; - - case 65: - rrc->srb1_timer_reordering = T_Reordering_ms65; - break; - - case 70: - rrc->srb1_timer_reordering = T_Reordering_ms70; - break; - - case 75: - rrc->srb1_timer_reordering = T_Reordering_ms75; - break; - - case 80: - rrc->srb1_timer_reordering = T_Reordering_ms80; - break; - - case 85: - rrc->srb1_timer_reordering = T_Reordering_ms85; - break; - - case 90: - rrc->srb1_timer_reordering = T_Reordering_ms90; - break; - - case 95: - rrc->srb1_timer_reordering = T_Reordering_ms95; - break; - - case 100: - rrc->srb1_timer_reordering = T_Reordering_ms100; - break; - - case 110: - rrc->srb1_timer_reordering = T_Reordering_ms110; - break; - - case 120: - rrc->srb1_timer_reordering = T_Reordering_ms120; - break; - - case 130: - rrc->srb1_timer_reordering = T_Reordering_ms130; - break; - - case 140: - rrc->srb1_timer_reordering = T_Reordering_ms140; - break; - - case 150: - rrc->srb1_timer_reordering = T_Reordering_ms150; - break; - - case 160: - rrc->srb1_timer_reordering = T_Reordering_ms160; - break; - - case 170: - rrc->srb1_timer_reordering = T_Reordering_ms170; - break; - - case 180: - rrc->srb1_timer_reordering = T_Reordering_ms180; - break; - - case 190: - rrc->srb1_timer_reordering = T_Reordering_ms190; - break; - - case 200: - rrc->srb1_timer_reordering = T_Reordering_ms200; - break; - - default: - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_reordering %u!\n", - RC.config_file_name, i, srb1_timer_reordering); - } - - } else { - rrc->srb1_timer_poll_retransmit = T_PollRetransmit_ms80; - rrc->srb1_timer_reordering = T_Reordering_ms35; - rrc->srb1_timer_status_prohibit = T_StatusProhibit_ms0; - rrc->srb1_poll_pdu = PollPDU_p4; - rrc->srb1_poll_byte = PollByte_kBinfinity; - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; - } - - /* - // Network Controller - subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); - - if (subsetting != NULL) { - if ( ( - config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, - (const char **)&flexran_agent_interface_name) - && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, - (const char **)&flexran_agent_ipv4_address) - && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, - &flexran_agent_port) - && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, - (const char **)&flexran_agent_cache) - ) - ) { - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name); - cidr = flexran_agent_ipv4_address; - address = strtok(cidr, "/"); - //enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address); - if (address) { - IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); - } - - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port; - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache); - } - } - */ - break; - } - + break; + } } } -return 0; + + return 0; } int RCconfig_gtpu(void ) { - int num_enbs = 0; - - - - char* enb_interface_name_for_S1U = NULL; - char* enb_ipv4_address_for_S1U = NULL; + char *enb_interface_name_for_S1U = NULL; + char *enb_ipv4_address_for_S1U = NULL; uint32_t enb_port_for_S1U = 0; char *address = NULL; char *cidr = NULL; char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; - - paramdef_t ENBSParams[] = ENBSPARAMS_DESC; - paramdef_t GTPUParams[] = GTPUPARAMS_DESC; LOG_I(GTPU,"Configuring GTPu\n"); - -/* get number of active eNodeBs */ - config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + /* 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); - - + "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); - config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); - - - - cidr = enb_ipv4_address_for_S1U; - address = strtok(cidr, "/"); - - if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); - - LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); - - } - - RC.gtpv1u_data_g->enb_port_for_S1u_S12_S4_up = enb_port_for_S1U; -return 0; + config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); + cidr = enb_ipv4_address_for_S1U; + address = strtok(cidr, "/"); + + if (address) { + MessageDef *message; + AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, GTPV1U_ENB_S1_REQ))!=NULL,""); + IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); + GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U; + itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + } else + LOG_E(GTPU,"invalid address for S1U\n"); + + return 0; } int RCconfig_S1(MessageDef *msg_p, uint32_t i) { - int j,k = 0; - - int enb_id; - int32_t my_int; - - - - const char* active_enb[MAX_ENB]; - - + const char *active_enb[MAX_ENB]; char *address = NULL; char *cidr = NULL; + // for no gcc warnings + (void)my_int; + memset((char *)active_enb, 0, MAX_ENB * sizeof(char *)); + 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); + 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); + } - // for no gcc warnings + // 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 S1Params[] = S1PARAMS_DESC; + paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0}; + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + paramdef_t NETParams[] = NETPARAMS_DESC; + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; + + if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { + 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; + } 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)); + } + + S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); + S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr + && !ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, + "It seems that you use an old configuration file. Please change the existing\n" + " tracking_area_code = \"1\";\n" + " mobile_country_code = \"208\";\n" + " mobile_network_code = \"93\";\n" + "to\n" + " tracking_area_code = 1; // no string!!\n" + " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + 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); + + S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt; + + for (int l = 0; l < PLMNParamList.numelt; ++l) { + S1AP_REGISTER_ENB_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] == 3 + || S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + S1AP_REGISTER_ENB_REQ(msg_p).mnc[l]); + } + + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; + config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix); + S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0; + + for (int l = 0; l < S1ParamList.numelt; l++) { + S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1; + strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr)); + strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr)); + + if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; + } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; + } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; + } + + if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr) + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].numelt; + else + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0; + + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, + "List of broadcast PLMN to be sent to MME can not be longer than actual " + "PLMN list (max %d, but is %d)\n", + S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]); + + for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) { + /* UINTARRAY gets mapped to int, see config_libconfig.c:223 */ + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr[el]; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0 + && S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, + "index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n", + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el], + S1AP_REGISTER_ENB_REQ(msg_p).num_plmn); + } + + /* if no broadcasst_plmn array is defined, fill default values */ + if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) { + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; + + for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el) + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el; + } + } + + // SCTP SETTING + S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + S1AP_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); + S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); + } - (void)my_int; + 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); + // S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); + cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr); + address = strtok(cidr, "/"); + S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0; + S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4 = 1; + strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, address); + break; + } + } + } + } + } - memset((char*)active_enb, 0 , MAX_ENB * sizeof(char*)); + return 0; +} +int RCconfig_X2(MessageDef *msg_p, uint32_t i) { + int I, J, j, k, l; + int enb_id; + char *address = NULL; + char *cidr = NULL; 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); + /* define CC params */ + int32_t Nid_cell = 0; + char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed, + *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled, + *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource, + *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha, + *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2, + *pucch_deltaF_Format2a, *pucch_deltaF_Format2b, + *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB; + long long int downlink_frequency; + int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset, + Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index, + prach_zero_correlation, prach_freq_offset, pucch_delta_shift, + pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower, + pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment, + pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal, + pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles, + rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA, + rach_powerRampingStep, rach_preambleInitialReceivedTargetPower, + rach_preambleTransMax, rach_raResponseWindowSize, + rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx, + pcch_defaultPagingCycle, bcch_modificationPeriodCoeff, + ue_TimersAndConstants_t300, ue_TimersAndConstants_t301, + ue_TimersAndConstants_t310, ue_TimersAndConstants_t311, + ue_TimersAndConstants_n310, ue_TimersAndConstants_n311, + ue_TransmissionMode, ue_multiple_max; + const char *rxPool_sc_CP_Len; + const char *rxPool_sc_Period; + const char *rxPool_data_CP_Len; + libconfig_int rxPool_ResourceConfig_prb_Num; + libconfig_int rxPool_ResourceConfig_prb_Start; + libconfig_int rxPool_ResourceConfig_prb_End; + const char *rxPool_ResourceConfig_offsetIndicator_present; + libconfig_int rxPool_ResourceConfig_offsetIndicator_choice; + const char *rxPool_ResourceConfig_subframeBitmap_present; + char *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //SIB19 + //for discRxPool + const char *discRxPool_cp_Len; + const char *discRxPool_discPeriod; + libconfig_int discRxPool_numRetx; + libconfig_int discRxPool_numRepetition; + libconfig_int discRxPool_ResourceConfig_prb_Num; + libconfig_int discRxPool_ResourceConfig_prb_Start; + libconfig_int discRxPool_ResourceConfig_prb_End; + const char *discRxPool_ResourceConfig_offsetIndicator_present; + libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice; + const char *discRxPool_ResourceConfig_subframeBitmap_present; + char *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + //for discRxPoolPS + const char *discRxPoolPS_cp_Len; + const char *discRxPoolPS_discPeriod; + libconfig_int discRxPoolPS_numRetx; + libconfig_int discRxPoolPS_numRepetition; + libconfig_int discRxPoolPS_ResourceConfig_prb_Num; + libconfig_int discRxPoolPS_ResourceConfig_prb_Start; + libconfig_int discRxPoolPS_ResourceConfig_prb_End; + const char *discRxPoolPS_ResourceConfig_offsetIndicator_present; + libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice; + const char *discRxPoolPS_ResourceConfig_subframeBitmap_present; + char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; + paramdef_t CCsParams[] = CCPARAMS_DESC; + paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; -/* get global parameters, defined outside any section in the config file */ - - config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { - asn_debug = 0; - asn1_xer_print = 0; - } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) { - asn_debug = 1; - asn1_xer_print = 1; - } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) { - asn_debug = 1; - asn1_xer_print = 2; - } else { - asn_debug = 0; - asn1_xer_print = 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]); + } -#endif + /*#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) + if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { + asn_debug = 0; + asn1_xer_print = 0; + } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) { + asn_debug = 1; + asn1_xer_print = 1; + } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) { + asn_debug = 1; + asn1_xer_print = 2; + } else { + asn_debug = 0; + asn1_xer_print = 0; + } + #endif */ + 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); - 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) { + if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) { // Output a list of all eNBs. - config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); - - - - - + 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 (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { + // Calculate a default eNB ID # if defined(ENABLE_USE_MME) - uint32_t hash; - - hash = s1ap_generate_eNB_id (); - enb_id = k + (hash & 0xFFFF8); + uint32_t hash; + hash = s1ap_generate_eNB_id (); + enb_id = k + (hash & 0xFFFF8); # else - enb_id = k; + enb_id = k; # endif - } else { + } 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 S1Params[] = S1PARAMS_DESC; - paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0}; - - paramdef_t SCTPParams[] = SCTPPARAMS_DESC; - paramdef_t NETParams[] = NETPARAMS_DESC; - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - - S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; - - if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { - 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; - } 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)); - } - - S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).tac = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).mcc = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).mnc = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).default_drx = 0; - AssertFatal((S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 2) || - (S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 3), - "BAD MNC DIGIT LENGTH %d", - S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length); - - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); - config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix); - - S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0; - - for (int l = 0; l < S1ParamList.numelt; l++) { - - S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1; - - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr)); - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr)); - - if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_ACTIVE_IDX].strptr), "yes") == 0) { -#if defined(ENABLE_USE_MME) - EPC_MODE_ENABLED = 1; -#endif - } - if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; - } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; - } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; - } - } - - - // SCTP SETTING - S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; - S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; + + // 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 X2Params[] = X2PARAMS_DESC; + paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + paramdef_t NETParams[] = NETPARAMS_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]",ENB_CONFIG_STRING_ENB_LIST,k); + /* Some default/random parameters */ + X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; + + if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { + 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 { + 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)); + } + + X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); + X2AP_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); + + 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][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_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) { + //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); + X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = eutra_band; + X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) downlink_frequency; + X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) uplink_frequency_offset; + X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= Nid_cell; + + 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; + + 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)) { + 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); + } + + 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; + } 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); + } + + X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(eutra_band, downlink_frequency, N_RB_DL); + X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(eutra_band, downlink_frequency + uplink_frequency_offset, N_RB_DL); + } + } + + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_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; + } 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].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; + } + } + + // 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 defined(ENABLE_USE_MME) - 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); - S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); - S1AP_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_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); #endif - 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); - - // S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); - cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr); - address = strtok(cidr, "/"); - - S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0; - S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4 = 1; - - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, address); - - /* - in_addr_t ipv4_address; + // 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); + + 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); + } + } + } + } + } - if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); - } - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, inet_ntoa(ipv4_address)); - // S1AP_REGISTER_ENB_REQ (msg_p).enb_port_for_S1U = enb_port_for_S1U; + return 0; +} +int RCconfig_parallel(void) { + char *parallel_conf = NULL; + char *worker_conf = NULL; + extern char *parallel_config; + extern char *worker_config; + paramdef_t ThreadParams[] = THREAD_CONF_DESC; + paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0}; + config_getlist( &THREADParamList,NULL,0,NULL); + + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); + } else { + parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); + } - S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME); - cidr = enb_ipv4_address_for_S1_MME; - address = strtok(cidr, "/"); - - if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, S1AP_REGISTER_ENB_REQ(msg_p).enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" ); - } -*/ - + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); + } else { + worker_conf = strdup("WORKER_ENABLE"); + } + if(parallel_config == NULL) set_parallel_conf(parallel_conf); + if(worker_config == NULL) set_worker_conf(worker_conf); - break; - } - } - } - } - } -return 0; + return 0; } void RCConfig(void) { - paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; paramlist_def_t L1ParamList = {CONFIG_STRING_L1_LIST,NULL,0}; paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; paramdef_t ENBSParams[] = ENBSPARAMS_DESC; paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0}; - - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - - - -/* get global parameters, defined outside any section in the config file */ - + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + /* get global parameters, defined outside any section in the config file */ printf("Getting ENBSParams\n"); - - config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); +# if defined(ENABLE_USE_MME) + EPC_MODE_ENABLED = ((*ENBSParams[ENB_NOS1_IDX].uptr) == 0); +#endif RC.nb_inst = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; - + if (RC.nb_inst > 0) { RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int)); - for (int i=0;i<RC.nb_inst;i++) { + + for (int i=0; i<RC.nb_inst; i++) { sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,i); config_getlist( &CCsParamList,NULL,0, aprefix); - RC.nb_CC[i] = CCsParamList.numelt; + RC.nb_CC[i] = CCsParamList.numelt; } } - // Get num MACRLC instances - - - config_getlist( &MACRLCParamList,NULL,0, NULL); - RC.nb_macrlc_inst = MACRLCParamList.numelt; - // Get num L1 instances - config_getlist( &L1ParamList,NULL,0, NULL); - RC.nb_L1_inst = L1ParamList.numelt; - - // Get num RU instances - config_getlist( &RUParamList,NULL,0, NULL); - RC.nb_RU = RUParamList.numelt; - - + // Get num MACRLC instances + config_getlist( &MACRLCParamList,NULL,0, NULL); + RC.nb_macrlc_inst = MACRLCParamList.numelt; + // Get num L1 instances + config_getlist( &L1ParamList,NULL,0, NULL); + RC.nb_L1_inst = L1ParamList.numelt; + // Get num RU instances + config_getlist( &RUParamList,NULL,0, NULL); + RC.nb_RU = RUParamList.numelt; + RCconfig_parallel(); } diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 96156a4bc454232699f4db39ada3845e0d3aaa59..ed1b4aeaa2924dd08f49be84d5f20337b307a044 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -46,8 +46,8 @@ #else #include "RRC/LTE/MESSAGES/SystemInformationBlockType2.h" #endif -#include "intertask_interface_types.h" #include "RRC/LTE/rrc_defs.h" +#include <intertask_interface.h> #define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ struct in_addr inp;\ @@ -106,6 +106,7 @@ void ru_config_display(void); int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc); int RCconfig_S1(MessageDef *msg_p, uint32_t i); +int RCconfig_X2(MessageDef *msg_p, uint32_t i); #endif /* ENB_CONFIG_H_ */ /** @} */ diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 23b4c2a8376e90349ce8a7f03fbc36dd85dcfb0a..524daac43d12563f6cad5b12d1eee209012fab10 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -55,11 +55,6 @@ -#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 #else @@ -102,6 +97,8 @@ typedef enum { #define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" #define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" #define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" +#define CONFIG_STRING_RU_SDR_ADDRS "sdr_addrs" +#define CONFIG_STRING_RU_SDR_CLK_SRC "clock_src" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -121,6 +118,8 @@ typedef enum { #define RU_ATT_TX_IDX 15 #define RU_ATT_RX_IDX 16 #define RU_NBIOTRRC_LIST_IDX 17 +#define RU_SDR_ADDRS 18 +#define RU_SDR_CLK_SRC 19 @@ -147,6 +146,8 @@ typedef enum { {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ +{CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ +{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -160,25 +161,19 @@ typedef enum { /* global parameters, not under a specific section */ #define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity" #define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs" +#define ENB_CONFIG_STRING_NOS1 "noS1" /*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* global configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define ENBSPARAMS_DESC { \ -{ENB_CONFIG_STRING_ASN1_VERBOSITY, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_ACTIVE_ENBS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRINGLIST, 0} \ +{ENB_CONFIG_STRING_ASN1_VERBOSITY, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_ACTIVE_ENBS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRINGLIST, 0}, \ +{ENB_CONFIG_STRING_NOS1, NULL, PARAMFLAG_BOOL, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ } #define ENB_ASN1_VERBOSITY_IDX 0 #define ENB_ACTIVE_ENBS_IDX 1 - - -/* -{ENB_CONFIG_STRING_COMPONENT_CARRIERS,"", "", 0, uptr:NULL,defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,TYPE_STRING,0}, \ -{ENB_CONFIG_STRING_CC_NODE_FUNCTION,"", "", 0, uptr:NULL,defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,TYPE_STRING,0}, \ -{ENB_CONFIG_STRING_CC_NODE_TIMING,"", "", 0, uptr:NULL,defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,TYPE_STRING,0}, \ -{ENB_CONFIG_STRING_CC_NODE_SYNCH_REF,"", "", 0, uptr:NULL,defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,TYPE_STRING,0}, \ -*/ - +#define ENB_NOS1_IDX 2 /*------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -190,8 +185,8 @@ typedef enum { #define ENB_CONFIG_STRING_CELL_TYPE "cell_type" #define ENB_CONFIG_STRING_ENB_NAME "eNB_name" #define ENB_CONFIG_STRING_TRACKING_AREA_CODE "tracking_area_code" -#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mobile_country_code" -#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mobile_network_code" +#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD "mobile_country_code" +#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD "mobile_network_code" #define ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE "tr_s_preference" #define ENB_CONFIG_STRING_LOCAL_S_IF_NAME "local_s_if_name" #define ENB_CONFIG_STRING_LOCAL_S_ADDRESS "local_s_address" @@ -209,9 +204,9 @@ typedef enum { {ENB_CONFIG_STRING_ENB_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_CELL_TYPE, NULL, 0, strptr:NULL, defstrval:"CELL_MACRO_ENB", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_NAME, NULL, 0, strptr:NULL, defstrval:"OAIeNodeB", TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_LOCAL_S_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ @@ -225,8 +220,8 @@ typedef enum { #define ENB_CELL_TYPE_IDX 1 #define ENB_ENB_NAME_IDX 2 #define ENB_TRACKING_AREA_CODE_IDX 3 -#define ENB_MOBILE_COUNTRY_CODE_IDX 4 -#define ENB_MOBILE_NETWORK_CODE_IDX 5 +#define ENB_MOBILE_COUNTRY_CODE_IDX_OLD 4 +#define ENB_MOBILE_NETWORK_CODE_IDX_OLD 5 #define ENB_TRANSPORT_S_PREFERENCE_IDX 6 #define ENB_LOCAL_S_IF_NAME_IDX 7 #define ENB_LOCAL_S_ADDRESS_IDX 8 @@ -235,9 +230,56 @@ typedef enum { #define ENB_REMOTE_S_PORTC_IDX 11 #define ENB_LOCAL_S_PORTD_IDX 12 #define ENB_REMOTE_S_PORTD_IDX 13 + +#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} +#define ENBPARAMS_CHECK { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s2 = { config_check_intrange, TRACKING_AREA_CODE_OKRANGE } },\ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ +} + /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* PLMN ID configuration */ + +#define ENB_CONFIG_STRING_PLMN_LIST "plmn_list" + +#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mcc" +#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mnc" +#define ENB_CONFIG_STRING_MNC_DIGIT_LENGTH "mnc_length" + +#define ENB_MOBILE_COUNTRY_CODE_IDX 0 +#define ENB_MOBILE_NETWORK_CODE_IDX 1 +#define ENB_MNC_DIGIT_LENGTH 2 + +#define PLMNPARAMS_DESC { \ +/* optname helpstr paramflags XXXptr def val type numelt */ \ + {ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, "mobile country code", 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, "mobile network code", 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_MNC_DIGIT_LENGTH, "length of the MNC (2 or 3)", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + +#define MCC_MNC_OKRANGES {0,999} +#define MNC_DIGIT_LENGTH_OKVALUES {2,3} + +#define PLMNPARAMS_CHECK { \ + { .s2 = { config_check_intrange, MCC_MNC_OKRANGES } }, \ + { .s2 = { config_check_intrange, MCC_MNC_OKRANGES } }, \ + { .s1 = { config_check_intval, MNC_DIGIT_LENGTH_OKVALUES, 2 } }, \ +} + /* component carries configuration parameters name */ @@ -686,6 +728,7 @@ typedef enum { #define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6" #define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active" #define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference" +#define ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX "broadcast_plmn_index" /*-------------------------------------------------------------------------------------------------------------------------------------*/ @@ -697,13 +740,40 @@ typedef enum { {ENB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL,TYPE_UINTARRAY, 6} \ } #define ENB_MME_IPV4_ADDRESS_IDX 0 #define ENB_MME_IPV6_ADDRESS_IDX 1 #define ENB_MME_IP_ADDRESS_ACTIVE_IDX 2 #define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3 +#define ENB_MME_BROADCAST_PLMN_INDEX 4 /*---------------------------------------------------------------------------------------------------------------------------------------*/ + +/* X2 configuration parameters section name */ +#define ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS "target_enb_x2_ip_address" + +/* X2 configuration parameters names */ + + +#define ENB_CONFIG_STRING_TARGET_ENB_X2_IPV4_ADDRESS "ipv4" +#define ENB_CONFIG_STRING_TARGET_ENB_X2_IPV6_ADDRESS "ipv6" +#define ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS_PREFERENCE "preference" + + +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +/* X2 configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------*/ +#define X2PARAMS_DESC { \ +{ENB_CONFIG_STRING_TARGET_ENB_X2_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TARGET_ENB_X2_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +} + +#define ENB_X2_IPV4_ADDRESS_IDX 0 +#define ENB_X2_IPV6_ADDRESS_IDX 1 +#define ENB_X2_IP_ADDRESS_PREFERENCE_IDX 2 /*---------------------------------------------------------------------------------------------------------------------------------------*/ /* SCTP configuration parameters section name */ #define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP" @@ -735,6 +805,8 @@ typedef enum { #define ENB_INTERFACE_NAME_FOR_S1U_IDX 2 #define ENB_IPV4_ADDR_FOR_S1U_IDX 3 #define ENB_PORT_FOR_S1U_IDX 4 +#define ENB_IPV4_ADDR_FOR_X2C_IDX 5 +#define ENB_PORT_FOR_X2C_IDX 6 /* S1 interface configuration parameters names */ #define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME" @@ -743,8 +815,12 @@ typedef enum { #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" +/* X2 interface configuration parameters names */ +#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" + /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* S1 interface configuration parameters */ +/* S1/X2 interface configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ #define NETPARAMS_DESC { \ @@ -752,7 +828,9 @@ typedef enum { {ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0} \ +{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}, \ } @@ -851,3 +929,28 @@ typedef enum { #define MACRLC_SCHED_MODE_IDX 17 #define MACRLC_PHY_TEST_IDX 18 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* thread configuration parameters section name */ +#define THREAD_CONFIG_STRING_THREAD_STRUCT "THREAD_STRUCT" + +/* thread configuration parameters names */ +#define THREAD_CONFIG_STRING_PARALLEL "parallel_config" +#define THREAD_CONFIG_STRING_WORKER "worker_config" + + +#define THREAD_PARALLEL_IDX 0 +#define THREAD_WORKER_IDX 1 + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* thread configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define THREAD_CONF_DESC { \ +{THREAD_CONFIG_STRING_PARALLEL, CONFIG_HLP_PARALLEL, 0, strptr:NULL, defstrval:"PARALLEL_RU_L1_TRX_SPLIT", TYPE_STRING, 0}, \ +{THREAD_CONFIG_STRING_WORKER, CONFIG_HLP_WORKER, 0, strptr:NULL, defstrval:"WORKER_ENABLE", TYPE_STRING, 0} \ +} + + +#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n" +#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n" +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index aed8f9eb60dc386700e74fbd1eeb7e7fddd5f96b..4ce727ff1c7c89e305ccb7ff2d1641010122e64a 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -39,7 +39,7 @@ #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" #include "flexran_agent_pdcp.h" -#include "log.h" +#include "common/utils/LOG/log.h" #include "assertions.h" /* Initiation of the eNodeB agent */ diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 3bbea167d37dfacf1e8e2ca6cc0c576a2918f18d..1a92c9e2621e37ae028e1ceba277d7357527db7f 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -36,7 +36,8 @@ #include "flexran_agent_net_comm.h" #include "flexran_agent_ran_api.h" //#include "PHY/extern.h" -#include "log.h" +#include "common/utils/LOG/log.h" +#include "flexran_agent_mac_internal.h" //#include "SCHED/defs.h" #include "RRC/LTE/rrc_extern.h" @@ -287,6 +288,23 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { free(reply->cell_config[i]->si_config->si_message); free(reply->cell_config[i]->si_config); } + if (reply->cell_config[i]->slice_config != NULL) { + for (j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) { + if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0) + free(reply->cell_config[i]->slice_config->dl[j]->sorting); + free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name); + free(reply->cell_config[i]->slice_config->dl[j]); + } + free(reply->cell_config[i]->slice_config->dl); + for (j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) { + if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0) + free(reply->cell_config[i]->slice_config->ul[j]->sorting); + free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name); + free(reply->cell_config[i]->slice_config->ul[j]); + } + free(reply->cell_config[i]->slice_config->ul); + free(reply->cell_config[i]->slice_config); + } free(reply->cell_config[i]); } free(reply->cell_config); @@ -396,8 +414,14 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ FILE *f; f = fopen(target, "wb"); - fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); - fclose(f); + if (f) { + fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); + fclose(f); + } + else { + LOG_W(FLEXRAN_AGENT, "[%d] can not write control delegation data to %s\n", + mod_id, target); + } // long time_elapsed_nanos = timer_end(vartime); *msg = NULL; @@ -435,6 +459,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl xid = (lc_config_request_msg->header)->xid; int i, j; + int UE_id; Protocol__FlexLcConfigReply *lc_config_reply_msg; lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply)); @@ -460,13 +485,15 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig)); protocol__flex_lc_ue_config__init(lc_ue_config[i]); + UE_id = flexran_get_ue_id(mod_id, i); + lc_ue_config[i]->has_rnti = 1; - lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i); + lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); //TODO: Set the number of LC configurations that will be reported for this UE //Set this according to the current state of the UE. This is only a temporary fix int status = 0; - status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, i)); + status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, UE_id)); /* TODO needs to be revised and appropriate API to be implemented */ if (status < RRC_CONNECTED) { lc_ue_config[i]->n_lc_config = 0; @@ -489,14 +516,14 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config[j]->has_lcid = 1; lc_config[j]->lcid = j+1; - int lcg = flexran_get_lcg(mod_id, i, j+1); + int lcg = flexran_get_lcg(mod_id, UE_id, j+1); if (lcg >= 0 && lcg <= 3) { lc_config[j]->has_lcg = 1; - lc_config[j]->lcg = flexran_get_lcg(mod_id, i,j+1); + lc_config[j]->lcg = flexran_get_lcg(mod_id, UE_id, j+1); } lc_config[j]->has_direction = 1; - lc_config[j]->direction = flexran_get_direction(i,j+1); + lc_config[j]->direction = flexran_get_direction(UE_id, j+1); //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported lc_config[j]->has_qos_bearer_type = 1; lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR; @@ -563,6 +590,7 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl xid = (ue_config_request_msg->header)->xid; int i; + int UE_id; Protocol__FlexUeConfigReply *ue_config_reply_msg; ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply)); @@ -587,26 +615,31 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig)); protocol__flex_ue_config__init(ue_config[i]); - ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i); + UE_id = flexran_get_ue_id(mod_id, i); + ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); ue_config[i]->has_rnti = 1; - ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i); + ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, UE_id); ue_config[i]->has_imsi = 1; + ue_config[i]->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, UE_id); + ue_config[i]->has_dl_slice_id = 1; + ue_config[i]->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, UE_id); + ue_config[i]->has_ul_slice_id = 1; //TODO: Set the DRX configuration (optional) //Not supported for now, so we do not set it - if (flexran_get_time_alignment_timer(mod_id,i) != -1) { - ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - ue_config[i]->has_time_alignment_timer = 1; + if (flexran_get_time_alignment_timer(mod_id, UE_id) != -1) { + ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id, UE_id); + ue_config[i]->has_time_alignment_timer = 1; } - if (flexran_get_meas_gap_config(mod_id,i) != -1) { - ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - ue_config[i]->has_meas_gap_config_pattern = 1; + if (flexran_get_meas_gap_config(mod_id, UE_id) != -1) { + ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id, UE_id); + ue_config[i]->has_meas_gap_config_pattern = 1; } if (ue_config[i]->has_meas_gap_config_pattern == 1 && - ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); + ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id, UE_id); ue_config[i]->has_meas_gap_config_sf_offset = 1; } //TODO: Set the SPS configuration (Optional) @@ -618,77 +651,77 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl //TODO: Set the CQI configuration (Optional) //We do not set it for now - if (flexran_get_ue_transmission_mode(mod_id,i) != -1) { - ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); + if (flexran_get_ue_transmission_mode(mod_id, UE_id) != -1) { + ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id, UE_id); ue_config[i]->has_transmission_mode = 1; } - ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); + ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, UE_id); ue_config[i]->has_ue_aggregated_max_bitrate_ul = 1; - ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); + ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id, UE_id); ue_config[i]->has_ue_aggregated_max_bitrate_dl = 1; Protocol__FlexUeCapabilities *capabilities; capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); protocol__flex_ue_capabilities__init(capabilities); capabilities->has_half_duplex = 1; - capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); + capabilities->half_duplex = flexran_get_half_duplex(mod_id, UE_id); capabilities->has_intra_sf_hopping = 1; - capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); + capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, UE_id); capabilities->has_type2_sb_1 = 1; - capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); + capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, UE_id); capabilities->has_ue_category = 1; - capabilities->ue_category = flexran_get_ue_category(mod_id, i); + capabilities->ue_category = flexran_get_ue_category(mod_id, UE_id); capabilities->has_res_alloc_type1 = 1; - capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); + capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, UE_id); //Set the capabilites to the message ue_config[i]->capabilities = capabilities; - if (flexran_get_ue_transmission_antenna(mod_id,i) != -1) { + if (flexran_get_ue_transmission_antenna(mod_id, UE_id) != -1) { ue_config[i]->has_ue_transmission_antenna = 1; - ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); + ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id, UE_id); } - if (flexran_get_tti_bundling(mod_id,i) != -1) { + if (flexran_get_tti_bundling(mod_id, UE_id) != -1) { ue_config[i]->has_tti_bundling = 1; - ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id,i); + ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id, UE_id); } - if (flexran_get_maxHARQ_TX(mod_id,i) != -1) { + if (flexran_get_maxHARQ_TX(mod_id, UE_id) != -1) { ue_config[i]->has_max_harq_tx = 1; - ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); + ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id, UE_id); } - if (flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - ue_config[i]->has_beta_offset_ack_index = 1; - ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); + if (flexran_get_beta_offset_ack_index(mod_id, UE_id) != -1) { + ue_config[i]->has_beta_offset_ack_index = 1; + ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id, UE_id); } - if (flexran_get_beta_offset_ri_index(mod_id,i) != -1) { + if (flexran_get_beta_offset_ri_index(mod_id, UE_id) != -1) { ue_config[i]->has_beta_offset_ri_index = 1; - ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); + ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id, UE_id); } - if (flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { + if (flexran_get_beta_offset_cqi_index(mod_id, UE_id) != -1) { ue_config[i]->has_beta_offset_cqi_index = 1; - ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); + ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id, UE_id); } /* assume primary carrier */ - if (flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0) != -1) { + if (flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0) != -1) { ue_config[i]->has_ack_nack_simultaneous_trans = 1; - ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0); + ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0); } - if (flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { + if (flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id) != -1) { ue_config[i]->has_simultaneous_ack_nack_cqi = 1; - ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); + ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id); } - if (flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { + if (flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id) != -1) { ue_config[i]->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); + int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id); if (mode > 4) { ue_config[i]->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; } else { @@ -696,26 +729,26 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl } } - if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { + if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id) != -1) { ue_config[i]->has_tdd_ack_nack_feedback = 1; - ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); + ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id); } - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { + if(flexran_get_ack_nack_repetition_factor(mod_id, UE_id) != -1) { ue_config[i]->has_ack_nack_repetition_factor = 1; - ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); + ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id, UE_id); } - if (flexran_get_extended_bsr_size(mod_id, i) != -1) { + if (flexran_get_extended_bsr_size(mod_id, UE_id) != -1) { ue_config[i]->has_extended_bsr_size = 1; - ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); + ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, UE_id); } //TODO: Set carrier aggregation support (boolean) ue_config[i]->has_ca_support = 0; ue_config[i]->ca_support = 0; ue_config[i]->has_pcell_carrier_index = 1; - ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, i); + ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, UE_id); if(ue_config[i]->has_ca_support){ //TODO: Set cross carrier scheduling support (boolean) ue_config[i]->has_cross_carrier_sched_support = 0; @@ -830,8 +863,8 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig)); protocol__flex_cell_config__init(cell_conf[i]); - cell_conf[i]->phy_cell_id = 1; - cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i); + cell_conf[i]->phy_cell_id = flexran_get_cell_id(mod_id,i); + cell_conf[i]->has_phy_cell_id = 1; cell_conf[i]->cell_id = i; cell_conf[i]->has_cell_id = 1; @@ -1030,6 +1063,10 @@ 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; + + /* get a pointer to the config which is maintained in the agent throughout + * its lifetime */ + cell_conf[i]->slice_config = flexran_agent_get_slice_config(mod_id); } enb_config_reply_msg->cell_config=cell_conf; } @@ -1090,5 +1127,39 @@ int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){ return 0; } +int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) +{ + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg; + + if (enb_config->n_cell_config == 0) { + LOG_W(FLEXRAN_AGENT, + "received enb_config_reply message does not contain a cell_config\n"); + *msg = NULL; + return 0; + } + + if (enb_config->n_cell_config > 1) + LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n"); + if (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]); + } + + *msg = NULL; + return 0; +} + +int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) +{ + int i; + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg; + for (i = 0; i < ue_config_reply->n_ue_config; i++) + prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]); + *msg = NULL; + return 0; +} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 057c5b9489a7332a9cdb8923f3abeb58a44f7d46..c83d3c24819ad30e0dad650a17d8c7c3d7a1c620 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -46,7 +46,6 @@ # include "tree.h" # include "intertask_interface.h" -# include "timer.h" #define FLEXRAN_VERSION 0 @@ -167,4 +166,19 @@ void flexran_agent_send_update_stats(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 + * since we do not reply to this message (yet). Instead, the controller has to + * issue another eNB config request message. */ +int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg); + +/* Handle a received UE config reply message as an "order" to reconfigure the + * association of a UE to a slice. It does not come as a reconfiguration + * message as this is a "structured" ProtoBuf message (as opposed to + * "unstructured" YAML). There is no destructor since we do not reply to this + * message (yet). Instead, the controller has to issue another eNB config + * request message. */ +int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg); + #endif diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 8874a0f64852f06ac619ba4eed39e7d02fe292ec..9f1a1d3710a8a106400f2bd0bd4499110110c5bd 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -31,57 +31,7 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" - -/* needed to soft-restart the lte-softmodem */ -#include "targets/RT/USER/lte-softmodem.h" - -void handle_reconfiguration(mid_t mod_id) -{ - struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC, &start); - flexran_agent_info_t *flexran = RC.flexran[mod_id]; - - 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, " * eNB %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_F(ENB_APP, "can not restart, killing lte-softmodem\n"); - itti_terminate_tasks(TASK_PHY_ENB); - 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); -} +#include "enb_app.h" int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { @@ -589,3 +539,32 @@ int apply_parameter_modification(void *parameter, yaml_parser_t *parser) { return -1; } + +void initiate_soft_restart(module_id_t mod_id, Protocol__FlexCellConfig *c) +{ + uint8_t cc_id = c->has_cell_id ? c->cell_id : 0; + if (c->has_eutra_band) { + flexran_agent_set_operating_eutra_band(mod_id, cc_id, c->eutra_band); + LOG_I(ENB_APP, "Setting eutra_band to %d\n", c->eutra_band); + } + if (c->has_dl_freq && c->has_ul_freq) { + flexran_agent_set_operating_dl_freq(mod_id, cc_id, c->dl_freq); + LOG_I(ENB_APP, "Setting dl_freq to %d\n", c->dl_freq); + int32_t ul_freq_offset = c->ul_freq - c->dl_freq; + flexran_agent_set_operating_ul_freq(mod_id, cc_id, ul_freq_offset); + LOG_I(ENB_APP, "Setting ul_freq to %d\n", c->ul_freq); + } + if (c->has_dl_bandwidth) { + flexran_agent_set_operating_bandwidth(mod_id, cc_id, c->dl_bandwidth); + LOG_I(ENB_APP, "Setting bandwidth to %d\n", c->dl_bandwidth); + if (c->has_ul_bandwidth && c->ul_bandwidth != c->dl_bandwidth) + LOG_W(ENB_APP, "UL/DL bandwidth mismatch, applied DL bandwidth\n"); + } else if (c->has_ul_bandwidth) { + flexran_agent_set_operating_bandwidth(mod_id, cc_id, c->ul_bandwidth); + LOG_I(ENB_APP, "Setting bandwidth to %d\n", c->ul_bandwidth); + } + + MessageDef *msg; + msg = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SOFT_RESTART_MESSAGE); + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} diff --git a/openair2/ENB_APP/flexran_agent_common_internal.h b/openair2/ENB_APP/flexran_agent_common_internal.h index bf908ac13232b8743c72411481a8be649d884519..544321e228017900d5334501be1da0d327e0a464 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.h +++ b/openair2/ENB_APP/flexran_agent_common_internal.h @@ -32,6 +32,7 @@ #include <yaml.h> #include "flexran_agent_defs.h" +#include "flexran.pb-c.h" int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length); @@ -57,4 +58,7 @@ int skip_subsystem_parameters_config(yaml_parser_t *parser); //that is not yet implmeneted in order to skip its configuration, without affecting the rest int skip_parameter_modification(yaml_parser_t *parser); +// applies reconfiguration parameters and notifies ENB APP +void initiate_soft_restart(mid_t mod_id, Protocol__FlexCellConfig *c); + #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index d4c82e4dff127b12828c1a72ed6779705cf73714..74ea5bfa1fa80fa69d59a0af958bb7985f56aaa3 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -33,7 +33,7 @@ #include "flexran_agent_pdcp.h" #include "flexran_agent_timer.h" #include "flexran_agent_ran_api.h" -#include "log.h" +#include "common/utils/LOG/log.h" #include "assertions.h" @@ -46,9 +46,9 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {0, 0, 0}, /*PROTOCOK__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG*/ {flexran_agent_enb_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG*/ - {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG*/ + {flexran_agent_handle_enb_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG*/ {flexran_agent_ue_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REQUEST_MSG*/ - {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG*/ + {flexran_agent_handle_ue_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG*/ {flexran_agent_lc_config_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG*/ {flexran_agent_mac_handle_dl_mac_config, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_DL_MAC_CONFIG_MSG*/ @@ -210,6 +210,7 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 int enb_id = mod_id; + int UE_id; //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; //UE_list_t *eNB_UE_list= &eNB->UE_list; @@ -249,8 +250,9 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr goto error; } for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; - report_config.ue_report_type[i].ue_report_flags = ue_flags; + UE_id = flexran_get_ue_id(mod_id, i); + report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, UE_id); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; + 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; @@ -359,7 +361,8 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr goto error; } for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i]; + UE_id = flexran_get_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; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index e39d676061f5e38a47078ee38001c785790811be..973d322a5f30177871bad5ac6984411c447d49dd 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -26,6 +26,7 @@ * \version 0.1 */ +#include <dlfcn.h> #include "flexran_agent_ran_api.h" static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) @@ -112,6 +113,21 @@ int flexran_get_num_ues(mid_t mod_id) return RC.mac[mod_id]->UE_list.num_UEs; } +int flexran_get_ue_id(mid_t mod_id, int i) +{ + int n; + if (!mac_is_present(mod_id)) return 0; + /* get the (i+1)'th active UE */ + for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[mod_id]->UE_list.active[n] == TRUE) { + if (i == 0) + return n; + --i; + } + } + return 0; +} + rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) { return UE_RNTI(mod_id, ue_id); @@ -1193,106 +1209,158 @@ void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_fra /*********** PDCP *************/ /*PDCP super frame counter flexRAN*/ -uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ + +/* TODO the following is a hack. all the functions below should instead already + * receive the PDCP's uid and operate on it and the caller has the obligation + * to get the ID for this layer. + */ +static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id) +{ + rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); + if (rnti == NOT_A_RNTI) return 0; + + for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) { + if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti) + return pdcp_uid; + } + return 0; +} + +uint32_t flexran_get_pdcp_sfn(mid_t mod_id) +{ return pdcp_enb[mod_id].sfn; } /*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ +void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); if (obs_window > 0 ){ - Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window; + Pdcp_stats_tx_window_ms[mod_id][uid]=obs_window; } else{ - Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000; + Pdcp_stats_tx_window_ms[mod_id][uid]=1000; } } /*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ +void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); if (obs_window > 0 ){ - Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window; + Pdcp_stats_rx_window_ms[mod_id][uid]=obs_window; } else{ - Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000; + Pdcp_stats_rx_window_ms[mod_id][uid]=1000; } } /*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> MAX_MOBILES_PER_ENB || lcid<0 || lcid>NB_RB_MAX) +uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + if (mod_id < 0 || mod_id > MAX_NUM_CCs || ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB + || lcid < 0 || lcid > NB_RB_MAX) return -1; - return Pdcp_stats_tx[mod_id][ue_id][lcid]; + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx[mod_id][uid][lcid]; } /*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_bytes[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_bytes[mod_id][uid][lcid]; } /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_w[mod_id][uid][lcid]; } /*PDCP throughput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_bytes_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid]; } /*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_sn[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_sn[mod_id][uid][lcid]; } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_aiat[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_aiat[mod_id][uid][lcid]; } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_aiat_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid]; } - /*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx[mod_id][uid][lcid]; } /*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_bytes[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_bytes[mod_id][uid][lcid]; } /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_w[mod_id][uid][lcid]; } /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_bytes_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid]; } /*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_sn[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_sn[mod_id][uid][lcid]; } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_aiat[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_aiat[mod_id][uid][lcid]; } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_aiat_w[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid]; } /*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_outoforder[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + return Pdcp_stats_rx_outoforder[mod_id][uid][lcid]; } /******************** RRC *****************************/ @@ -1393,3 +1461,419 @@ float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0; return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; } + +int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return -1; + int slice_idx = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id]; + if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl) + return RC.mac[mod_id]->slice_info.dl[slice_idx].id; + return 0; +} + +void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return; + if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; + if (!flexran_dl_slice_exists(mod_id, slice_idx)) return; + RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id] = slice_idx; +} + +int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return -1; + int slice_idx = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id]; + if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul) + return RC.mac[mod_id]->slice_info.ul[slice_idx].id; + return 0; +} + +void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return; + if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; + if (!flexran_ul_slice_exists(mod_id, slice_idx)) return; + RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id] = slice_idx; +} + +int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl; +} + +int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return -1; + int newidx = RC.mac[mod_id]->slice_info.n_dl; + if (newidx >= MAX_NUM_SLICES) return -1; + ++RC.mac[mod_id]->slice_info.n_dl; + flexran_set_dl_slice_id(mod_id, newidx, slice_id); + return newidx; +} + +int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + int n = sli->n_dl; + for (int i = 0; i < n; i++) { + if (sli->dl[i].id == slice_id) return i; + } + return -1; +} + +int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + if (sli->n_dl <= 1) return -1; + + if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name); + --sli->n_dl; + /* move last element to the position of the removed one */ + if (slice_idx != sli->n_dl) + memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl])); + memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl])); + + /* all UEs that have been in the old slice are put into slice index 0 */ + int *assoc_list = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx; + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { + if (assoc_list[i] == slice_idx) + assoc_list[i] = 0; + } + return sli->n_dl; +} + +int flexran_get_num_dl_slices(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.n_dl; +} + +int flexran_get_intraslice_sharing_active(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.intraslice_share_active; +} +void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active; +} + +int flexran_get_interslice_sharing_active(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.interslice_share_active; +} +void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active; +} + +slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].id; +} +void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id; +} + +int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f; +} +void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f; +} + +int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].isol; +} +void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated; +} + +int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].prio; +} +void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority; +} + +int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low; +} +void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow; +} + +int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high; +} +void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh; +} + +int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs; +} +void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs; +} + +int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) +{ + if (!mac_is_present(mod_id)) return -1; + if (!(*sorting_list)) { + *sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting)); + if (!(*sorting_list)) return -1; + } + uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting; + for (int i = 0; i < CR_NUM; i++) { + switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) { + case CR_ROUND: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; + break; + case CR_SRB12: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12; + break; + case CR_HOL: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL; + break; + case CR_LC: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC; + break; + case CR_CQI: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI; + break; + case CR_LCP: + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP; + break; + default: + /* this should not happen, but a "default" */ + (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; + break; + } + } + return CR_NUM; +} +void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) +{ + if (!mac_is_present(mod_id)) return; + uint32_t policy = 0; + for (int i = 0; i < n && i < CR_NUM; i++) { + switch (sorting_list[i]) { + case PROTOCOL__FLEX_DL_SORTING__CR_ROUND: + policy = policy << 4 | CR_ROUND; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_SRB12: + policy = policy << 4 | CR_SRB12; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_HOL: + policy = policy << 4 | CR_HOL; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_LC: + policy = policy << 4 | CR_LC; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_CQI: + policy = policy << 4 | CR_CQI; + break; + case PROTOCOL__FLEX_DL_SORTING__CR_LCP: + policy = policy << 4 | CR_LCP; + break; + default: /* suppresses warnings */ + policy = policy << 4 | CR_ROUND; + break; + } + } + /* fill up with 0 == CR_ROUND */ + if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n); + RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy; +} + +Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; + switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) { + case POL_FAIR: + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; + case POL_GREEDY: + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY; + default: + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; + } +} +void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) +{ + if (!mac_is_present(mod_id)) return; + switch (accounting) { + case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR: + RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; + return; + case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY: + RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY; + return; + default: + RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; + return; + } +} + +char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name; +} +int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) +{ + if (!mac_is_present(mod_id)) return 0; + if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name) + free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name); + RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name); + RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name); + return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL; +} + +int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return -1; + int newidx = RC.mac[mod_id]->slice_info.n_ul; + if (newidx >= MAX_NUM_SLICES) return -1; + ++RC.mac[mod_id]->slice_info.n_ul; + flexran_set_ul_slice_id(mod_id, newidx, slice_id); + return newidx; +} + +int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + int n = sli->n_ul; + for (int i = 0; i < n; i++) { + if (sli->ul[i].id == slice_id) return i; + } + return -1; +} + +int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + slice_info_t *sli = &RC.mac[mod_id]->slice_info; + if (sli->n_ul <= 1) return -1; + + if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name); + --sli->n_ul; + /* move last element to the position of the removed one */ + if (slice_idx != sli->n_ul) + memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul])); + memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul])); + + /* all UEs that have been in the old slice are put into slice index 0 */ + int *assoc_list = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx; + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { + if (assoc_list[i] == slice_idx) + assoc_list[i] = 0; + } + return sli->n_ul; +} + +int flexran_get_num_ul_slices(mid_t mod_id) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.n_ul; +} + +int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul; +} + +slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].id; +} +void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id; +} + +int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f; +} +void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f; +} + +int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb; +} + +void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb; +} + +int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs; +} +void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) +{ + if (!mac_is_present(mod_id)) return; + RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs; +} + +char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) +{ + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name; +} +int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) +{ + if (!mac_is_present(mod_id)) return 0; + if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name) + free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name); + RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name); + RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name); + return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 3354d8ace875da91ed0dc6fc9b53f5fca5225877..37bdaae170d856064f33b3b4bf8c87851a59d42b 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -43,7 +43,7 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/LTE/rrc_eNB_UE_context.h" #include "PHY/phy_extern.h" -#include "log.h" +#include "common/utils/LOG/log.h" /**************************** * get generic info from RAN @@ -73,6 +73,10 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); /* Return the number of attached UEs */ int flexran_get_num_ues(mid_t mod_id); +/* Return the UE id of attached UE as opposed to the index [0,NUM UEs] (i.e., + * the i'th active UE). Returns 0 if the i'th active UE could not be found. */ +int flexran_get_ue_id(mid_t mod_id, int i); + /* Get the rnti of a UE with id ue_id */ rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id); @@ -421,59 +425,59 @@ uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id); /***************************** PDCP ***********************/ /*PDCP superframe numberflexRAN*/ -uint32_t flexran_get_pdcp_sfn(const mid_t mod_id); +uint32_t flexran_get_pdcp_sfn(mid_t mod_id); /*PDCP pdcp tx stats window*/ -void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window); /*PDCP pdcp rx stats window*/ -void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window); /*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP pdcp tx bytes in a given window flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP tx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP rx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*********************RRC**********************/ /*Get primary cell measuremeant id flexRAN*/ @@ -504,3 +508,155 @@ int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); */ /*Get MNC PLMN identity neighbouring Cell*/ /* currently not implemented int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */ + +/************************** Slice configuration **************************/ + +/* Get the DL slice ID for a UE */ +int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); + +/* Set the DL slice index(!) for a UE */ +void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); + +/* Get the UL slice ID for a UE */ +int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); + +/* Set the UL slice index(!) for a UE */ +void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); + +/* Whether intraslice sharing is active, return boolean */ +int flexran_get_intraslice_sharing_active(mid_t mod_id); +/* Set whether intraslice sharing is active */ +void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active); + +/* Whether intraslice sharing is active, return boolean */ +int flexran_get_interslice_sharing_active(mid_t mod_id); +/* Set whether intraslice sharing is active */ +void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active); + +/* Get the number of slices in DL */ +int flexran_get_num_dl_slices(mid_t mod_id); + +/* Query slice existence in DL. Return is boolean value */ +int flexran_dl_slice_exists(mid_t mod_id, int slice_idx); + +/* Create slice in DL, returns the new slice index */ +int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Finds slice in DL with given slice_id and returns slice index */ +int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in DL, returns new number of slices or -1 on error */ +int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); + +/* Get the ID of a slice in DL */ +slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx); +/* Set the ID of a slice in DL */ +void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); + +/* Get the RB share a slice in DL, value 0-100 */ +int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx); +/* Set the RB share a slice in DL, value 0-100 */ +void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage); + +/* Whether a slice in DL is isolated */ +int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx); +/* Set whether a slice in DL is isolated */ +void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated); + +/* Get the priority of a slice in DL */ +int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx); +/* Get the priority of a slice in DL */ +void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority); + +/* Get the lower end of the frequency range for the slice positioning in DL */ +int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx); +/* Set the lower end of the frequency range for the slice positioning in DL */ +void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow); + +/* Get the higher end of the frequency range for the slice positioning in DL */ +int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx); +/* Set the higher end of the frequency range for the slice positioning in DL */ +void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh); + +/* Get the maximum MCS for slice in DL */ +int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx); +/* Set the maximum MCS for slice in DL */ +void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); + +/* Get the sorting order of a slice in DL, return value is number of elements + * in sorting_list */ +int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list); +/* Set the sorting order of a slice in DL */ +void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n); + +/* Get the accounting policy for a slice in DL */ +Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx); +/* Set the accounting policy for a slice in DL */ +void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting); + +/* Get the scheduler name for a slice in DL */ +char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx); +/* Set the scheduler name for a slice in DL */ +int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name); + +/* Get the number of slices in UL */ +int flexran_get_num_ul_slices(mid_t mod_id); + +/* Query slice existence in UL. Return is boolean value */ +int flexran_ul_slice_exists(mid_t mod_id, int slice_idx); + +/* Create slice in UL, returns the new slice index */ +int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Finds slice in UL with given slice_id and returns slice index */ +int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in UL */ +int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); + +/* Get the ID of a slice in UL */ +slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx); +/* Set the ID of a slice in UL */ +void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); + +/* Get the RB share a slice in UL, value 0-100 */ +int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx); +/* Set the RB share a slice in UL, value 0-100 */ +void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage); + +/* TODO Whether a slice in UL is isolated */ +/*int flexran_get_ul_slice_isolation(mid_t mod_id, int slice_idx);*/ +/* TODO Set whether a slice in UL is isolated */ +/*void flexran_set_ul_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);*/ + +/* TODO Get the priority of a slice in UL */ +/*int flexran_get_ul_slice_priority(mid_t mod_id, int slice_idx);*/ +/* TODO Set the priority of a slice in UL */ +/*void flexran_set_ul_slice_priority(mid_t mod_id, int slice_idx, int priority);*/ + +/* Get the first RB for allocation in a slice in UL */ +int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx); +/* Set the first RB for allocation in a slice in UL */ +void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb); + +/* TODO Get the number of RB for the allocation in a slice in UL */ +/*int flexran_get_ul_slice_length_rb(mid_t mod_id, int slice_idx);*/ +/* TODO Set the of number of RB for the allocation in a slice in UL */ +/*void flexran_set_ul_slice_length_rb(mid_t mod_id, int slice_idx, int poshigh);*/ + +/* Get the maximum MCS for slice in UL */ +int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx); +/* Set the maximum MCS for slice in UL */ +void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); + +/* TODO Get the sorting order of a slice in UL, return value is number of elements + * in sorting_list */ +/*int flexran_get_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting **sorting_list);*/ +/* TODO Set the sorting order of a slice in UL */ +/*void flexran_set_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting *sorting_list, int n);*/ + +/* TODO Get the accounting policy for a slice in UL */ +/*Protocol__UlAccountingPolicy flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx);*/ +/* TODO Set the accounting policy for a slice in UL */ +/*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/ + +/* Get the scheduler name for a slice in UL */ +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); diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index 98d83c78a950d7db533316f297e3f3e4ac4c9704..06443c14d1f399aaf836a5469d9bee97abfe05da 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -37,7 +37,6 @@ # include "tree.h" # include "intertask_interface.h" -# include "timer.h" diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 8fd85e78118f497a215eff748b1ffbbadb975d34..0b4f05a56e1883374afc17d50a35d9ee7a69bd4e 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -160,6 +160,58 @@ uint32_t to_earfcn(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw) (eutra_bandtable[i].N_OFFs_DL / 10)); } +uint32_t to_earfcn_DL(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw) +{ + + uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; + int bw_by_100 = bw / 100; + + int i; + + AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); + for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + + AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, + "Band %d, bw %u : DL carrier frequency %lld Hz < %u\n", + eutra_bandP, bw, dl_CarrierFreq, + eutra_bandtable[i].dl_min); + AssertFatal(dl_CarrierFreq_by_100k <= + (eutra_bandtable[i].dl_max - bw_by_100), + "Band %d, bw %u : DL carrier frequency %lld Hz > %d\n", + eutra_bandP, bw, dl_CarrierFreq, + eutra_bandtable[i].dl_max - bw_by_100); + + + return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + + (eutra_bandtable[i].N_OFFs_DL / 10)); +} + +uint32_t to_earfcn_UL(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw) +{ + + uint32_t ul_CarrierFreq_by_100k = ul_CarrierFreq / 100000; + int bw_by_100 = bw / 100; + + int i; + + AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); + for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + + AssertFatal(ul_CarrierFreq_by_100k >= eutra_bandtable[i].ul_min, + "Band %d, bw %u : UL carrier frequency %lld Hz < %u\n", + eutra_bandP, bw, ul_CarrierFreq, + eutra_bandtable[i].ul_min); + AssertFatal(ul_CarrierFreq_by_100k <= + (eutra_bandtable[i].ul_max - bw_by_100), + "Band %d, bw %u : UL carrier frequency %lld Hz > %d\n", + eutra_bandP, bw, ul_CarrierFreq, + eutra_bandtable[i].ul_max - bw_by_100); + + + return (ul_CarrierFreq_by_100k - eutra_bandtable[i].ul_min + + ((eutra_bandtable[i].N_OFFs_DL + 180000) / 10)); +} + uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { @@ -733,7 +785,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, if (RC.mac == NULL) l2_init_eNB(); - mac_top_init_eNB(); + //mac_top_init_eNB(); RC.mac[Mod_idP]->common_channels[CC_idP].mib = mib; RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId; @@ -852,16 +904,21 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); } else { - if (logicalChannelConfig) + if (logicalChannelConfig) { UE_list-> UE_template[CC_idP][UE_id].lcgidmap [logicalChannelIdentity] = *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup; - else - UE_list-> - UE_template[CC_idP][UE_id].lcgidmap - [logicalChannelIdentity] = 0; + ul_SpecificParameters->logicalChannelGroup; + UE_list-> + UE_template[CC_idP][UE_id].lcgidpriority + [logicalChannelIdentity]= + logicalChannelConfig->ul_SpecificParameters->priority; + + } else + UE_list-> + UE_template[CC_idP][UE_id].lcgidmap + [logicalChannelIdentity] = 0; } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index dc7cbd409c4db13361bf2e1b7f1137179f7fcb48..4dbf3cf36f57d2c700463d071b02d805bb61a704 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -538,8 +538,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, 0 ? "in synch" : "out of sync", UE_list->UE_template[CC_id][i].phr_info, UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], - (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, - (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); + (5*UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 640) / 10, + (5*UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 640) / 10); } RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + @@ -703,6 +703,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); } + if (mac_agent_registered[module_idP] && subframeP == 9) { + flexran_agent_slice_update(module_idP); + } + stop_meas(&RC.mac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 35590ec896716ca9777c774fbe215690a36ae04e..b637a92a9616f53e447cb422087a43dd3789eff4 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -988,9 +988,10 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, payload[0], ra->msg4_TBsize)); if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, WS_C_RNTI, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); LOG_D(OPT, @@ -1193,9 +1194,10 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, payload[0], ra->msg4_TBsize)); if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, WS_C_RNTI, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); LOG_D(OPT, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index d965bc811bf1c07ccf84c5e816a63ce5ffbe1a01..b2b59691f88db67daeafa8dbe2db05a8267bce01 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -281,10 +281,10 @@ schedule_SIB1_BR(module_id_t module_idP, eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_BR_pdu[0].payload[0], bcch_sdu_length, - 0xffff, 4, 0xffff, eNB->frame, eNB->subframe, 0, 0); + 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); LOG_D(OPT, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); @@ -472,11 +472,11 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_BR_pdu[i + 1].payload[0], bcch_sdu_length, 0xffff, - 4, + WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); LOG_D(OPT, @@ -759,11 +759,11 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_pdu.payload[0], bcch_sdu_length, 0xffff, - 4, 0xffff, eNB->frame, eNB->subframe, 0, 0); + WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); LOG_D(OPT, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", module_idP, frameP, CC_id, 0xffff, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index df52b83d729b4087ba4d137da71bfcb339440252..d4f7c04d0374b82a93245b84ae2df8c702f4db0b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -29,6 +29,7 @@ */ +#define _GNU_SOURCE #include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac_proto.h" @@ -54,10 +55,6 @@ #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 <dlfcn.h> #include "T.h" @@ -65,54 +62,21 @@ #define ENABLE_MAC_PAYLOAD_DEBUG //#define DEBUG_eNB_SCHEDULER 1 +#include "common/ran_context.h" extern RAN_CONTEXT_t RC; extern uint8_t nfapi_mode; - -// number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; - -// RB share for each slice for past and current time -float avg_slice_percentage=0.25; -float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage = 0; -float total_slice_percentage_current = 0; - -// MAX MCS for each slice for past and current time -int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; -int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; - -int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; -int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; - -// name of available scheduler -char *dl_scheduler_type[MAX_NUM_SLICES] = - { "schedule_ue_spec", - "schedule_ue_spec", - "schedule_ue_spec", - "schedule_ue_spec" - }; - -// The lists of criteria that enforce the sorting policies of the slices -uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; -uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; - -// pointer to the slice specific scheduler -slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; - //------------------------------------------------------------------------------ void add_ue_dlsch_info(module_id_t module_idP, - int CC_id, - int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) + int CC_id, + int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) //------------------------------------------------------------------------------ { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); + UE_RNTI(module_idP, UE_id); // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; @@ -124,7 +88,7 @@ add_ue_dlsch_info(module_id_t module_idP, //------------------------------------------------------------------------------ int schedule_next_dlue(module_id_t module_idP, int CC_id, - sub_frame_t subframeP) + sub_frame_t subframeP) //------------------------------------------------------------------------------ { @@ -134,7 +98,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) { if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { + S_DL_WAITING) { return next_ue; } } @@ -146,21 +110,21 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, } } - return (-1); //next_ue; + return (-1); //next_ue; } //------------------------------------------------------------------------------ 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) + 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) //------------------------------------------------------------------------------ { @@ -218,10 +182,10 @@ generate_dlsch_header(unsigned char *mac_header, // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + "timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); ce_ptr += sizeof(TIMING_ADVANCE_CMD); //msg("offset %d\n",ce_ptr-mac_header_control_elements); } @@ -246,9 +210,9 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 1; LOG_T(MAC, - "[eNB ][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]); + "[eNB ][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]); memcpy(ce_ptr, ue_cont_res_id, 6); ce_ptr += 6; @@ -258,7 +222,7 @@ generate_dlsch_header(unsigned char *mac_header, for (i = 0; i < num_sdus; i++) { LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); + num_sdus, sdu_lengths[i]); if (first_element > 0) { mac_header_ptr->E = 1; @@ -291,10 +255,10 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 3; #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif } } @@ -316,7 +280,7 @@ generate_dlsch_header(unsigned char *mac_header, printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } */ - if (post_padding > 0) { // we have lots of padding at the end of the packet + 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 @@ -324,7 +288,7 @@ generate_dlsch_header(unsigned char *mac_header, mac_header_ptr->E = 0; mac_header_ptr->LCID = SHORT_PADDING; mac_header_ptr++; - } else { // no end of packet padding + } else { // no end of packet padding // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) mac_header_ptr++; } @@ -334,9 +298,9 @@ generate_dlsch_header(unsigned char *mac_header, if ((ce_ptr - mac_header_control_elements) > 0) { // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); + ce_ptr - mac_header_control_elements); mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); + (unsigned char) (ce_ptr - mac_header_control_elements); } //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); @@ -346,7 +310,7 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ void set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, - int subframeP) + int subframeP) //------------------------------------------------------------------------------ { @@ -354,202 +318,106 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, UE_list_t *UE_list = &eNB->UE_list; unsigned char DAI; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config != NULL) { //TDD + if (cc->tdd_Config != NULL) { //TDD DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); // Save DAI for Format 0 DCI switch (cc->tdd_Config->subframeAssignment) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; - - case 1: - switch (subframeP) { case 0: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; - - case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) break; - case 5: - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; - - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + case 1: + switch (subframeP) { + case 0: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; break; - } - break; - case 2: - // if ((subframeP==3)||(subframeP==8)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; - case 3: + case 5: + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; - //} - switch (subframeP) { - case 5: - case 6: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; - - case 7: - case 8: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + } + break; - case 9: - case 0: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; - break; + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - default: - break; - } + case 3: + + //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; + //} + switch (subframeP) { + case 5: + case 6: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; + + case 7: + case 8: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + + case 9: + case 0: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; + break; + + default: + break; + } - break; + break; - case 4: - // if ((subframeP==8)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 4: + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 5: - // if (subframeP==8) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 5: + // if (subframeP==8) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 6: + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - default: - break; + default: + break; } } } //------------------------------------------------------------------------------ void -schedule_dlsch(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) -//------------------------------------------------------------------------------{ -{ +schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { int i = 0; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; + memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub)); - total_slice_percentage=0; - avg_slice_percentage=1.0/n_active_slices; - - // reset the slice percentage for inactive slices - for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { - slice_percentage[i]=0; - } - for (i = 0; i < n_active_slices; i++) { - if (slice_percentage[i] < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, slice_percentage[i]); - slice_percentage[i]=0; - } - total_slice_percentage+=slice_percentage[i]; - } - - for (i = 0; i < n_active_slices; i++) { - - // Load any updated functions - if (update_dl_scheduler[i] > 0 ) { - slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0 ; - update_dl_scheduler_current[i] = 0; - LOG_I(MAC,"update dl scheduler slice %d\n", i); - } - - if (total_slice_percentage <= 1.0){ // the new total RB share is within the range - - // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices ){ - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { - LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); - - n_active_slices_current = n_active_slices; - - } else { - LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; - } - } - - // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); - total_slice_percentage_current= total_slice_percentage; - slice_percentage_current[i] = slice_percentage[i]; - - } - - // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]){ - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); - slice_maxmcs_current[i] = slice_maxmcs[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs[i],slice_maxmcs_current[i]); - slice_maxmcs[i]= slice_maxmcs_current[i]; - } - } - - // check if a new scheduler, and log the console - if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, dl_scheduler_type[i]); - update_dl_scheduler_current[i] = update_dl_scheduler[i]; - } - - } else { - // here we can correct the values, e.g. reduce proportionally - - if (n_active_slices == n_active_slices_current){ - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, total_slice_percentage_current, total_slice_percentage); - if (slice_percentage[i] >= avg_slice_percentage){ - slice_percentage[i]-=0.1; - total_slice_percentage-=0.1; - } - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, total_slice_percentage_current, total_slice_percentage, - n_active_slices, n_active_slices_current ); - n_active_slices = n_active_slices_current; - slice_percentage[i] = slice_percentage_current[i]; - } - } - - // Check for new sorting policy - if (sorting_policy_current[i] != sorting_policy[i]) { - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", - module_idP, i, frameP, subframeP, sorting_policy_current[i], sorting_policy[i]); - sorting_policy_current[i] = sorting_policy[i]; - } - + for (i = 0; i < sli->n_dl; i++) { // Run each enabled slice-specific schedulers one by one - slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); + sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } } @@ -558,8 +426,8 @@ schedule_dlsch(module_id_t module_idP, //------------------------------------------------------------------------------ void -schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) +schedule_ue_spec(module_id_t module_idP, int slice_idxP, + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { int CC_id; @@ -587,10 +455,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_sched_ctrl *ue_sched_ctl; int mcs; int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; + int min_rb_unit[NFAPI_CC_MAX]; + int N_RB_DL[NFAPI_CC_MAX]; + int total_nb_available_rb[NFAPI_CC_MAX]; + int N_RBG[NFAPI_CC_MAX]; nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_pdu_t *dl_config_pdu; int tdd_sfa; @@ -599,61 +467,58 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, int header_length_total; start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); // for TDD: check that we have to act here, otherwise return if (cc[0].tdd_Config) { tdd_sfa = cc[0].tdd_Config->subframeAssignment; switch (subframeP) { - case 0: - // always continue - break; - case 1: - return; - break; - case 2: - return; - break; - case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) - return; - break; - case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 5: - break; - case 6: - case 7: - if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) - return; - break; - case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 9: - if (tdd_sfa == 0) - return; - break; - + case 0: + // always continue + break; + case 1: + return; + break; + case 2: + return; + break; + case 3: + if ((tdd_sfa != 2) && (tdd_sfa != 5)) + return; + break; + case 4: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 5: + break; + case 6: + case 7: + if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) + return; + break; + case 8: + if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 9: + if (tdd_sfa == 0) + return; + break; } } //weight = get_ue_weight(module_idP,UE_id); aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); // get number of PRBs less those used by common channels total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; for (i = 0; i < N_RB_DL[CC_id]; i++) if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; + total_nb_available_rb[CC_id]--; N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); @@ -665,22 +530,37 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; } - /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) + // CALLING Pre_Processor for downlink scheduling + // (Returns estimation of RBs required by each UE and the allocation on sub-band) + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, - slice_idP, + slice_idxP, frameP, subframeP, - N_RBG, - mbsfn_flag); + mbsfn_flag, + eNB->slice_info.rballoc_sub); stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); + + //RC.mac[module_idP]->slice_info.slice_counter--; + // Do the multiplexing and actual allocation only when all slices have been pre-processed. + //if (RC.mac[module_idP]->slice_info.slice_counter > 0) { + //stop_meas(&eNB->schedule_dlsch); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + //return; + //} + + if (RC.mac[module_idP]->slice_info.interslice_share_active) { + dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP, eNB->slice_info.rballoc_sub); + /* the interslice multiplexing re-sorts the UE_list for the slices it tries + * to multiplex, so we need to sort it for the current slice again */ + sort_UEs(module_idP, slice_idxP, frameP, subframeP); + } + + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; @@ -688,49 +568,51 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (mbsfn_flag[CC_id] > 0) continue; - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - continue_flag = 0; // reset the flag to allow allocation for the remaining UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", CC_id, UE_id); + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs rnti = UE_RNTI(module_idP, UE_id); eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", - UE_id, UE_list->num_UEs); - continue_flag = 1; + LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id, UE_list->num_UEs); + continue_flag = 1; } if (eNB_UE_stats == NULL) { - LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); - continue_flag = 1; + LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); + continue_flag = 1; + } + + if (!ue_dl_slice_membership(module_idP, UE_id, slice_idxP)) { + LOG_D(MAC, "UE%d is not part of slice %d ID %d\n", + UE_id, slice_idxP, RC.mac[module_idP]->slice_info.dl[slice_idxP].id); + /* prevent execution of add_ue_dlsch_info(), it is done by the other + * slice */ + continue; } - if (!ue_slice_membership(UE_id, slice_idP)) - continue; if (continue_flag != 1) { - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC, "Unsupported transmission mode %d\n", - get_tmode(module_idP, CC_id, UE_id)); - aggregation = 2; - } + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + case 3: + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + default: + LOG_W(MAC, "Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id)); + aggregation = 2; + } } + /* if (continue_flag != 1 */ if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, @@ -741,78 +623,74 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 } - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai(subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + // If TDD + if (cc[CC_id].tdd_Config != NULL) { //TDD + set_ue_dai(subframeP, + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); } if (continue_flag == 1) { - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, S_DL_NONE); - continue; + add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_NONE); + continue; } nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) { + LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id); + continue; + } header_length_total = 0; sdu_length_total = 0; num_sdus = 0; /* - DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || + (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - else { // this operation is also done in the preprocessor - eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } else { // this operation is also done in the preprocessor + eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, + eNB->slice_info.dl[slice_idxP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } + // Store stats + // UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - - // store stats - //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - - // initializing the rb allocation indicator for each UE + // Initializing the rb allocation indicator for each UE for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; } LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], - eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); - - + "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, + nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); /* process retransmission */ - if (round != 8) { - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], - nb_rb); + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], nb_rb); if (nb_rb <= nb_available_rb) { if (cc[CC_id].tdd_Config != NULL) { @@ -825,82 +703,82 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->UE_template[CC_id][UE_id].DAI); } - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) - printf("WARN: rballoc_subband not free for retrans?\n"); - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) + printf("WARN: rballoc_subband not free for retrans?\n"); + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } - for(j=0; j<N_RBG[CC_id]; j++) { - eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ - - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; - - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); - } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + j = j + 1; + } + } + + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + + for(j = 0; j < N_RBG[CC_id]; ++j) { + eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ + + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n", rnti); + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI: see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + + // TDD + if (cc[CC_id].tdd_Config != NULL) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = + (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + } else { + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); } if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, @@ -912,48 +790,44 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 - /* retransmission, no pdu_index */ - , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); - - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - // No TX request for retransmission (check if null request for FAPI) - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); - } - } - + fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1, + /* retransmission, no pdu_index */ + rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), + round & 3, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], round); + + program_dlsch_acknak(module_idP, CC_id, UE_id, frameP, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + // No TX request for retransmission (check if null request for FAPI) + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, subframeP, UE_id, rnti); + } + } - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); + add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); //eNB_UE_stats->dlsch_trials[round]++; UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; @@ -975,17 +849,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, // add the length for all the control elements (timing adv, drx, etc) : header + payload - if (ue_sched_ctl->ta_timer == 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 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; + ta_len = (ta_update != 31) ? 2 : 0; // RLC data on DCCH if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { @@ -996,7 +871,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, #endif ); - sdu_lengths[0] = 0; + sdu_lengths[0] = 0; if (rlc_status.bytes_in_buffer > 0) { LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", @@ -1062,10 +937,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } } - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), - T_INT(sdu_lengths[0])); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), + T_INT(sdu_lengths[0])); LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", module_idP, CC_id, sdu_lengths[0]); @@ -1083,15 +958,15 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, num_sdus = 1; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); + LOG_T(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } + for (j = 0; j < sdu_lengths[0]; ++j) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif } } @@ -1121,10 +996,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, #endif ); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; @@ -1139,15 +1014,15 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, num_sdus++; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); + LOG_T(MAC, + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } + for (j = 0; j < sdu_lengths[num_sdus]; ++j) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif } @@ -1236,15 +1111,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, // Now compute number of required RBs for total sdu length // Assume RAH format 2 - mcs = eNB_UE_stats->dlsch_mcs1; + mcs = eNB_UE_stats->dlsch_mcs1; - if (mcs == 0) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb = min_rb_unit[CC_id]; - } - - TBS = get_TBS_DL(mcs, nb_rb); + if (mcs == 0) { + nb_rb = 4; // don't let the TBS get too small + } else { + nb_rb = min_rb_unit[CC_id]; + } + TBS = get_TBS_DL(mcs, nb_rb); while (TBS < sdu_length_total + header_length_total + ta_len) { nb_rb += min_rb_unit[CC_id]; // @@ -1256,33 +1130,31 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, break; } - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - } + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } - j = j + 1; - } - } + j = j + 1; + } + } // decrease mcs until TBS falls below required length while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { @@ -1300,16 +1172,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, TBS = get_TBS_DL(mcs, nb_rb); } - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); + LOG_D(MAC, + "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, mcs); #ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); + LOG_D(MAC, + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { @@ -1320,12 +1192,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, post_padding = 1; } - offset = generate_dlsch_header((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 - NULL, // contention res id - padding, post_padding); + offset = generate_dlsch_header((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 + NULL, // contention res id + padding, post_padding); //#ifdef DEBUG_eNB_SCHEDULER if (ta_update != 31) { @@ -1339,19 +1212,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } //#endif #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } + for (i = 0; i < 16; ++i) { + LOG_T(MAC, "%x.", dlsch_buffer[i]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - // 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(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + // 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(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); // fill remainder of DLSCH with 0 for (j = 0; j < (TBS - sdu_length_total - offset); j++) { @@ -1359,9 +1231,9 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *) - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS, module_idP, 3, + trace_pdu(DIRECTION_DOWNLINK, + (uint8_t *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, WS_C_RNTI, UE_RNTI(module_idP, UE_id), eNB->frame, eNB->subframe, 0, 0); LOG_D(OPT, @@ -1375,14 +1247,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, T_INT(subframeP), T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; + add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); + // store stats + eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; + eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; @@ -1391,10 +1261,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; if (cc[CC_id].tdd_Config != NULL) { // TDD UE_list->UE_template[CC_id][UE_id].DAI++; @@ -1419,8 +1289,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; if (normalized_rx_power > (target_rx_power + 4)) { tpc = 0; //-1 @@ -1443,39 +1313,40 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, tpc = 1; //0 } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - mcs); - } else { - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP, CC_id, harq_pid, mcs); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = + get_aggregation(get_bw_index(module_idP, CC_id), ue_sched_ctl->dl_cqi[CC_id], format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = + 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = + (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + mcs); + } else { + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP, CC_id, harq_pid, mcs); } @@ -1490,16 +1361,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - // Toggle NDI for next time - LOG_D(MAC, - "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP, subframeP, UE_id, rnti, - harq_pid, - UE_list-> - UE_template[CC_id][UE_id].oldNDI[harq_pid]); + // Toggle NDI for next time + LOG_D(MAC, + "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP, subframeP, UE_id, rnti, harq_pid, + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; @@ -1550,24 +1419,199 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } } - if (cc[CC_id].tdd_Config != NULL) { // TDD - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + if (cc[CC_id].tdd_Config != NULL) { // TDD + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); } - } // UE_id loop } // CC_id loop - fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); } +//------------------------------------------------------------------------------ +void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) +//------------------------------------------------------------------------------ +{ + // FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct. + + int UE_id, CC_id, rbg, i; + int N_RB_DL, min_rb_unit, tm; + int owned, used; + + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + UE_sched_ctrl *ue_sched_ctl; + COMMON_channels_t *cc; + int N_RBG[NFAPI_CC_MAX]; + + int slice_sorted_list[MAX_NUM_SLICES]; + int slice_idx; + int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX]; + int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES]; + uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + + uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB]; + uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB]; + uint8_t (*MIMO_mode_indicator)[N_RBG_MAX]; + + // Initialize the free RBGs map + // free_rbgs_map[CC_id][rbg] = -1 if RBG is allocated, + // otherwise it contains the id of the slice it belongs to. + // (Information about slicing must be retained to deal with isolation). + // FIXME: This method does not consider RBGs that are free and belong to no slices + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + for (i = 0; i < sli->n_dl; ++i) { + owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; + if (owned) { + used = rballoc_sub[CC_id][rbg]; + free_rbgs_map[CC_id][rbg] = used ? -1 : i; + break; + } + } + } + } + + // Find out which slices need other resources. + // FIXME: I don't think is really needed since we check nb_rbs_remaining later + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { + for (i = 0; i < sli->n_dl; ++i) { + has_traffic[CC_id][i] = 0; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + if (sli->pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { + has_traffic[CC_id][i] = 1; + break; + } + } + } + } + + slice_priority_sort(Mod_id, slice_sorted_list); + + // MULTIPLEXING + // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { + + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + min_rb_unit = get_min_rb_unit(Mod_id, CC_id); + + for (i = 0; i < sli->n_dl; ++i) { + slice_idx = slice_sorted_list[i]; + + if (has_traffic[CC_id][slice_idx] == 0) continue; + + // Build an ad-hoc allocation mask fo the slice + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + if (free_rbgs_map[CC_id][rbg] == -1) { + // RBG is already allocated + allocation_mask[CC_id][rbg] = 0; + continue; + } + if (sli->dl[free_rbgs_map[CC_id][rbg]].isol == 1) { + // RBG belongs to an isolated slice + allocation_mask[CC_id][rbg] = 0; + continue; + } + // RBG is free + allocation_mask[CC_id][rbg] = 1; + } + + // Sort UE again + // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) + // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it + sort_UEs(Mod_id, slice_idx, frameP, subframeP); + + nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining; + nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required; + MIMO_mode_indicator = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; + + // Allocation + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + tm = get_tmode(Mod_id, CC_id, UE_id); + + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + + // FIXME: I think that some of these checks are redundant + if (allocation_mask[CC_id][rbg] == 0) continue; + if (rballoc_sub[CC_id][rbg] != 0) continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] != 0) continue; + if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue; + + if ((rbg == N_RBG[CC_id] - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { + // Allocating last, smaller RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) { + rballoc_sub[CC_id][rbg] = 1; + free_rbgs_map[CC_id][rbg] = -1; + ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1; + MIMO_mode_indicator[CC_id][rbg] = 1; + if (tm == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; + } + } else { + // Allocating a standard-sized RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) { + rballoc_sub[CC_id][rbg] = 1; + free_rbgs_map[CC_id][rbg] = -1; + ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1; + MIMO_mode_indicator[CC_id][rbg] = 1; + if (tm == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; + } + } + } + } + } + } +} + +//------------------------------------------------------------------------------ +void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + int UE_id, CC_id, i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + //UE_sched_ctrl *ue_sched_ctl; + + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { + for (i = 0; i < sli->n_dl; ++i) { + + // Sort UE again + // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it + sort_UEs(Mod_id, (uint8_t)i, frameP, subframeP); + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + //ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + // TODO: Do something here + // ue_sched_ctl->pre_nb_available_rbs[CC_id]; + } + } + } +} + + //------------------------------------------------------------------------------ void fill_DLSCH_dci(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) //------------------------------------------------------------------------------ { @@ -1591,9 +1635,9 @@ fill_DLSCH_dci(module_id_t module_idP, start_meas(&eNB->fill_DLSCH_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); + (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); if (mbsfn_flagP[CC_id] > 0) @@ -1605,42 +1649,43 @@ fill_DLSCH_dci(module_id_t module_idP, // UE specific DCIs for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { + UE_id = UE_list->next[UE_id]) { LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, - eNB_dlsch_info[module_idP][CC_id][UE_id].status); + eNB_dlsch_info[module_idP][CC_id][UE_id].status); if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; - rnti = UE_RNTI(module_idP, UE_id); + // clear scheduling flag + eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP, UE_id); harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - /// Synchronizing rballoc with rballoc_sub - for (i = 0; i < N_RBG; i++) { - rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; - } + /// Synchronizing rballoc with rballoc_sub + for (i = 0; i < N_RBG; i++) { + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; + } - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - - for (i = 0; - i < DL_req[CC_id].dl_config_request_body.number_pdu; - i++) { - dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; - if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; - } else - if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); - } - } + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + + for (i = 0; + i < DL_req[CC_id].dl_config_request_body.number_pdu; + i++) { + dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, + rballoc_sub); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; + } else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, + rballoc_sub); + } + } } } @@ -1652,8 +1697,8 @@ fill_DLSCH_dci(module_id_t module_idP, //------------------------------------------------------------------------------ unsigned char *get_dlsch_sdu(module_id_t module_idP, - int CC_id, frame_t frameP, rnti_t rntiP, - uint8_t TBindex) + int CC_id, frame_t frameP, rnti_t rntiP, + uint8_t TBindex) //------------------------------------------------------------------------------ { @@ -1662,28 +1707,28 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, if (rntiP == SI_RNTI) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + module_idP, CC_id, frameP); return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); } - if (rntiP==P_RNTI) { - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); + if (rntiP == P_RNTI) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); - return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); + return ((unsigned char *) &eNB->common_channels[CC_id].PCCH_pdu.payload[0]); } - UE_id = find_UE_id(module_idP,rntiP); + UE_id = find_UE_id(module_idP, rntiP); if (UE_id != -1) { LOG_D(MAC, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); + "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, frameP, CC_id, rntiP, UE_id); return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); } else { LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); + "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, frameP, CC_id, rntiP); return NULL; } @@ -1700,7 +1745,7 @@ update_ul_dci(module_id_t module_idP, nfapi_hi_dci0_request_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; int i; @@ -1711,8 +1756,8 @@ update_ul_dci(module_id_t module_idP, i++) { if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; } } @@ -1722,84 +1767,83 @@ update_ul_dci(module_id_t module_idP, //------------------------------------------------------------------------------ void set_ue_dai(sub_frame_t subframeP, - int UE_id, uint8_t CC_id, uint8_t tdd_config, - UE_list_t * UE_list) + int UE_id, uint8_t CC_id, uint8_t tdd_config, + UE_list_t *UE_list) //------------------------------------------------------------------------------ { switch (tdd_config) { - case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 0: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) + || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 1: + if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) + || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 2: - if ((subframeP == 4) || (subframeP == 5)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 2: + if ((subframeP == 4) || (subframeP == 5)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 3: + if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 4: - if ((subframeP == 0) || (subframeP == 6)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 4: + if ((subframeP == 0) || (subframeP == 6)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 5: - if (subframeP == 9) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 5: + if (subframeP == 9) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 6: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) + || (subframeP == 6) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - default: - UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_I(MAC, "unknow TDD config %d\n", tdd_config); - break; + default: + UE_list->UE_template[CC_id][UE_id].DAI = 0; + LOG_I(MAC, "unknown TDD config %d\n", tdd_config); + break; } } -void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) -{ +void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { /* DCI:format 1A/1C P-RNTI:0xFFFE */ /* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */ - uint16_t pcch_sdu_length; - int mcs = -1; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int n_rb_dl; - int first_rb = -1; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; + uint16_t pcch_sdu_length; + int mcs = -1; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int n_rb_dl; + int first_rb = -1; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; #ifdef FORMAT1C int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ @@ -1823,9 +1867,9 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) start_meas(&eNB->schedule_pch); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { cc = &eNB->common_channels[CC_id]; - vrb_map = (void*)&cc->vrb_map; + vrb_map = (void *) &cc->vrb_map; n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { @@ -1833,17 +1877,18 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) continue; } if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { - pcch_sdu_length = mac_rrc_data_req(module_idP, + pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, - PCCH,1, + PCCH, 1, &cc->PCCH_pdu.payload[0], i); // used for ue index - if (pcch_sdu_length == 0) { - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); - continue; - } - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); + if (pcch_sdu_length == 0) { + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP, frameP, subframeP); + continue; + } + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, + frameP, subframeP, CC_id, i, pcch_sdu_length); #ifdef FORMAT1C //NO SIB if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || @@ -1968,66 +2013,55 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) } } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= get_TBS_DL(0,3)) { - mcs=0; - } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { - mcs=1; - } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { - mcs=2; - } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { - mcs=3; - } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { - mcs=4; - } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { - mcs=5; - } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { - mcs=6; - } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { - mcs=7; - } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { - mcs=8; - } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { - mcs=9; - } + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= get_TBS_DL(0, 3)) { + mcs = 0; + } else if (pcch_sdu_length <= get_TBS_DL(1, 3)) { + mcs = 1; + } else if (pcch_sdu_length <= get_TBS_DL(2, 3)) { + mcs = 2; + } else if (pcch_sdu_length <= get_TBS_DL(3, 3)) { + mcs = 3; + } else if (pcch_sdu_length <= get_TBS_DL(4, 3)) { + mcs = 4; + } else if (pcch_sdu_length <= get_TBS_DL(5, 3)) { + mcs = 5; + } else if (pcch_sdu_length <= get_TBS_DL(6, 3)) { + mcs = 6; + } else if (pcch_sdu_length <= get_TBS_DL(7, 3)) { + mcs = 7; + } else if (pcch_sdu_length <= get_TBS_DL(8, 3)) { + mcs = 8; + } else if (pcch_sdu_length <= get_TBS_DL(9, 3)) { + mcs = 9; + } #endif - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); #ifdef FORMAT1C - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; -#endif - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - - // Rel10 fields -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; -#endif - // Rel13 fields -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); @@ -2044,12 +2078,12 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; #ifdef FORMAT1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); #else - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; @@ -2068,6 +2102,18 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + + // Rel10 fields +#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; +#endif + // Rel13 fields +#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; +#endif + dl_req->number_pdu++; eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; @@ -2085,7 +2131,7 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) } if (opt_enabled == 1) { - trace_pdu(1, + trace_pdu(DIRECTION_DOWNLINK, &eNB->common_channels[CC_id].PCCH_pdu.payload[0], pcch_sdu_length, 0xffff, @@ -2116,3 +2162,27 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) stop_meas(&eNB->schedule_pch); return; } + +static int slice_priority_compare(const void *_a, const void *_b, void *_c) +{ + const int slice_id1 = *(const int *) _a; + const int slice_id2 = *(const int *) _b; + const module_id_t Mod_id = *(int *) _c; + const slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + + if (sli->dl[slice_id1].prio > sli->dl[slice_id2].prio) { + return -1; + } + return 1; +} + +void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]) +{ + int i; + for (i = 0; i < RC.mac[Mod_id]->slice_info.n_dl; ++i) { + slice_list[i] = i; + } + + qsort_r(slice_list, RC.mac[Mod_id]->slice_info.n_dl, sizeof(int), + slice_priority_compare, &Mod_id); +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 1acf65722099af3c1cf4df99251ebbcbbe591355..9ab4306000ffe05ba7686a2fcf01f14e75ccb4cc 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -542,8 +542,9 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, uint16_t temp_total_rbs_count; unsigned char temp_total_ue_count; unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; + uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX]; int UE_id, i; - uint16_t j; + uint16_t j,c; uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -554,8 +555,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, uint8_t CC_id; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - int N_RB_DL; - int transmission_mode = 0; UE_sched_ctrl *ue_sched_ctl; // int rrc_status = RRC_IDLE; COMMON_channels_t *cc; @@ -590,14 +589,14 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, + 0, frameP, subframeP, - N_RBG[CC_id], + min_rb_unit, (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, rballoc_sub, - MIMO_mode_indicator); + MIMO_mode_indicator, + mbsfn_flag); } } @@ -621,7 +620,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, average_rbs_per_user[CC_id] = 0; cc = &RC.mac[Mod_id]->common_channels[CC_id]; // Get total available RBS count and total UE count - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); temp_total_rbs_count = RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs; temp_total_ue_count = dlsch_ue_select[CC_id].ue_num; @@ -658,19 +656,22 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, nb_rbs_required_remaining[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], dlsch_ue_select[CC_id].list[i].nb_rb); } - transmission_mode = get_tmode(Mod_id,CC_id,UE_id); + /* slicing support has been introduced into the scheduler. Provide dummy + * data so that the preprocessor "simply works" */ + for (c = 0; c < MAX_NUM_CCs; ++c) + for (j = 0; j < N_RBG_MAX; ++j) + slice_allocation[c][j] = 1; LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n "); dlsch_scheduler_pre_processor_allocate (Mod_id, UE_id, CC_id, N_RBG[CC_id], - transmission_mode, min_rb_unit[CC_id], - N_RB_DL, (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining, rballoc_sub, + slice_allocation, MIMO_mode_indicator); temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id]; temp_total_ue_count--; @@ -787,13 +788,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, // unsigned char aggregation; mac_rlc_status_resp_t rlc_status; unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = - 0, header_len_dtch_last = 0; + unsigned char header_len_dtch = 0, header_len_dtch_tmp = 0, header_len_dtch_last = 0; unsigned char ta_len = 0; unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = - 0, post_padding = 0; + uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = 0, post_padding = 0; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; unsigned char round = 0; unsigned char harq_pid = 0; @@ -818,7 +817,10 @@ schedule_ue_spec_fairRR(module_id_t module_idP, nfapi_dl_config_request_pdu_t *dl_config_pdu; int tdd_sfa; int ta_update; - +#ifdef DEBUG_eNB_SCHEDULER + int k; +#endif + start_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); @@ -1335,8 +1337,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP, "[eNB %d][DCCH] CC_id %d Got %d bytes :", module_idP, CC_id, sdu_lengths[0]); - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); + for (k = 0; k < sdu_lengths[0]; k++) { + LOG_T(MAC, "%x ", dlsch_buffer[k]); } LOG_T(MAC, "\n"); @@ -1389,8 +1391,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", module_idP, CC_id, sdu_lengths[num_sdus]); - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); + for (k = 0; k < sdu_lengths[num_sdus]; k++) { + LOG_T(MAC, "%x ", dlsch_buffer[k]); } LOG_T(MAC, "\n"); @@ -1638,8 +1640,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP, #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n",module_idP ); - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); + for (k = 0; k < 16; k++) { + LOG_T(MAC, "%x.", dlsch_buffer[k]); } LOG_T(MAC, "\n"); @@ -1655,8 +1657,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP, } if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP,UE_id), eNB->frame, eNB->subframe,0,0); LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS); @@ -1696,9 +1698,9 @@ schedule_ue_spec_fairRR(module_id_t module_idP, // this is the normalized RX power eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ - normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; - target_rx_power = 208; + /* Unit is not dBm, it's special from nfapi */ + normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30;//(+eNB->measurements.n0_power_dB[0]) + target_rx_power= eNB->puCch10xSnr/10 + 30;//(+eNB->measurements.n0_power_dB[0]) // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out @@ -2690,9 +2692,25 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, if (status < RRC_CONNECTED) cqi_req = 0; else if (UE_sched_ctrl->cqi_req_timer>30) { - cqi_req = 1; - UE_sched_ctrl->cqi_req_timer=0; - UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; + cqi_req = 1; + // To be safe , do not ask CQI in special SFs:36.213/7.2.3 CQI definition + if (cc->tdd_Config) { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + if( 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->cqi_req_timer=0; + UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; + } } else cqi_req = 0; @@ -2701,8 +2719,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, //compute the expected ULSCH RX power (for the stats) // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; - target_rx_power = 178; + normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; //(+eNB->measurements.n0_power_dB[0]) + target_rx_power= eNB->puSch10xSnr/10 + 30; //(+eNB->measurements.n0_power_dB[0]) // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 63a471177881ab5fafc6cfd71bdecf0825a79265..16953e958a8ffe39ee32593e2a4053f8fb5567f9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -767,7 +767,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, /* Tracing of PDU is done on UE side */ if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xffff, // M_RNTI = 6 in wirehsark RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0); LOG_D(OPT, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c index 49cc68b06a65505bd24db81ed945efa4952978af..81c418c12352ea83d87cbe1aedbf0941df37641b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -202,7 +202,8 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s int32_t normalized_rx_power; int32_t target_rx_power= 178; int CC_id = 0; - int nb_rb = 96; + int nb_rb = 24; + int N_RB_UL; eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc = &mac->common_channels[0]; UE_list_t *UE_list=&mac->UE_list; @@ -211,8 +212,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s int sched_frame=frameP; int sched_subframe = (subframeP+4)%10; uint16_t ul_req_index; - uint8_t dlsch_flag; - + if (sched_subframe<subframeP) sched_frame++; nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id][subframeP]; @@ -222,6 +222,18 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s //nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[0];; nfapi_ul_config_request_body_t *ul_req = &mac->UL_req[CC_id].ul_config_request_body; + N_RB_UL = to_prb(cc->mib->message.dl_Bandwidth); + switch(N_RB_UL){ + case 100: + nb_rb = 96; + break; + case 50: + nb_rb = 48; + break; + case 25: + nb_rb = 24; + break; + } mac->UL_req[CC_id].sfn_sf = (sched_frame<<4) + sched_subframe; hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; @@ -306,10 +318,8 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s hi_dci0_req_body->number_of_dci++; ul_req_index = 0; - dlsch_flag = 0; for(ul_req_index = 0;ul_req_index < ul_req->number_of_pdus;ul_req_index++){ if(ul_req->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){ - 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; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index b85335caab0e95b8a42155078b188fedc243db1d..c9d3d9dbacda4506cac3d8ea568f04899431d40e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -62,8 +62,6 @@ extern uint16_t frame_cnt; extern RAN_CONTEXT_t RC; -extern int n_active_slices; - int choose(int n, int k) { int res = 1; @@ -1157,11 +1155,11 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, } break; case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, + AssertFatal(use_simultaneous_pucch_pusch == 0, "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); break; case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, + AssertFatal(use_simultaneous_pucch_pusch == 1, "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); break; @@ -1853,7 +1851,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) return (rnti); } - LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); + //LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); //display_backtrace(); return (NOT_A_RNTI); } @@ -1963,6 +1961,9 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP sizeof(eNB_UE_STATS)); UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; + /* default slice in case there was something different */ + UE_list->assoc_dl_slice_idx[UE_id] = 0; + UE_list->assoc_ul_slice_idx[UE_id] = 0; UE_list->UE_sched_ctrl[UE_id].ta_update = 31; @@ -4536,19 +4537,31 @@ harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, // Flexran Slicing functions -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) +uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) { return (uint16_t) floor(rb_percentage * total_rbs); } -int ue_slice_membership(int UE_id, int slice_id) +int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx) { - if ((slice_id < 0) || (slice_id > n_active_slices)) - LOG_W(MAC, "out of range slice id %d\n", slice_id); - + if ((slice_idx < 0) + || (slice_idx >= RC.mac[mod_id]->slice_info.n_dl)) { + LOG_W(MAC, "out of range slice index %d (slice ID %d)\n", + slice_idx, RC.mac[mod_id]->slice_info.dl[slice_idx].id); + return 0; + } + return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE + && RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[UE_id] == slice_idx; +} - if ((UE_id % n_active_slices) == slice_id) { - return 1; // this ue is a member of this slice +int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx) +{ + if ((slice_idx < 0) + || (slice_idx >= RC.mac[mod_id]->slice_info.n_ul)) { + LOG_W(MAC, "out of range slice index %d (slice ID %d)\n", + slice_idx, RC.mac[mod_id]->slice_info.dl[slice_idx].id); + return 0; } - return 0; + return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE + && RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[UE_id] == slice_idx; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 04415a838626df5e9f91b59dd599b7d94245faad..31c11e2c0a942fb42d882132644bcc0376ba148d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -63,6 +63,9 @@ #include "T.h" +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 @@ -72,46 +75,14 @@ extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offs extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); extern uint8_t nfapi_mode; -extern uint8_t nfapi_mode; - // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 }; -/* number of active slices for past and current time*/ -int n_active_slices_uplink = 1; -int n_active_slices_current_uplink = 1; - -/* RB share for each slice for past and current time*/ -float avg_slice_percentage_uplink=0.25; -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage_uplink = 0; -float total_slice_percentage_current_uplink = 0; - -// MAX MCS for each slice for past and current time -int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; -int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; - -/*resource blocks allowed*/ -uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; -/*Slice Update */ -int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; -int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; - -/* name of available scheduler*/ -char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti", - "schedule_ulsch_rnti", - "schedule_ulsch_rnti", - "schedule_ulsch_rnti" -}; extern mui_t rrc_eNB_mui; -/* Slice Function Pointer */ -slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; - void rx_sdu(const module_id_t enb_mod_idP, const int CC_idP, @@ -150,7 +121,7 @@ rx_sdu(const module_id_t enb_mod_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); if (opt_enabled == 1) { - trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, + trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0); LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", enb_mod_idP, frameP, current_rnti, sdu_lenP); @@ -432,10 +403,10 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); @@ -466,10 +437,10 @@ rx_sdu(const module_id_t enb_mod_idP, int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); int bsr3 = payload_ptr[2] & 0x3F; - lcgid_updated[0] = 1; - lcgid_updated[1] = 1; - lcgid_updated[2] = 1; - lcgid_updated[3] = 1; + lcgid_updated[LCGID0] = 1; + lcgid_updated[LCGID1] = 1; + lcgid_updated[LCGID2] = 1; + lcgid_updated[LCGID3] = 1; // update buffer info UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; @@ -478,10 +449,10 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; LOG_D(MAC, @@ -951,9 +922,10 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - uint16_t first_rb[MAX_NUM_CCs], i; + uint16_t first_rb[NFAPI_CC_MAX], i; int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; COMMON_channels_t *cc; start_meas(&mac->schedule_ulsch); @@ -1034,12 +1006,10 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, break; } } - if (sched_subframe < subframeP) sched_frame++; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - + if (sched_subframe < subframeP) sched_frame++; + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { //leave out first RB for PUCCH first_rb[CC_id] = 1; @@ -1066,102 +1036,9 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } } - // perform slice-specifc operations - - total_slice_percentage_uplink=0; - avg_slice_percentage_uplink=1.0/n_active_slices_uplink; - - // reset the slice percentage for inactive slices - for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { - slice_percentage_uplink[i]=0; - } - for (i = 0; i < n_active_slices_uplink; i++) { - if (slice_percentage_uplink[i] < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, slice_percentage_uplink[i]); - slice_percentage_uplink[i]=0; - } - total_slice_percentage_uplink+=slice_percentage_uplink[i]; - } - - for (i = 0; i < n_active_slices_uplink; i++) { - - // Load any updated functions - if (update_ul_scheduler[i] > 0 ) { - slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); - update_ul_scheduler[i] = 0; - update_ul_scheduler_current[i] = 0; - //slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; - //total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; - //if (total_slice_percentage_current_uplink> 1) - //total_slice_percentage_current_uplink=1; - LOG_I(MAC,"update ul scheduler slice %d\n", i); - } - // the new total RB share is within the range - if (total_slice_percentage_uplink <= 1.0){ - - // check if the number of slices has changed, and log - if (n_active_slices_current_uplink != n_active_slices_uplink ){ - if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { - LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, n_active_slices_current_uplink, n_active_slices_uplink); - n_active_slices_current_uplink = n_active_slices_uplink; - } else { - LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n", - n_active_slices_uplink, n_active_slices_current_uplink); - n_active_slices_uplink = n_active_slices_current_uplink; - } - } - - // check if the slice rb share has changed, and log the console - if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ - LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, total_slice_percentage_current_uplink, - total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); - total_slice_percentage_current_uplink = total_slice_percentage_uplink; - slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; - } - - // check if the slice max MCS, and log the console - if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ - if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ - LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); - slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n", - module_idP, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); - slice_maxmcs_uplink[i] = slice_maxmcs_current_uplink[i]; - } - } - - // check if a new scheduler, and log the console - if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ - LOG_I(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", - module_idP, i, frameP, subframeP, ul_scheduler_type[i]); - update_ul_scheduler_current[i] = update_ul_scheduler[i]; - } - } else { - if (n_active_slices_uplink == n_active_slices_current_uplink) { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - module_idP, i, total_slice_percentage_current_uplink, total_slice_percentage_uplink); - if (slice_percentage_uplink[i] > avg_slice_percentage_uplink) { - slice_percentage_uplink[i] -= 0.1; - total_slice_percentage_uplink -= 0.1; - } - } else { - // here we can correct the values, e.g. reduce proportionally - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - module_idP, i, total_slice_percentage_current_uplink, - total_slice_percentage_uplink, n_active_slices_uplink, - n_active_slices_current_uplink); - n_active_slices_uplink = n_active_slices_current_uplink; - slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; - } - } - + for (i = 0; i < sli->n_ul; i++) { // Run each enabled slice-specific schedulers one by one - slice_sched_ul[i](module_idP, i, frameP, subframeP, sched_subframe, first_rb); + sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); } stop_meas(&mac->schedule_ulsch); @@ -1169,7 +1046,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, void schedule_ulsch_rnti(module_id_t module_idP, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb) @@ -1191,12 +1068,14 @@ schedule_ulsch_rnti(module_id_t module_idP, eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc = mac->common_channels; UE_list_t *UE_list = &mac->UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_TEMPLATE *UE_template; UE_sched_ctrl *UE_sched_ctrl; int sched_frame = frameP; int rvidx_tab[4] = { 0, 2, 3, 1 }; uint16_t ul_req_index; uint8_t dlsch_flag; + int first_rb_slice[NFAPI_CC_MAX]; if (sched_subframeP < subframeP) sched_frame++; @@ -1208,9 +1087,18 @@ schedule_ulsch_rnti(module_id_t module_idP, 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; + + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { + N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + UE_list->first_rb_offset[CC_id][slice_idx] = cmin(N_RB_UL, sli->ul[slice_idx].first_rb); + } + //LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, sched_subframeP, first_rb); + ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, 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]; + } //LOG_D(MAC, "exiting ulsch preprocesor\n"); hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; @@ -1219,7 +1107,7 @@ schedule_ulsch_rnti(module_id_t module_idP, for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - if (!ue_slice_membership(UE_id, slice_id)) + if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) continue; // don't schedule if Msg4 is not received yet @@ -1296,7 +1184,7 @@ schedule_ulsch_rnti(module_id_t module_idP, } /* be sure that there are some free RBs */ - if (first_rb[CC_id] >= N_RB_UL - 1) { + if (first_rb_slice[CC_id] >= N_RB_UL - 1) { 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); @@ -1337,10 +1225,24 @@ schedule_ulsch_rnti(module_id_t module_idP, if (status >= RRC_CONNECTED && UE_sched_ctrl->cqi_req_timer > 30) { if (UE_sched_ctrl->cqi_received == 0) { if (nfapi_mode) { - cqi_req = 0; + cqi_req = 0; } else { - cqi_req = 1; - UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; + cqi_req = 1; + // 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->cqi_req_flag |= 1 << sched_subframeP; } } else if (UE_sched_ctrl->cqi_received == 1) { @@ -1393,7 +1295,7 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_template->oldNDI_UL[harq_pid] = ndi; UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; - UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]); + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS if (UE_template->pre_allocated_rb_table_index_ul >= 0) { @@ -1407,7 +1309,7 @@ schedule_ulsch_rnti(module_id_t module_idP, // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb[CC_id])) + while (((rb_table[rb_table_index] > (N_RB_UL - first_rb_slice[CC_id])) || (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) { rb_table_index--; @@ -1424,7 +1326,7 @@ schedule_ulsch_rnti(module_id_t module_idP, T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), + T_INT(first_rb_slice[CC_id]), T_INT(rb_table[rb_table_index]), T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); @@ -1434,14 +1336,14 @@ schedule_ulsch_rnti(module_id_t module_idP, module_idP, harq_pid, rnti, CC_id, frameP, subframeP, UE_id, UE_template->mcs_UL[harq_pid], - first_rb[CC_id], rb_table[rb_table_index], + first_rb_slice[CC_id], rb_table[rb_table_index], rb_table_index, UE_template->TBS_UL[harq_pid], harq_pid); // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) //store for possible retransmission UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + UE_template->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); if (UE_id == UE_list->head) @@ -1473,7 +1375,7 @@ schedule_ulsch_rnti(module_id_t module_idP, 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[CC_id]; + 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->mcs_UL[harq_pid]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; @@ -1500,7 +1402,8 @@ schedule_ulsch_rnti(module_id_t module_idP, 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){ + 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; @@ -1508,7 +1411,7 @@ schedule_ulsch_rnti(module_id_t module_idP, } // 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->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->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->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms 0, // frequency_hopping_enabled_flag @@ -1571,13 +1474,13 @@ schedule_ulsch_rnti(module_id_t module_idP, 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,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); // increment first rb for next UE allocation - first_rb[CC_id] += rb_table[rb_table_index]; + first_rb_slice[CC_id] += rb_table[rb_table_index]; } else { // round > 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->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), + T_INT(first_rb_slice[CC_id]), T_INT(rb_table[rb_table_index]), T_INT(round)); // Add UL_config PDUs @@ -1588,7 +1491,8 @@ schedule_ulsch_rnti(module_id_t module_idP, 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){ + 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; diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index d9e914f087009858a77e323fb2c3597609ca3d38..ed6171dcebfaa35f74e608f7a86c0d6d1ce3c187 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -159,7 +159,7 @@ #define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE) /*!\brief maximum number of slices / groups */ -#define MAX_NUM_SLICES 4 +#define MAX_NUM_SLICES 10 #define U_PLANE_INACTIVITY_VALUE 6000 @@ -442,7 +442,7 @@ typedef struct { /*!\brief LCID of MCCH for DL */ #define MCCH_LCHANID 0 /*!\brief LCID of MCH scheduling info for DL */ -#define MCH_SCHDL_INFO 3 +#define MCH_SCHDL_INFO 30 /*!\brief LCID of Carrier component activation/deactivation */ #define CC_ACT_DEACT 27 //TTN (for D2D) @@ -849,6 +849,9 @@ typedef struct { /// LCGID mapping long lcgidmap[11]; + ///UE logical channel priority + long lcgidpriority[11]; + /// phr information int8_t phr_info; @@ -1099,6 +1102,10 @@ typedef struct { /// Sorting criteria for the UE list in the MAC preprocessor uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; + uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES]; + + int assoc_dl_slice_idx[MAX_MOBILES_PER_ENB]; + int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB]; } UE_list_t; @@ -1118,6 +1125,117 @@ typedef struct { int tail_freelist; ///the tail position of the delete list } UE_free_list_t; +/// Structure for saving the output of each pre_processor instance +typedef struct { + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; + + uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID]; + uint32_t wb_pmi[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint8_t mcs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + +} pre_processor_results_t; + +/** + * slice specific scheduler for the DL + */ +typedef void (*slice_scheduler_dl)(module_id_t mod_id, + int slice_idx, + frame_t frame, + sub_frame_t subframe, + int *mbsfn_flag); + +typedef struct { + slice_id_t id; + + /// RB share for each slice + float pct; + + /// whether this slice is isolated from the others + int isol; + + int prio; + + /// Frequency ranges for slice positioning + int pos_low; + int pos_high; + + // max mcs for each slice + int maxmcs; + + /// criteria for sorting policies of the slices + uint32_t sorting; + + /// Accounting policy (just greedy(1) or fair(0) setting for now) + int accounting; + + /// name of available scheduler + char *sched_name; + + /// pointer to the slice specific scheduler in DL + slice_scheduler_dl sched_cb; + +} slice_sched_conf_dl_t; + +typedef void (*slice_scheduler_ul)(module_id_t mod_id, + int slice_idx, + frame_t frame, + sub_frame_t subframe, + unsigned char sched_subframe, + uint16_t *first_rb); + +typedef struct { + slice_id_t id; + + /// RB share for each slice + float pct; + + // MAX MCS for each slice + int maxmcs; + + /// criteria for sorting policies of the slices + uint32_t sorting; + + /// starting RB (RB offset) of UL scheduling + int first_rb; + + /// name of available scheduler + char *sched_name; + + /// pointer to the slice specific scheduler in UL + slice_scheduler_ul sched_cb; + +} slice_sched_conf_ul_t; + + +typedef struct { + /// counter used to indicate when all slices have pre-allocated UEs + //int slice_counter; + + /// indicates whether remaining RBs after first intra-slice allocation will + /// be allocated to UEs of the same slice + int intraslice_share_active; + /// indicates whether remaining RBs after slice allocation will be + /// allocated to UEs of another slice. Isolated slices will be ignored + int interslice_share_active; + + /// number of active DL slices + int n_dl; + slice_sched_conf_dl_t dl[MAX_NUM_SLICES]; + + /// number of active UL slices + int n_ul; + slice_sched_conf_ul_t ul[MAX_NUM_SLICES]; + + pre_processor_results_t pre_processor_results[MAX_NUM_SLICES]; + + /// common rb allocation list between slices + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; +} slice_info_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1238,7 +1356,10 @@ typedef struct eNB_MAC_INST_s { /// UL handle uint32_t ul_handle; UE_list_t UE_list; - + + /// slice-related configuration + slice_info_t slice_info; + ///subband bitmap configuration SBMAP_CONF sbmap_conf; /// CCE table used to build DCI scheduling information @@ -1502,7 +1623,16 @@ typedef struct { /// MCCH status uint8_t mcch_status; /// MSI status - uint8_t msi_status; // could be an array if there are >1 MCH in one MBSFN area + uint8_t msi_status_v[28]; + uint8_t msi_current_alloc; + uint8_t msi_pmch; + + struct MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? + uint8_t commonSF_AllocPeriod_r9; + int common_num_sf_alloc; + + uint8_t pmch_lcids[28]; + uint16_t pmch_stop_mtch[28]; #endif //#ifdef CBA /// CBA RNTI for each group diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index aba8c26d92042d55bfb8dcc0393d703f2e7a4323..e0fdade419fab0907c807d392cbb7f3070522ac7 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -36,22 +36,6 @@ * @{ */ -/** - * slice specific scheduler - */ -typedef void (*slice_scheduler_dl)(module_id_t mod_id, - slice_id_t slice_id, - frame_t frame, - sub_frame_t subframe, - int *mbsfn_flag); - -typedef void (*slice_scheduler_ul)(module_id_t mod_id, - slice_id_t slice_id, - frame_t frame, - sub_frame_t subframe, - unsigned char sched_subframe, - uint16_t *first_rb); - /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. @param Mod_id Instance ID of eNB @@ -119,12 +103,12 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, /** \brief ULSCH Scheduling per RNTI @param Mod_id Instance ID of eNB -@param slice_id Instance slice for this eNB +@param slice_idx Slice instance index for this eNB @param frame Frame index @param subframe Subframe number on which to act @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup) */ -void schedule_ulsch_rnti(module_id_t module_idP, slice_id_t slice_idP, frame_t frameP, +void schedule_ulsch_rnti(module_id_t module_idP, int slice_idx, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint16_t * first_rb); @@ -147,7 +131,7 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,i void schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); -void schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, +void schedule_ue_spec(module_id_t module_idP, int slice_idxP, frame_t frameP,sub_frame_t subframe, int *mbsfn_flag); void schedule_ue_spec_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag); @@ -181,6 +165,10 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, //main.c +void init_UE_list(UE_list_t *UE_list); + +void init_slice_info(slice_info_t *sli); + int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); @@ -204,24 +192,11 @@ void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, frame_t frameP, sub_frame_t subframeP); -void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t - nb_rbs_required[NFAPI_CC_MAX] - [MAX_MOBILES_PER_ENB], - unsigned char - rballoc_sub[NFAPI_CC_MAX] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[NFAPI_CC_MAX] - [N_RBG_MAX]); // eNB functions /* \brief This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done @param Mod_id Instance ID of eNB +@param slice_idxP Slice instance index for the slice in which scheduling happens @param frame Index of frame @param subframe Index of current subframe @param N_RBS Number of resource block groups @@ -229,24 +204,73 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, void dlsch_scheduler_pre_processor(module_id_t module_idP, - slice_id_t slice_idP, - frame_t frameP, - sub_frame_t subframe, - int N_RBG[NFAPI_CC_MAX], - int *mbsfn_flag); - + int slice_idxP, + frame_t frameP, + sub_frame_t subframe, + int *mbsfn_flag, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]); + +void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + int *mbsfn_flag); + +void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, + int slice_idx, + const uint8_t rbs_retx[NFAPI_CC_MAX]); + +void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]); + +void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, + int slice_idx, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); + +void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, + int slice_idx, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); + +void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]); + +void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]); + +void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP); void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); + int UE_id, + uint8_t CC_id, + int N_RBG, + int min_rb_unit, + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. @@ -676,8 +700,8 @@ int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti, int harq_pid ); int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP); -void store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP); -void assign_rbs_required(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]); +void store_dlsch_buffer(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP); +void assign_rbs_required(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]); int maxround(module_id_t Mod_id, uint16_t rnti, int frame, sub_frame_t subframe, uint8_t ul_flag); @@ -696,20 +720,20 @@ void set_ul_DAI(int module_idP, int frameP, int subframeP); -void ulsch_scheduler_pre_processor(module_id_t module_idP, slice_id_t slice_id, int frameP, +void ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb); void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP); void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP); -void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, +void assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, uint16_t * first_rb); void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE * UE_template); int phy_stats_exist(module_id_t Mod_id, int rnti); -void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP); +void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subframeP); /*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index) \brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures. @@ -1244,9 +1268,9 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, #endif /*Slice related functions */ -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); - -int ue_slice_membership(int UE_id, int slice_id); +uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); +int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); +int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); /* 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); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index da2d9778757985b6b001d526a590733391a397fe..8fb8d44e0abc80301bb20f566162f7b206e45ac6 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -29,6 +29,7 @@ */ +#include <dlfcn.h> #include "mac.h" #include "mac_proto.h" #include "mac_extern.h" @@ -45,96 +46,113 @@ extern RAN_CONTEXT_t RC; - -void mac_top_init_eNB(void) +void init_UE_list(UE_list_t *UE_list) { + int list_el; + UE_list->num_UEs = 0; + UE_list->head = -1; + UE_list->head_ul = -1; + UE_list->avail = 0; + for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { + UE_list->next[list_el] = list_el + 1; + UE_list->next_ul[list_el] = list_el + 1; + } + UE_list->next[list_el] = -1; + UE_list->next_ul[list_el] = -1; + memset(UE_list->DLSCH_pdu, 0, sizeof(UE_list->DLSCH_pdu)); + memset(UE_list->UE_template, 0, sizeof(UE_list->UE_template)); + memset(UE_list->eNB_UE_stats, 0, sizeof(UE_list->eNB_UE_stats)); + memset(UE_list->UE_sched_ctrl, 0, sizeof(UE_list->UE_sched_ctrl)); + memset(UE_list->active, 0, sizeof(UE_list->active)); + memset(UE_list->assoc_dl_slice_idx, 0, sizeof(UE_list->assoc_dl_slice_idx)); + memset(UE_list->assoc_ul_slice_idx, 0, sizeof(UE_list->assoc_ul_slice_idx)); +} - module_id_t i, j; - int list_el; - UE_list_t *UE_list; - eNB_MAC_INST *mac; - - LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", - RC.nb_macrlc_inst); +void init_slice_info(slice_info_t *sli) +{ + sli->intraslice_share_active = 1; + sli->interslice_share_active = 1; + + sli->n_dl = 1; + memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); + sli->dl[0].pct = 1.0; + sli->dl[0].prio = 10; + sli->dl[0].pos_high = N_RBG_MAX; + sli->dl[0].maxmcs = 28; + sli->dl[0].sorting = 0x012345; + sli->dl[0].sched_name = "schedule_ue_spec"; + sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); + AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); + + sli->n_ul = 1; + memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); + sli->ul[0].pct = 1.0; + sli->ul[0].maxmcs = 20; + sli->ul[0].sorting = 0x0123; + sli->ul[0].sched_name = "schedule_ulsch_rnti"; + sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); + AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); +} - if (RC.nb_macrlc_inst > 0) { - if (RC.mac == NULL){ - RC.mac = - (eNB_MAC_INST **) malloc16(RC.nb_macrlc_inst * - sizeof(eNB_MAC_INST *)); - bzero(RC.mac, RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *)); - } - AssertFatal(RC.mac != NULL, - "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", - RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), - RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); - for (i = 0; i < RC.nb_macrlc_inst; i++) { - if (RC.mac[i] == NULL) { - RC.mac[i] = (eNB_MAC_INST *) malloc16(sizeof(eNB_MAC_INST)); - AssertFatal(RC.mac[i] != NULL, - "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", - RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), - RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); - LOG_D(MAC, - "[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n", - sizeof(eNB_MAC_INST), RC.nb_macrlc_inst, RC.mac); - bzero(RC.mac[i], sizeof(eNB_MAC_INST)); - } - RC.mac[i]->Mod_id = i; - for (j = 0; j < MAX_NUM_CCs; j++) { - RC.mac[i]->DL_req[j].dl_config_request_body. - dl_config_pdu_list = RC.mac[i]->dl_config_pdu_list[j]; - RC.mac[i]->UL_req[j].ul_config_request_body. - ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list[j]; - for (int k = 0; k < 10; k++) - RC.mac[i]->UL_req_tmp[j][k]. - ul_config_request_body.ul_config_pdu_list = - RC.mac[i]->ul_config_pdu_list_tmp[j][k]; - for(int sf=0;sf<10;sf++){ - RC.mac[i]->HI_DCI0_req[j][sf].hi_dci0_request_body.hi_dci0_pdu_list =RC.mac[i]->hi_dci0_pdu_list[j][sf]; - } - - RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list = - RC.mac[i]->tx_request_pdu[j]; - RC.mac[i]->ul_handle = 0; - } - } - - AssertFatal(rlc_module_init() == 0, - "Could not initialize RLC layer\n"); - - // These should be out of here later - pdcp_layer_init(); - - rrc_init_global_param(); - - } else { - RC.mac = NULL; +void mac_top_init_eNB(void) +{ + module_id_t i, j; + eNB_MAC_INST **mac; + + LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n", + RC.nb_macrlc_inst); + + if (RC.nb_macrlc_inst <= 0) { + RC.mac = NULL; + return; + } + + mac = malloc16(RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *)); + AssertFatal(mac != NULL, + "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", + RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), + RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); + for (i = 0; i < RC.nb_macrlc_inst; i++) { + mac[i] = malloc16(sizeof(eNB_MAC_INST)); + AssertFatal(mac[i] != NULL, + "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", + RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *), + RC.nb_macrlc_inst, sizeof(eNB_MAC_INST)); + LOG_D(MAC, + "[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n", + sizeof(eNB_MAC_INST), RC.nb_macrlc_inst, mac); + bzero(mac[i], sizeof(eNB_MAC_INST)); + mac[i]->Mod_id = i; + for (j = 0; j < MAX_NUM_CCs; j++) { + mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = + mac[i]->dl_config_pdu_list[j]; + mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = + mac[i]->ul_config_pdu_list[j]; + for (int k = 0; k < 10; k++) + mac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list = + mac[i]->ul_config_pdu_list_tmp[j][k]; + for(int sf=0;sf<10;sf++) + mac[i]->HI_DCI0_req[j][sf].hi_dci0_request_body.hi_dci0_pdu_list = + mac[i]->hi_dci0_pdu_list[j][sf]; + mac[i]->TX_req[j].tx_request_body.tx_pdu_list = mac[i]->tx_request_pdu[j]; + mac[i]->ul_handle = 0; } - // Initialize Linked-List for Active UEs - for (i = 0; i < RC.nb_macrlc_inst; i++) { - mac = RC.mac[i]; + mac[i]->if_inst = IF_Module_init(i); + init_UE_list(&mac[i]->UE_list); + init_slice_info(&mac[i]->slice_info); + } - mac->if_inst = IF_Module_init(i); + RC.mac = mac; - UE_list = &mac->UE_list; + AssertFatal(rlc_module_init() == 0, + "Could not initialize RLC layer\n"); - UE_list->num_UEs = 0; - UE_list->head = -1; - UE_list->head_ul = -1; - UE_list->avail = 0; - - for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) { - UE_list->next[list_el] = list_el + 1; - UE_list->next_ul[list_el] = list_el + 1; - } - - UE_list->next[list_el] = -1; - UE_list->next_ul[list_el] = -1; - } + // These should be out of here later + pdcp_layer_init(); + rrc_init_global_param(); } void mac_init_cell_params(int Mod_idP, int CC_idP) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 16cbd3fc19cbfb26e811451e831ca606ff8880f3..5846720c7f71a357a338631110853e708d33e4e7 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -54,14 +54,6 @@ extern RAN_CONTEXT_t RC; #define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 -extern float slice_percentage[MAX_NUM_SLICES]; -extern float slice_percentage_uplink[MAX_NUM_SLICES]; -extern uint32_t sorting_policy[MAX_NUM_SLICES]; - -extern int slice_maxmcs[MAX_NUM_SLICES]; -extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; - - //#define ICIC 0 /* this function checks that get_eNB_UE_stats returns @@ -95,290 +87,280 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) // This function stores the downlink buffer for all the logical channels void -store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, - sub_frame_t subframeP) -{ - - int UE_id, i; - rnti_t rnti; - mac_rlc_status_resp_t rlc_status; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_TEMPLATE *UE_template; +store_dlsch_buffer(module_id_t Mod_id, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP) { - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; + int UE_id, lcid; + rnti_t rnti; + mac_rlc_status_resp_t rlc_status; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_TEMPLATE *UE_template; - if (!ue_slice_membership(UE_id, slice_id)) + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id] != TRUE) continue; - UE_template = - &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) + continue; - // clear logical channel interface variables - UE_template->dl_buffer_total = 0; - UE_template->dl_pdus_total = 0; + UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; - for (i = 0; i < MAX_NUM_LCID; i++) { - UE_template->dl_buffer_info[i] = 0; - UE_template->dl_pdus_in_buffer[i] = 0; - UE_template->dl_buffer_head_sdu_creation_time[i] = 0; - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; - } + // clear logical channel interface variables + UE_template->dl_buffer_total = 0; + UE_template->dl_pdus_total = 0; + for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) { + UE_template->dl_buffer_info[lcid] = 0; + UE_template->dl_pdus_in_buffer[lcid] = 0; + UE_template->dl_buffer_head_sdu_creation_time[lcid] = 0; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = 0; + } - rnti = UE_RNTI(Mod_id, UE_id); + rnti = UE_RNTI(Mod_id, UE_id); - for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels + for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) { // loop over all the logical channels - rlc_status = - mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, - ENB_FLAG_YES, MBMS_FLAG_NO, i, 0 + rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, + ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); - - UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; - UE_template->dl_buffer_head_sdu_creation_time[i] = - rlc_status.head_sdu_creation_time; - UE_template->dl_buffer_head_sdu_creation_time_max = - cmax(UE_template->dl_buffer_head_sdu_creation_time_max, - rlc_status.head_sdu_creation_time); - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = - rlc_status.head_sdu_remaining_size_to_send; - UE_template->dl_buffer_head_sdu_is_segmented[i] = - rlc_status.head_sdu_is_segmented; - UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer - UE_template->dl_pdus_total += - UE_template->dl_pdus_in_buffer[i]; + UE_template->dl_buffer_info[lcid] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel + UE_template->dl_pdus_in_buffer[lcid] = rlc_status.pdus_in_buffer; + UE_template->dl_buffer_head_sdu_creation_time[lcid] = rlc_status.head_sdu_creation_time; + UE_template->dl_buffer_head_sdu_creation_time_max = + cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time); + UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = rlc_status.head_sdu_remaining_size_to_send; + UE_template->dl_buffer_head_sdu_is_segmented[lcid] = rlc_status.head_sdu_is_segmented; + UE_template->dl_buffer_total += UE_template->dl_buffer_info[lcid]; //storing the total dlsch buffer + UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[lcid]; #ifdef DEBUG_eNB_SCHEDULER - /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : - * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent - */ - if (UE_template->dl_buffer_info[i] > 0) - LOG_D(MAC, - "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, slice_id, frameP, subframeP, UE_id, - i, UE_template->dl_pdus_in_buffer[i], - UE_template->dl_buffer_info[i], - UE_template->dl_buffer_head_sdu_creation_time[i], - UE_template-> - dl_buffer_head_sdu_remaining_size_to_send[i], - UE_template->dl_buffer_head_sdu_is_segmented[i]); + /* note for dl_buffer_head_sdu_remaining_size_to_send[lcid] : + * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent + */ + if (UE_template->dl_buffer_info[lcid] > 0) + LOG_D(MAC, + "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", + Mod_id, RC.mac[Mod_id]->slice_info.dl[slice_idx].id, frameP, + subframeP, UE_id, lcid, UE_template->dl_pdus_in_buffer[lcid], + UE_template->dl_buffer_info[lcid], + UE_template->dl_buffer_head_sdu_creation_time[lcid], + UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid], + UE_template->dl_buffer_head_sdu_is_segmented[lcid]); #endif - } - - //#ifdef DEBUG_eNB_SCHEDULER - if (UE_template->dl_buffer_total > 0) - LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", - Mod_id, frameP, subframeP, UE_id, - UE_template->dl_buffer_total, - UE_template->dl_pdus_total); - //#endif } + + if (UE_template->dl_buffer_total > 0) + LOG_D(MAC, + "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", + Mod_id, frameP, subframeP, UE_id, + UE_template->dl_buffer_total, + UE_template->dl_pdus_total); + } } +int cqi2mcs(int cqi) { + return cqi_to_mcs[cqi]; +} // This function returns the estimated number of RBs required by each UE for downlink scheduling void assign_rbs_required(module_id_t Mod_id, - slice_id_t slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t - nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - int min_rb_unit[NFAPI_CC_MAX]) + int slice_idx, + frame_t frameP, + sub_frame_t subframe, + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + int min_rb_unit[NFAPI_CC_MAX]) { - uint16_t TBS = 0; + uint16_t TBS = 0; - int UE_id, n, i, j, CC_id, pCCid, tmp; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; - int N_RB_DL; + int UE_id, n, i, j, CC_id, pCCid, tmp; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; + int N_RB_DL; - // clear rb allocations across all CC_id - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - pCCid = UE_PCCID(Mod_id, UE_id); - - //update CQI information across component carriers - for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - CC_id = UE_list->ordered_CCids[n][UE_id]; - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - - eNB_UE_stats->dlsch_mcs1 =cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], - slice_maxmcs[slice_id]); - - } - - // provide the list of CCs sorted according to MCS - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - eNB_UE_stats_i = - &UE_list->eNB_UE_stats[UE_list-> - ordered_CCids[i][UE_id]][UE_id]; - for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { - DevAssert(j < NFAPI_CC_MAX); - eNB_UE_stats_j = - &UE_list-> - eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; - if (eNB_UE_stats_j->dlsch_mcs1 > - eNB_UE_stats_i->dlsch_mcs1) { - tmp = UE_list->ordered_CCids[i][UE_id]; - UE_list->ordered_CCids[i][UE_id] = - UE_list->ordered_CCids[j][UE_id]; - UE_list->ordered_CCids[j][UE_id] = tmp; - } - } - } - - if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) { - LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id); - - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - CC_id = UE_list->ordered_CCids[i][UE_id]; - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - - if (eNB_UE_stats->dlsch_mcs1 == 0) { - nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small - } else { - nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; - } - - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_rbs_required[CC_id][UE_id]); - - LOG_D(MAC, - "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", - UE_id, CC_id, - UE_list->UE_template[pCCid][UE_id].dl_buffer_total, - nb_rbs_required[CC_id][UE_id], - eNB_UE_stats->dlsch_mcs1, TBS); - - N_RB_DL = - to_prb(RC.mac[Mod_id]->common_channels[CC_id]. - mib->message.dl_Bandwidth); - - UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); - - /* calculating required number of RBs for each UE */ - while (TBS < - UE_list->UE_template[pCCid][UE_id]. - dl_buffer_total) { - nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - - if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); - nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; - break; - } - - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_rbs_required[CC_id][UE_id]); - } // end of while - - LOG_D(MAC, - "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", - Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id], - nb_rbs_required[CC_id][UE_id], TBS, - eNB_UE_stats->dlsch_mcs1); - } - } + // clear rb allocations across all CC_id + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id] != TRUE) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; + pCCid = UE_PCCID(Mod_id, UE_id); + + //update CQI information across component carriers + for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { + + CC_id = UE_list->ordered_CCids[n][UE_id]; + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; +// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_idx].maxmcs); + eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_idx].maxmcs); + + } + + // provide the list of CCs sorted according to MCS + for (i = 0; i < UE_list->numactiveCCs[UE_id]; ++i) { + eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id]; + for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { + DevAssert(j < NFAPI_CC_MAX); + eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; + if (eNB_UE_stats_j->dlsch_mcs1 > eNB_UE_stats_i->dlsch_mcs1) { + tmp = UE_list->ordered_CCids[i][UE_id]; + UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id]; + UE_list->ordered_CCids[j][UE_id] = tmp; + } + } + } + + if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) { + LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id); + + for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + + if (eNB_UE_stats->dlsch_mcs1 == 0) { + nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small + } else { + nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; + } + + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); + + LOG_D(MAC, + "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", + UE_id, CC_id, + UE_list->UE_template[pCCid][UE_id].dl_buffer_total, + nb_rbs_required[CC_id][UE_id], + eNB_UE_stats->dlsch_mcs1, TBS); + + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + + UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->dl[slice_idx].pct, N_RB_DL); + + /* calculating required number of RBs for each UE */ + while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { + nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; + + if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]) { + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]); + nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]; + break; + } + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); + } // end of while + + LOG_D(MAC, + "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", + Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id], + nb_rbs_required[CC_id][UE_id], TBS, + eNB_UE_stats->dlsch_mcs1); + + sli->pre_processor_results[slice_idx].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; + } } + } } // This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes - int maxround(module_id_t Mod_id, uint16_t rnti, int frame, - sub_frame_t subframe, uint8_t ul_flag) -{ - - uint8_t round, round_max = 0, UE_id; - int CC_id, harq_pid; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - COMMON_channels_t *cc; + sub_frame_t subframe, uint8_t ul_flag) { - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - - cc = &RC.mac[Mod_id]->common_channels[CC_id]; + uint8_t round, round_max = 0, UE_id; + int CC_id, harq_pid; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + COMMON_channels_t *cc; - UE_id = find_UE_id(Mod_id, rnti); + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + cc = &RC.mac[Mod_id]->common_channels[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe); + UE_id = find_UE_id(Mod_id, rnti); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe); - round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; - if (round > round_max) { - round_max = round; - } + round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; + if (round > round_max) { + round_max = round; } + } - return round_max; + return round_max; } // This function scans all CC_ids for a particular UE to find the maximum DL CQI // it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL) -int maxcqi(module_id_t Mod_id, int32_t UE_id) -{ - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - int CC_id, n; - int CQI = 0; +int maxcqi(module_id_t Mod_id, int32_t UE_id) { + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int CC_id, n; + int CQI = 0; - for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - CC_id = UE_list->ordered_CCids[n][UE_id]; + for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { + CC_id = UE_list->ordered_CCids[n][UE_id]; - if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) { - CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; - } + if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) { + CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; } + } + + return CQI; +} + +long min_lcgidpriority(module_id_t Mod_id, int32_t UE_id) { + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int i; + int pCC_id = UE_PCCID(Mod_id, UE_id); + long ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[0]; + + for (i = 1; i < 11; ++i) { + if (UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i] < ret) + ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i]; + } - return CQI; + return ret; } struct sort_ue_dl_params { int Mod_idP; int frameP; int subframeP; - int slice_id; + int slice_idx; }; static int ue_dl_compare(const void *_a, const void *_b, void *_params) { - struct sort_ue_dl_params *params = _params; - UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; + struct sort_ue_dl_params *params = _params; + UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; - int i; - int slice_id = params->slice_id; - int UE_id1 = *(const int *) _a; - int UE_id2 = *(const int *) _b; + int i; + int slice_idx = params->slice_idx; + int UE_id1 = *(const int *) _a; + int UE_id2 = *(const int *) _b; - int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); - int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); - int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); + int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); + int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); + int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); - int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); - int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); - int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); + int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); + int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); + int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); - int cqi1 = maxcqi(params->Mod_idP, UE_id1); - int cqi2 = maxcqi(params->Mod_idP, UE_id2); + int cqi1 = maxcqi(params->Mod_idP, UE_id1); + int cqi2 = maxcqi(params->Mod_idP, UE_id2); + + long lcgid1 = min_lcgidpriority(params->Mod_idP, UE_id1); + long lcgid2 = min_lcgidpriority(params->Mod_idP, UE_id2); for (i = 0; i < CR_NUM; ++i) { - switch (UE_list->sorting_criteria[slice_id][i]) { + switch (UE_list->sorting_criteria[slice_idx][i]) { case CR_ROUND : if (round1 > round2) @@ -423,6 +405,13 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) return -1; if (cqi1 < cqi2) return 1; + break; + + case CR_LCP : + if (lcgid1 < lcgid2) + return -1; + if (lcgid1 > lcgid2) + return 1; default : break; @@ -432,190 +421,272 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) return 0; } -void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { - int i; +void decode_sorting_policy(module_id_t Mod_idP, int slice_idx) { + int i; - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - uint32_t policy = sorting_policy[slice_id]; - uint32_t mask = 0x0000000F; - uint16_t criterion; + UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting; + uint32_t mask = 0x0000000F; + uint16_t criterion; - for(i = 0; i < CR_NUM; ++i) { - criterion = (uint16_t)(policy >> 4*(CR_NUM - 1 - i) & mask); - if (criterion >= CR_NUM) { - LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); - sorting_policy[slice_id] = 0x1234; - break; - } - UE_list->sorting_criteria[slice_id][i] = criterion; - } + for (i = 0; i < CR_NUM; ++i) { + criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); + if (criterion >= CR_NUM) { + LOG_W(MAC, + "Invalid criterion in slice index %d ID %d policy, revert to default policy \n", + slice_idx, RC.mac[Mod_idP]->slice_info.dl[slice_idx].id); + RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting = 0x12345; + break; + } + UE_list->sorting_criteria[slice_idx][i] = criterion; + } +} + +void decode_slice_positioning(module_id_t Mod_idP, + int slice_idx, + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) +{ + uint8_t CC_id; + int RBG, start_frequency, end_frequency; + + // Init slice_alloc_mask + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) { + for (RBG = 0; RBG < N_RBG_MAX; ++RBG) { + slice_allocation_mask[CC_id][RBG] = 0; + } + } + + start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_low; + end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_high; + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) { + for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { + slice_allocation_mask[CC_id][RBG] = 1; + } + } } // This fuction sorts the UE in order their dlsch buffer and CQI -void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) +void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subframeP) { - int i; - int list[MAX_MOBILES_PER_ENB]; - int list_size = 0; - int rnti; - struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP, slice_id }; + int i; + int list[MAX_MOBILES_PER_ENB]; + int list_size = 0; + struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx}; - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + + if (UE_list->active[i] == FALSE) continue; + if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_idP, i, slice_idx)) continue; + + list[list_size] = i; + list_size++; + } + + decode_sorting_policy(Mod_idP, slice_idx); + + qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); - if (UE_list->active[i] == FALSE) - continue; - if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) - continue; - if (!ue_slice_membership(i, slice_id)) - continue; + if (list_size) { + for (i = 0; i < list_size - 1; ++i) + UE_list->next[list[i]] = list[i + 1]; + UE_list->next[list[list_size - 1]] = -1; + UE_list->head = list[0]; + } else { + UE_list->head = -1; + } +} + +void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, + int slice_idx, + const uint8_t rbs_retx[NFAPI_CC_MAX]) +{ + int UE_id, CC_id, N_RB_DL, i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + uint16_t available_rbs; - list[list_size] = i; - list_size++; - } + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - decode_sorting_policy(Mod_idP, slice_id); + if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; - qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if (list_size) { - for (i = 0; i < list_size - 1; i++) - UE_list->next[list[i]] = list[i + 1]; - UE_list->next[list[list_size - 1]] = -1; - UE_list->head = list[0]; - } else { - UE_list->head = -1; - } + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_idx].pct, N_RB_DL); + if (rbs_retx[CC_id] < available_rbs) + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = available_rbs - rbs_retx[CC_id]; + else + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = 0; + } + } } void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, - int N_RBG[NFAPI_CC_MAX], int min_rb_unit[NFAPI_CC_MAX], - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { - - + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) +{ int UE_id, CC_id; - int ii, r1; + int i; rnti_t rnti; - uint8_t harq_pid, round, transmission_mode; - uint8_t total_rbs_used[NFAPI_CC_MAX]; - uint8_t total_ue_count[NFAPI_CC_MAX]; + uint8_t harq_pid, round; + uint16_t available_rbs[NFAPI_CC_MAX]; + uint8_t rbs_retx[NFAPI_CC_MAX]; uint16_t average_rbs_per_user[NFAPI_CC_MAX]; - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - uint16_t nb_rbs_required_remaining_1[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + int total_ue_count[NFAPI_CC_MAX]; + int ue_count_newtx[NFAPI_CC_MAX]; + int ue_count_retx[NFAPI_CC_MAX]; + //uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - int N_RB_DL; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; + // Reset for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { total_ue_count[CC_id] = 0; - total_rbs_used[CC_id] = 0; + ue_count_newtx[CC_id] = 0; + ue_count_retx[CC_id] = 0; + rbs_retx[CC_id] = 0; average_rbs_per_user[CC_id] = 0; - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - nb_rbs_required_remaining[CC_id][UE_id] = 0; - } + available_rbs[CC_id] = 0; + //for (UE_id = 0; UE_id < NFAPI_CC_MAX; ++UE_id) { + // ue_retx_flag[CC_id][UE_id] = 0; + //} } - // loop over all active UEs + // Find total UE count, and account the RBs required for retransmissions for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; - if (rnti == NOT_A_RNTI) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { + CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; - // TODO Can we use subframe2harqpid() here? - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; - average_rbs_per_user[CC_id] = 0; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id]++; + } if (round != 8) { nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id]; - } - - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + rbs_retx[CC_id] += nb_rbs_required[CC_id][UE_id]; + ue_count_retx[CC_id]++; + //ue_retx_flag[CC_id][UE_id] = 1; + } else { + ue_count_newtx[CC_id]++; } } } - // loop over all active UEs and calculate avg rb per user based on total active UEs - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - rnti = UE_RNTI(Mod_id, UE_id); + // PARTITIONING + // Reduces the available RBs according to slicing configuration + dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_idx, rbs_retx); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { + if (UE_list->head < 0) continue; // no UEs in list + // max_rbs_allowed_slice is saved in every UE, so take it from the first one + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_list->head]; + available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; + } - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + switch (RC.mac[Mod_id]->slice_info.dl[slice_idx].accounting) { - // hypothetical assignment - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ + // If greedy scheduling, try to account all the required RBs + case POL_GREEDY: - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - total_rbs_used[CC_id]; + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; - // recalculate based on the what is left after retransmission - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = - flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + if (available_rbs[CC_id] == 0) continue; + nb_rbs_accounted[CC_id][UE_id] = cmin(nb_rbs_required[CC_id][UE_id], available_rbs[CC_id]); + available_rbs[CC_id] -= nb_rbs_accounted[CC_id][UE_id]; + } + } + break; - if (total_ue_count[CC_id] == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= - (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); - } else { - // consider the total number of use that can be scheduled UE - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; + // Use the old, fair algorithm + // Loop over all active UEs and account the avg number of RBs to each UE, based on all non-retx UEs. + // case POL_FAIR: + default: + // FIXME: This is not ideal, why loop on UEs to find average_rbs_per_user[], that is per-CC? + // TODO: Look how to loop on active CCs only without using the UE_num_active_CC() function. + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { + + CC_id = UE_list->ordered_CCids[i][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; + + if (ue_count_newtx[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if (min_rb_unit[CC_id]*ue_count_newtx[CC_id] <= available_rbs[CC_id]) { + average_rbs_per_user[CC_id] = (uint16_t)floor(available_rbs[CC_id]/ue_count_newtx[CC_id]); + } else { + // consider the total number of use that can be scheduled UE + average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id]; + } + } } - } + + // note: nb_rbs_required is assigned according to total_buffer_dl + // extend nb_rbs_required to capture per LCID RB required + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_accounted[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + } + } + break; } - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required + + + + // Check retransmissions + // TODO: Do this once at the beginning for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; - if (rnti == NOT_A_RNTI) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); @@ -624,276 +695,494 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // control channel or retransmission /* TODO: do we have to check for retransmission? */ if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) { - nb_rbs_required_remaining_1[CC_id][UE_id] = - nb_rbs_required[CC_id][UE_id]; - } else { - nb_rbs_required_remaining_1[CC_id][UE_id] = - cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + nb_rbs_accounted[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; } } } +} - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { - - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - - if (r1 == 0) { - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining_1[CC_id][UE_id]; - } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required[CC_id][UE_id] - - nb_rbs_required_remaining_1[CC_id][UE_id] + - nb_rbs_required_remaining[CC_id][UE_id]; - if (nb_rbs_required_remaining[CC_id][UE_id] < 0) - abort(); - } +void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, + int slice_idx, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) +{ + int UE_id, CC_id; + int i; +#ifdef TM5 + uint8_t transmission_mode; +#endif + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; + int N_RBG[NFAPI_CC_MAX]; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - if (nb_rbs_required[CC_id][UE_id] > 0) - LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, UE_id, - nb_rbs_required_remaining[CC_id][UE_id], - nb_rbs_required_remaining_1[CC_id][UE_id], - nb_rbs_required[CC_id][UE_id], - UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], - N_RBG[CC_id], - min_rb_unit[CC_id]); + decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); - } - } + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + } - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + // Try to allocate accounted RBs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; - CC_id = UE_list->ordered_CCids[ii][UE_id]; - // if there are UEs with traffic - if (total_ue_count[CC_id] > 0) { - // ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - // round = ue_sched_ctl->round[CC_id][harq_pid]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_accounted[CC_id][UE_id]; +#ifdef TM5 + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); +#endif - rnti = UE_RNTI(Mod_id, UE_id); + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "Step 1: nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + CC_id, + UE_id, + nb_rbs_remaining[CC_id][UE_id], + nb_rbs_accounted[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); + + LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, + UE_id, + CC_id, + N_RBG[CC_id], + min_rb_unit[CC_id], + nb_rbs_required, + nb_rbs_remaining, + rballoc_sub, + slice_allocation_mask, + MIMO_mode_indicator); - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if (rnti == NOT_A_RNTI) - continue; - if (!ue_slice_membership(UE_id, slice_id)) - continue; +#ifdef TM5 + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + + for (j = 0; j < N_RBG[CC_id]; j += 2) { + + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_remaining[CC_id][UE_id] + > 0)) { + + for (i = UE_list->next[UE_id + 1]; i >= 0; + i = UE_list->next[i]) { + + UE_id2 = i; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { - transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - // rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); - /* 1st allocate for the retx */ - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, - CC_id, - N_RBG[CC_id], - transmission_mode, - min_rb_unit - [CC_id], - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth), - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); + if ((((j == (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_remaining + [CC_id] + [UE_id2] > 0)) { + + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; + + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } + + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; + + + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } + } + } + } + } + } + } +#endif + } + } +} +void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, + int slice_idx, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) +{ + int UE_id, CC_id; + int i; #ifdef TM5 - // data chanel TM5: to be revisited - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + uint8_t transmission_mode; +#endif + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int N_RBG[NFAPI_CC_MAX]; + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].slice_allocation_mask; - for (j = 0; j < N_RBG[CC_id]; j += 2) { + decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) - && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_required_remaining[CC_id][UE_id] - > 0)) { - - for (ii = UE_list->next[UE_id + 1]; ii >= 0; - ii = UE_list->next[ii]) { - - UE_id2 = ii; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = - &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) - continue; - if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) - continue; - - eNB_UE_stats2 = - UE_list-> - eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + } + + // Remaining RBs are allocated to high priority UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + + if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; + + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + nb_rbs_remaining[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + nb_rbs_remaining[CC_id][UE_id]; + if (nb_rbs_remaining[CC_id][UE_id] < 0) + abort(); +#ifdef TM5 + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); +#endif + + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "Step 2: nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + CC_id, + UE_id, + nb_rbs_remaining[CC_id][UE_id], + nb_rbs_accounted[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); + + LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, + UE_id, + CC_id, + N_RBG[CC_id], + min_rb_unit[CC_id], + nb_rbs_required, + nb_rbs_remaining, + rballoc_sub, + slice_allocation_mask, + MIMO_mode_indicator); + +#ifdef TM5 + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + + for (j = 0; j < N_RBG[CC_id]; j += 2) { + + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_remaining[CC_id][UE_id] + > 0)) { + + for (i = UE_list->next[UE_id + 1]; i >= 0; + i = UE_list->next[i]) { + + UE_id2 = i; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { + + if ((((j == (N_RBG[CC_id] - 1)) && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { - - if ((((j == (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) - && - (nb_rbs_required_remaining - [CC_id] - [UE_id2] > 0)) { - - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - - rballoc_sub[CC_id][j] = 1; - ue_sched_ctl-> - rballoc_sub_UE[CC_id] - [j] = 1; - ue_sched_ctl2-> - rballoc_sub_UE[CC_id] - [j] = 1; - MIMO_mode_indicator[CC_id] - [j] = 0; - - if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] - = 0; - } - - ue_sched_ctl-> - dl_pow_off[CC_id] - = 0; - ue_sched_ctl2-> - dl_pow_off[CC_id] - = 0; - - - if ((j == N_RBG[CC_id] - 1) - && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - } else { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + 4; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + 4; - } - - break; - } - } - } - } - } - } - } + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_remaining + [CC_id] + [UE_id2] > 0)) { + + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; + + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } + + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; + + + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } + } + } + } + } + } + } #endif - } // total_ue_count - } // CC - } // UE - } // end of for for r1 and r2 + } + } } // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done void dlsch_scheduler_pre_processor(module_id_t Mod_id, - slice_id_t slice_id, + int slice_idx, frame_t frameP, sub_frame_t subframeP, - int N_RBG[NFAPI_CC_MAX], - int *mbsfn_flag) { - + int *mbsfn_flag, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) +{ int UE_id; uint8_t CC_id; uint16_t i, j; - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting - int min_rb_unit[NFAPI_CC_MAX]; - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + + slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_required; + uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_accounted; + uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_remaining; + uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; @@ -910,63 +1199,64 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; - - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - if (UE_list->active[UE_id] != TRUE) - continue; - - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - // Initialize scheduling information for all active UEs - dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - rballoc_sub, - MIMO_mode_indicator); - - } - } - + // Initialize scheduling information for all active UEs + memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx])); + // FIXME: After the memset above, some of the resets in reset() are redundant + dlsch_scheduler_pre_processor_reset(Mod_id, slice_idx, frameP, subframeP, + min_rb_unit, + nb_rbs_required, + rballoc_sub, + MIMO_mode_indicator, + mbsfn_flag); // FIXME: Not sure if useful + + // STATUS // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); + store_dlsch_buffer(Mod_id, slice_idx, frameP, subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit); + assign_rbs_required(Mod_id, slice_idx, frameP, subframeP, nb_rbs_required, min_rb_unit); // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs(Mod_id, slice_id, frameP, subframeP); - - // This function does the main allocation of the number of RBs - dlsch_scheduler_pre_processor_accounting(Mod_id, - slice_id, - frameP, - subframeP, - N_RBG, - min_rb_unit, - rballoc_sub, - MIMO_mode_indicator, - nb_rbs_required); + sort_UEs(Mod_id, slice_idx, frameP, subframeP); + // ACCOUNTING + // This procedure decides the number of RBs to allocate + dlsch_scheduler_pre_processor_accounting(Mod_id, slice_idx, frameP, subframeP, + min_rb_unit, + nb_rbs_required, + nb_rbs_accounted); + // POSITIONING + // This procedure does the main allocation of the RBs + dlsch_scheduler_pre_processor_positioning(Mod_id, slice_idx, + min_rb_unit, + nb_rbs_required, + nb_rbs_accounted, + nb_rbs_remaining, + rballoc_sub, + MIMO_mode_indicator); + + // SHARING + // If there are available RBs left in the slice, allocate them to the highest priority UEs + if (RC.mac[Mod_id]->slice_info.intraslice_share_active) { + dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_idx, + min_rb_unit, + nb_rbs_required, + nb_rbs_accounted, + nb_rbs_remaining, + rballoc_sub, + MIMO_mode_indicator); + } #ifdef TM5 // This has to be revisited!!!! for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); + i1 = 0; + i2 = 0; + i3 = 0; - for (j = 0; j < N_RBG[CC_id]; j++) { + for (j = 0; j < N_RBG; j++) { if (MIMO_mode_indicator[CC_id][j] == 2) { i1 = i1 + 1; } else if (MIMO_mode_indicator[CC_id][j] == 1) { @@ -974,27 +1264,27 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } else if (MIMO_mode_indicator[CC_id][j] == 0) { i3 = i3 + 1; } - } + } - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { + if ((i1 < N_RBG) && (i2 > 0) && (i3 == 0)) { PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]-> check_for_SUMIMO_transmissions + 1; - } + } - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { + if (i3 == N_RBG && i1 == 0 && i2 == 0) { PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1; - } + } - if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { + if ((i1 < N_RBG) && (i3 > 0)) { PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]-> check_for_MUMIMO_transmissions + 1; - } + } - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1; @@ -1007,20 +1297,23 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id); LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]); LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id); - for (j = 0; j < N_RBG[CC_id]; j++) { + for (j = 0; j < N_RBG; j++) { //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id]; LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]); } //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", - Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); + Mod_id, RC.mac[Mod_id]->slice_info.dl[slice_idx].id, UE_id, + ue_sched_ctl->pre_nb_available_rbs[CC_id]); } } } @@ -1029,269 +1322,289 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, #define SF0_LIMIT 1 void -dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[NFAPI_CC_MAX] - [MAX_MOBILES_PER_ENB], - unsigned char - rballoc_sub[NFAPI_CC_MAX] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[NFAPI_CC_MAX] - [N_RBG_MAX]) +dlsch_scheduler_pre_processor_reset(module_id_t module_idP, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], + int *mbsfn_flag) { + + int UE_id; + uint8_t CC_id; int i, j; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_list_t *UE_list; + UE_sched_ctrl *ue_sched_ctl; + int N_RB_DL, RBGsize, RBGsize_last; + int N_RBG[NFAPI_CC_MAX]; - uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; - int N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); - int RBGsize = N_RB_DL / N_RBG, RBGsize_last; #ifdef SF0_LIMIT - int sf0_upper = -1, sf0_lower = -1; + int sf0_lower, sf0_upper; #endif + rnti_t rnti; + uint8_t *vrb_map; + COMMON_channels_t *cc; +// + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id,(int)(UE_RNTI(module_idP, UE_id))); - // initialize harq_pid and round + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id,(int)(UE_RNTI(module_idP, UE_id))); + // initialize harq_pid and round + cc = &RC.mac[module_idP]->common_channels[CC_id]; + N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; + if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here + continue; - /* - eNB_UE_stats *eNB_UE_stats; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - if (eNB_UE_stats == NULL) - return; + UE_list = &RC.mac[module_idP]->UE_list; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti = UE_RNTI(module_idP, UE_id); - mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti, - frameP,subframeP, - &ue_sched_ctl->harq_pid[CC_id], - &ue_sched_ctl->round[CC_id], - openair_harq_DL); - if (ue_sched_ctl->ta_timer == 0) { + if (rnti == NOT_A_RNTI) + continue; - // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... + if (UE_list->active[UE_id] != TRUE) + continue; - ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - switch (N_RB_DL) { - case 6: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update; - break; + if (!ue_dl_slice_membership(module_idP, UE_id, slice_idx)) + continue; - case 15: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2; - break; + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); + // initialize harq_pid and round + if (ue_sched_ctl->ta_timer) + ue_sched_ctl->ta_timer--; - case 25: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4; - break; - case 50: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8; - break; + /* + eNB_UE_stats *eNB_UE_stats; - case 75: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12; - break; + if (eNB_UE_stats == NULL) + return; - case 100: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16; - break; - } - // clear the update in case PHY does not have a new measurement after timer expiry - eNB_UE_stats->timing_advance_update = 0; - } - else { - ue_sched_ctl->ta_timer--; - ue_sched_ctl->ta_update =0; // don't trigger a timing advance command - } + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti, + frameP,subframeP, + &ue_sched_ctl->harq_pid[CC_id], + &ue_sched_ctl->round[CC_id], + openair_harq_DL); - if (UE_id==0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update); - } - */ - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; + if (ue_sched_ctl->ta_timer == 0) { + + // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... + + ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY + switch (N_RB_DL) { + case 6: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update; + break; + + case 15: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2; + break; + + case 25: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4; + break; + + case 50: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8; + break; + + case 75: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12; + break; + + case 100: + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16; + break; + } + // clear the update in case PHY does not have a new measurement after timer expiry + eNB_UE_stats->timing_advance_update = 0; + } + else { + ue_sched_ctl->ta_timer--; + ue_sched_ctl->ta_update =0; // don't trigger a timing advance command + } - switch (N_RB_DL) { - case 6: - RBGsize = 1; - RBGsize_last = 1; - break; - case 15: - RBGsize = 2; - RBGsize_last = 1; - break; - case 25: - RBGsize = 2; - RBGsize_last = 1; - break; - case 50: - RBGsize = 3; - RBGsize_last = 2; - break; - case 75: - RBGsize = 4; - RBGsize_last = 3; - break; - case 100: - RBGsize = 4; - RBGsize_last = 4; - break; - default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + + if (UE_id==0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update); + } + */ + + nb_rbs_required[CC_id][UE_id] = 0; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctl->dl_pow_off[CC_id] = 2; + + for (i = 0; i < N_RBG[CC_id]; i++) { + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; + } + } + + N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); #ifdef SF0_LIMIT - switch (N_RBG) { - case 6: - sf0_lower = 0; - sf0_upper = 5; - break; - case 8: - sf0_lower = 2; - sf0_upper = 5; - break; - case 13: - sf0_lower = 4; - sf0_upper = 7; - break; - case 17: - sf0_lower = 7; - sf0_upper = 9; - break; - case 25: - sf0_lower = 11; - sf0_upper = 13; - break; - default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + switch (N_RBG[CC_id]) { + case 6: + sf0_lower = 0; + sf0_upper = 5; + break; + case 8: + sf0_lower = 2; + sf0_upper = 5; + break; + case 13: + sf0_lower = 4; + sf0_upper = 7; + break; + case 17: + sf0_lower = 7; + sf0_upper = 9; + break; + case 25: + sf0_lower = 11; + sf0_upper = 13; + break; + default: + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; + switch (N_RB_DL) { + case 6: + RBGsize = 1; + RBGsize_last = 1; + break; + case 15: + RBGsize = 2; + RBGsize_last = 1; + break; + case 25: + RBGsize = 2; + RBGsize_last = 1; + break; + case 50: + RBGsize = 3; + RBGsize_last = 2; + break; + case 75: + RBGsize = 4; + RBGsize_last = 3; + break; + case 100: + RBGsize = 4; + RBGsize_last = 4; + break; + default: + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } + + vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + // Initialize Subbands according to VRB map + for (i = 0; i < N_RBG[CC_id]; i++) { + int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; #ifdef SF0_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) - /* TODO: make it proper - allocate those RBs, do not "protect" them, but - * compute number of available REs and limit MCS according to the - * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) - */ - if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) - rballoc_sub[CC_id][i] = 1; + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) + /* TODO: make it proper - allocate those RBs, do not "protect" them, but + * compute number of available REs and limit MCS according to the + * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) + */ + if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) + rballoc_sub[CC_id][i] = 1; #endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < rb_size; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; + // for SI-RNTI,RA-RNTI and P-RNTI allocations + for (j = 0; j < rb_size; j++) { + if (vrb_map[j + (i*RBGsize)] != 0) { + rballoc_sub[CC_id][i] = 1; + LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", frameP, subframeP, j + (i*RBGsize)); + break; + } } + //LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + //frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + MIMO_mode_indicator[CC_id][i] = 2; } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; } } void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) + int UE_id, + uint8_t CC_id, + int N_RBG, + int min_rb_unit, + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { + int i; + int tm = get_tmode(Mod_id, CC_id, UE_id); + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - int i; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - for (i = 0; i < N_RBG; i++) { - - if ((rballoc_sub[CC_id][i] == 0) && - (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && - (nb_rbs_required_remaining[CC_id][UE_id] > 0) && - (ue_sched_ctl->pre_nb_available_rbs[CC_id] < - nb_rbs_required[CC_id][UE_id])) { - - // if this UE is not scheduled for TM5 - if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { - - if ((i == N_RBG - 1) - && ((N_RB_DL == 25) || (N_RB_DL == 50))) { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit - 1) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit + 1; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit - 1; - } - } else { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit; - } - } - } // dl_pow_off[CC_id][UE_id] ! = 0 - } + for (i = 0; i < N_RBG; i++) { + + if (rballoc_sub[CC_id][i] != 0) continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) continue; + if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue; + if (slice_allocation_mask[CC_id][i] == 0) continue; + + if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { + // Allocating last, smaller RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) { + rballoc_sub[CC_id][i] = 1; + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; + MIMO_mode_indicator[CC_id][i] = 1; + if (tm == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; + } + } else { + // Allocating a standard-sized RBG + if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) { + rballoc_sub[CC_id][i] = 1; + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; + MIMO_mode_indicator[CC_id][i] = 1; + if (tm == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; + } } + } } /// ULSCH PRE_PROCESSOR void ulsch_scheduler_pre_processor(module_id_t module_idP, - slice_id_t slice_id, + int slice_idx, int frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t *first_rb) { - int16_t i; uint16_t UE_id, n, r; uint8_t CC_id, harq_pid; @@ -1302,13 +1615,15 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, uint16_t total_ue_count[NFAPI_CC_MAX]; rnti_t rnti = -1; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_TEMPLATE *UE_template = 0; UE_sched_ctrl *ue_sched_ctl; int N_RB_UL = 0; + uint16_t available_rbs, first_rb_offset; LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); + assign_max_mcs_min_rb(module_idP, slice_idx, frameP, subframeP, first_rb); LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); // sort ues @@ -1330,9 +1645,9 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][i]; UE_template = &UE_list->UE_template[CC_id][i]; - if (!ue_slice_membership(i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; - if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { + if (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) { total_ue_count[CC_id] += 1; } } @@ -1351,7 +1666,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(UE_id, slice_id)) + if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) continue; LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, @@ -1375,14 +1690,21 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); + + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], + N_RB_UL - first_rb[CC_id] - first_rb_offset); + if (available_rbs < 0) + available_rbs = 0; if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; } else if (total_ue_count[CC_id] == 1) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] + 1; - } else if (total_ue_count[CC_id] <= (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) { - average_rbs_per_user[CC_id] = (uint16_t) floor((ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]) / total_ue_count[CC_id]); + average_rbs_per_user[CC_id] = (uint16_t) (available_rbs + 1); + } else if (total_ue_count[CC_id] <= available_rbs) { + average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]); } else { average_rbs_per_user[CC_id] = 1; LOG_W(MAC, @@ -1403,7 +1725,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; @@ -1422,7 +1744,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; } else { nb_allocated_rbs[CC_id][UE_id] = - cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_id], + cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_idx], average_rbs_per_user[CC_id]); } @@ -1444,7 +1766,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; UE_id = i; @@ -1454,25 +1776,28 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; - total_remaining_rbs[CC_id] = - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; + N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], + N_RB_UL - first_rb[CC_id] - first_rb_offset); + total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id]; if (total_ue_count[CC_id] == 1) { total_remaining_rbs[CC_id] += 1; } if (r == 0) { - while ((UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) - && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_id]) + while ((UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) + && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_idx]) && (total_remaining_rbs[CC_id] > 0)) { nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id] + 1, - UE_template->pre_allocated_nb_rb_ul[slice_id]); + UE_template->pre_allocated_nb_rb_ul[slice_idx]); total_remaining_rbs[CC_id]--; total_allocated_rbs[CC_id]++; } } else { - UE_template->pre_allocated_nb_rb_ul[slice_id] = + UE_template->pre_allocated_nb_rb_ul[slice_idx] = nb_allocated_rbs[CC_id][UE_id]; LOG_D(MAC, "******************UL Scheduling Information for UE%d CC_id %d ************************\n", @@ -1480,7 +1805,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, LOG_D(MAC, "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", module_idP, UE_id, CC_id, - UE_template->pre_allocated_nb_rb_ul[slice_id]); + UE_template->pre_allocated_nb_rb_ul[slice_idx]); } } } @@ -1488,7 +1813,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, } void -assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, +assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, uint16_t * first_rb) { @@ -1500,11 +1825,13 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, int rb_table_index = 0, tbs, tx_power; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; + slice_info_t *sli = &RC.mac[module_idP]->slice_info; UE_TEMPLATE *UE_template; UE_sched_ctrl *ue_sched_ctl; int Ncp; int N_RB_UL; + int first_rb_offset, available_rbs; for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (UE_list->active[i] != TRUE) @@ -1516,16 +1843,16 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_slice_membership(i, slice_id)) + if (!ue_ul_slice_membership(module_idP, i, slice_idx)) continue; if (UE_list->UE_sched_ctrl[i].phr_received == 1) { /* if we've received the power headroom information the UE, we can go to * maximum mcs */ - mcs = cmin(20, slice_maxmcs_uplink[slice_id]); + mcs = cmin(20, sli->ul[slice_idx].maxmcs); } else { /* otherwise, limit to QPSK PUSCH */ - mcs = cmin(10, slice_maxmcs_uplink[slice_id]); + mcs = cmin(10, sli->ul[slice_idx].maxmcs); } UE_id = i; @@ -1547,7 +1874,8 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; if (bytes_to_schedule < 0) bytes_to_schedule = 0; @@ -1570,18 +1898,20 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs } + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], + N_RB_UL - first_rb[CC_id] - first_rb_offset); + while ((tbs < bits_to_schedule) - && (rb_table[rb_table_index] < (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) - && ((UE_template->phr_info - tx_power) > 0) - && (rb_table_index < 32)) { + && (rb_table[rb_table_index] < available_rbs) + && ((UE_template->phr_info - tx_power) > 0) + && (rb_table_index < 32)) { rb_table_index++; tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); } - UE_template->ue_tx_power = tx_power; - - if (rb_table[rb_table_index] > (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - 1)) { + if (rb_table[rb_table_index] > (available_rbs - 1)) { rb_table_index--; } // 1 or 2 PRB with cqi enabled does not work well @@ -1590,13 +1920,13 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, } UE_template->pre_allocated_rb_table_index_ul = rb_table_index; - UE_template->pre_allocated_nb_rb_ul[slice_id] = rb_table[rb_table_index]; + UE_template->pre_allocated_nb_rb_ul[slice_idx] = rb_table[rb_table_index]; LOG_D(MAC, "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", module_idP, frameP, subframeP, UE_id, CC_id, UE_template->pre_assigned_mcs_ul, UE_template->pre_allocated_rb_table_index_ul, - UE_template->pre_allocated_nb_rb_ul[slice_id], + UE_template->pre_allocated_nb_rb_ul[slice_idx], UE_template->phr_info, tx_power); } else { /* if UE has pending scheduling request then pre-allocate 3 RBs */ @@ -1605,11 +1935,11 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, /* use QPSK mcs */ UE_template->pre_assigned_mcs_ul = 10; UE_template->pre_allocated_rb_table_index_ul = 2; - UE_template->pre_allocated_nb_rb_ul[slice_id] = 3; + UE_template->pre_allocated_nb_rb_ul[slice_idx] = 3; } else { UE_template->pre_assigned_mcs_ul = 0; UE_template->pre_allocated_rb_table_index_ul = -1; - UE_template->pre_allocated_nb_rb_ul[slice_id] = 0; + UE_template->pre_allocated_nb_rb_ul[slice_idx] = 0; } } } diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index f5df67ab64d5ce540b14a2fa1c6975bdf9200aa7..aeabbd092a32c02dee9ba16fdabf6deab593b0ec 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -248,7 +248,7 @@ Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, UE_mac_inst[module_idP].RA_attempt_number++; if (opt_enabled) { - trace_pdu(0, NULL, 0, module_idP, 0, + trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI, UE_mac_inst[module_idP].RA_prach_resources. ra_PreambleIndex, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, @@ -277,8 +277,8 @@ Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; if (opt_enabled) { // msg3 - trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], - UE_mac_inst[module_idP].RA_Msg3_size, module_idP, 3, + trace_pdu(DIRECTION_UPLINK , &UE_mac_inst[module_idP].CCCH_pdu.payload[0], + UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index b70b3824946cf0271752ff735613fd473e781c99..2e6b47ff60464c320326a8d48455e47fc43792d2 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -96,7 +96,7 @@ fill_rar(const module_id_t module_idP, ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1); if (opt_enabled) { - trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1, + trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, module_idP, WS_RA_RNTI , 1, RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0); LOG_D(OPT, @@ -181,7 +181,7 @@ fill_rar_br(eNB_MAC_INST * eNB, ra->preamble_index, ra->timing_offset); if (opt_enabled) { - trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1, + trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, eNB->Mod_id, WS_RA_RNTI , 1, eNB->frame, eNB->subframe, 0, 0); LOG_D(OPT, "[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", diff --git a/openair2/LAYER2/MAC/rar_tools_ue.c b/openair2/LAYER2/MAC/rar_tools_ue.c index 991eaae052b40fe68297927593101cb548f192a6..35d1f7925e55ddc07c0d37dbe4217f19a0910aa0 100644 --- a/openair2/LAYER2/MAC/rar_tools_ue.c +++ b/openair2/LAYER2/MAC/rar_tools_ue.c @@ -119,8 +119,8 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra LOG_D(OPT, "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", module_idP, CC_id, frameP, ra_rnti); - trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, - module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame, + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, + module_idP, WS_RA_RNTI, ra_rnti, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index dd78da72751db65b3ae551d921b25353e9fcc33f..2c99b79ce8057860a4f3870c6dcd6a302854f7d7 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -420,7 +420,7 @@ ue_send_sdu(module_id_t module_idP, //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); if (opt_enabled) { - trace_pdu(1, sdu, sdu_len, module_idP, 3, + trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI, UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0); LOG_D(OPT, "[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", @@ -637,11 +637,11 @@ ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, stop_meas(&UE_mac_inst[module_idP].rx_si); #endif if (opt_enabled == 1) { - trace_pdu(0, + trace_pdu(DIRECTION_UPLINK, (uint8_t *) pdu, len, module_idP, - 4, + WS_SI_RNTI, 0xffff, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); @@ -675,11 +675,11 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, stop_meas(&UE_mac_inst[module_idP].rx_p); #endif if (opt_enabled == 1) { - trace_pdu(0, + trace_pdu(DIRECTION_UPLINK , (uint8_t *) pdu, len, module_idP, - 4, + WS_SI_RNTI, P_RNTI, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); @@ -750,7 +750,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint8_t sync_area) { - unsigned char num_sdu, i, *payload_ptr; + unsigned char num_sdu, i, j, *payload_ptr; unsigned char rx_lcids[NB_RB_MAX]; unsigned short rx_lengths[NB_RB_MAX]; #if UE_TIMING_TRACE @@ -771,47 +771,76 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, num_sdu); for (i = 0; i < num_sdu; i++) { - if (rx_lcids[i] == MCH_SCHDL_INFO) { - if (UE_mac_inst[module_idP].mcch_status == 1) { - LOG_I(MAC, - "[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes)\n", - module_idP, frameP, sync_area, eNB_index, - rx_lengths[i]); - // ??store necessary scheduling info to ue_mac_inst in order to - // calculate exact position of interested service (for the complex case has >1 mtch) - // set msi_status to 1 - UE_mac_inst[module_idP].msi_status = 1; - } - } else if (rx_lcids[i] == MCCH_LCHANID) { - LOG_I(MAC, - "[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n", - module_idP, frameP, i, sync_area, eNB_index, - rx_lengths[i]); - mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe - M_RNTI, - MCCH, - payload_ptr, rx_lengths[i], eNB_index, - sync_area); - } else if (rx_lcids[i] == MTCH) { - if (UE_mac_inst[module_idP].msi_status == 1) { - LOG_I(MAC, - "[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes)\n", - module_idP, frameP, sync_area, eNB_index, - rx_lengths[i]); + if (rx_lcids[i] == MCH_SCHDL_INFO) { + if (rx_lengths[i] & 0x01) { + LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n"); + } - mac_rlc_data_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, ENB_FLAG_NO, MBMS_FLAG_YES, MTCH, /*+ (maxDRB + 3), */ - (char *) payload_ptr, rx_lengths[i], 1, - NULL); + LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]); - } - } else { - LOG_W(MAC, - "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n", - module_idP, frameP, rx_lengths[i], i, rx_lcids[i], - UE_mac_inst[module_idP].mcch_status, eNB_index); - } + for (j=0; j<rx_lengths[i]/2; j++) { + uint16_t stop_mtch_val = ((uint16_t)(payload_ptr[2*j] & 0x07) << 8) | (uint16_t)payload_ptr[2*j+1]; + + UE_mac_inst[module_idP].pmch_lcids[j] = (payload_ptr[2*j] & 0xF8) >> 3; + UE_mac_inst[module_idP].pmch_stop_mtch[j] = stop_mtch_val; + LOG_D(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP); + + if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) { + LOG_D(MAC,"(reserved)\n"); + } + + UE_mac_inst[module_idP].msi_status_v[j] = 0; - payload_ptr += rx_lengths[i]; + if (UE_mac_inst[module_idP].mcch_status==1) { + LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]); + if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) { + UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc; + UE_mac_inst[module_idP].msi_status_v[j] = 1; + } + } + } + } else if (rx_lcids[i] == MCCH_LCHANID) { + LOG_D(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]); + mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP,0, // unknown subframe + M_RNTI, + MCCH, + payload_ptr + 1, // Skip RLC layer 1st byte + rx_lengths[i] - 1, + eNB_index, + sync_area); + } else if (rx_lcids[i] <= 28) { + for (j=0; j<28; j++) { + if (rx_lcids[i] == UE_mac_inst[module_idP].pmch_lcids[j]) + break; + } + + 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); + + mac_rlc_data_ind( + module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_YES, + rx_lcids[i], /*+ (maxDRB + 3),*/ + (char *)payload_ptr, + rx_lengths[i], + 1, + NULL); + + } + } else { + LOG_W(MAC, + "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n", + module_idP, frameP, rx_lengths[i], i, rx_lcids[i], + UE_mac_inst[module_idP].mcch_status, eNB_index); + } + + payload_ptr += rx_lengths[i]; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME @@ -916,406 +945,591 @@ int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_are } } -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 ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int commonSFAlloc_period, int commonSFAlloc_offset, int num_sf_alloc, int *mtch_active, int *msi_active, uint8_t *mch_lcid) { + int i, mtch_mcs = -1; + int mtch_flag = 0; + int msi_flag = 0; - int i = 0, j = 0, ii = 0, msi_pos = 0, mcch_mcs = -1; - int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; - int mbsfn_period = 0; // 1<<(UE_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - int mcch_period = 0; // 32<<(UE_mac_inst[module_idP].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); - int mch_scheduling_period = -1; + for (i = 0; i < 4; i++) { + if (UE_mac_inst[module_idP].pmch_Config[i] == NULL) + continue; - int frame_FDD = 1; + int mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[i]->mch_SchedulingPeriod_r9; + uint8_t sf_AllocEnd_r9 = UE_mac_inst[module_idP].pmch_Config[i]->sf_AllocEnd_r9; + if (sf_AllocEnd_r9 == 2047) { + msi_flag = 1; + break; + } -#if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].ue_query_mch); -#endif + if ((frameP % mch_scheduling_period) == (commonSFAlloc_offset + (frameP % 4))) { + if (i == 0) { + //msi and mtch are mutally excluded then the break is safe + if ((num_sf_alloc == 0) && (sf_AllocEnd_r9 >= 1)) { + msi_flag = 1; + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc); + UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc; + UE_mac_inst[module_idP].msi_pmch = i; + } + } else { //more that one MCH ?? check better this condition + //msi and mtch are mutally excluded then the break is safe + if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9 + 1) && (sf_AllocEnd_r9 >= (num_sf_alloc+1))) { + //msi should be just after + msi_flag = 1; + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc); + UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc; + UE_mac_inst[module_idP].msi_pmch = i; + } + } + } + } - if (UE_mac_inst[module_idP].pmch_Config[0]) { - mch_scheduling_period = - 8 << (UE_mac_inst[module_idP]. - pmch_Config[0]->mch_SchedulingPeriod_r9); + 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) { + mtch_flag = 1; + 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; + else + mtch_mcs = -1; + *mch_lcid = (uint8_t)i; + LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs,UE_mac_inst[module_idP].pmch_stop_mtch[i],UE_mac_inst[module_idP].pmch_lcids[i],UE_mac_inst[module_idP].msi_pmch); + break; + } } + } - for (i = 0; i < UE_mac_inst[module_idP].num_active_mbsfn_area; i++) { - // assume, that there is always a mapping - if ((j = - ue_get_mbsfn_sf_alloction(module_idP, i, eNB_index)) == -1) { - return -1; // continue; - } + *mtch_active = mtch_flag; + *msi_active = msi_flag; - ii = 0; - msi_pos = 0; - mbsfn_period = - 1 << (UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); - mcch_period = - 32 << (UE_mac_inst[module_idP]. - mbsfn_AreaInfo[0]->mcch_Config_r9. - mcch_RepetitionPeriod_r9); + return mtch_mcs; +} - LOG_D(MAC, - "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d,mac sched period (%d,%ld))\n", - module_idP, frameP, subframe, i, - UE_mac_inst[module_idP].num_active_mbsfn_area, j, - UE_mac_inst[module_idP].num_sf_allocation_pattern, - mbsfn_period, mcch_period, mch_scheduling_period, - UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[j]->radioframeAllocationOffset); - - // get the real MCS value - switch (UE_mac_inst[module_idP].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; - } +int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid) +{ + int i, j, mtch_mcs = -1; + int mtch_flag = 0; + + // 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) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format + continue; + + // four-frameP format + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + for (j = 0; j < 24; j++) + num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x800000 >> j)) == (0x800000 >> j)); + } - if (frameP % mbsfn_period == UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP - if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + for (i = 0; i < 8; i++ ) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format + continue; + + // four-frameP format + int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset; + int common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod; + int commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + + int jj = frameP % 4; + if ((frameP % common_mbsfn_period) != (common_mbsfn_alloc_offset + jj)) + continue; + + if(UE_mac_inst[module_idP].tdd_Config == NULL){ + switch (subframe) { + case 1: + if ((common_mbsfn_SubframeConfig & (0x800000 >> (jj*6))) == (0x800000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + 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);//48; + } + break; + case 2: + if ((common_mbsfn_SubframeConfig & (0x400000 >> (jj*6))) == (0x400000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + 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);//48; + } + break; + case 3: + if ((common_mbsfn_SubframeConfig & (0x200000 >> (jj*6))) == (0x200000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + 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);//48; + } + break; + case 6: + if ((common_mbsfn_SubframeConfig & (0x100000 >> (jj*6))) == (0x100000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + 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);//48; + } + break; + case 7: + if ((common_mbsfn_SubframeConfig & (0x80000 >> (jj*6))) == (0x80000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + 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);//48; + } + break; + case 8: + if ((common_mbsfn_SubframeConfig & (0x40000 >> (jj*6))) == (0x40000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + 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);//48; + } + break; + } + } else { + // TODO TDD + } + if (mtch_flag == 1) + break; + } - if (UE_mac_inst[module_idP].pmch_Config[0]) { - // Find the first subframe in this MCH to transmit MSI - if (frameP % mch_scheduling_period == - UE_mac_inst[module_idP]. - mbsfn_SubframeConfig - [j]->radioframeAllocationOffset) { - while (ii == 0) { - ii = UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[j]-> - subframeAllocation.choice. - oneFrame.buf[0] & (0x80 >> msi_pos); - msi_pos++; - } - } - } + return mtch_mcs; +} - if (UE_mac_inst[module_idP].tdd_Config == NULL) - frame_FDD = 1; - else - frame_FDD = 0; - // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 - switch (subframe) { - case 1: - if (frame_FDD == 1) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { - if (msi_pos == 1) { - msi_flag = 1; - } +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) +{ - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF1) == - MBSFN_FDD_SF1)) { - mcch_flag = 1; - } + int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1; + int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; + long mch_scheduling_period = -1; + uint8_t mch_lcid = 0; - mtch_flag = 1; - } - } +#if UE_TIMING_TRACE + start_meas(&UE_mac_inst[module_idP].ue_query_mch); +#endif - break; + if (UE_mac_inst[module_idP].pmch_Config[0]) { + mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9; + } - case 2: - if (frame_FDD == 1) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { - if (msi_pos == 2) { - msi_flag = 1; - } + for (i = 0; + i < UE_mac_inst[module_idP].num_active_mbsfn_area; + i++ ) + { + // assume, that there is always a mapping + if ((j = ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) { + return -1; // continue; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF2) == - MBSFN_FDD_SF2)) { - mcch_flag = 1; - } + ii = 0; + msi_pos = 0; + + long mbsfn_period = 1 << UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod; + long mbsfn_alloc_offset = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset; + long mcch_period = 32 << UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_RepetitionPeriod_r9; + long mcch_offset = UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_Offset_r9; - mtch_flag = 1; - } - } + LOG_D(MAC, + "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %ld, mcch period %ld,mac sched period (%ld,%ld))\n", + module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area, + j,UE_mac_inst[module_idP].num_sf_allocation_pattern,mbsfn_period,mcch_period, + mcch_offset,mbsfn_alloc_offset); + + // get the real MCS value + switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; - break; + case 1: + mcch_mcs = 7; + break; - case 3: - if (frame_FDD == 0) { //TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { - if (msi_pos == 1) { - msi_flag = 1; - } + case 2: + mcch_mcs = 13; + break; - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF3) == - MBSFN_TDD_SF3)) { - mcch_flag = 1; - } + case 3: + mcch_mcs = 19; + break; + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { - if (msi_pos == 3) { - msi_flag = 1; - } + if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + if (frameP % mbsfn_period == mbsfn_alloc_offset) { // MBSFN frameP - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF3) == - MBSFN_FDD_SF3)) { - mcch_flag = 1; - } + if (UE_mac_inst[module_idP].pmch_Config[0]) { + // Find the first subframe in this MCH to transmit MSI + if (frameP % mch_scheduling_period == mbsfn_alloc_offset) { + while (ii == 0) { + ii = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80 >> msi_pos); + msi_pos++; + } + } + } + + // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframe) { + case 1: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 2: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if (msi_pos == 2) { + msi_flag = 1; + } - case 4: - if (frame_FDD == 0) { - if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF4) == - MBSFN_TDD_SF4)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 3: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { + if (msi_pos == 1) { + msi_flag = 1; + } - case 6: - if (frame_FDD == 1) { - if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF6) == - MBSFN_FDD_SF6)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } else { // FDD + if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 4: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { + if (msi_pos == 2) { + msi_flag = 1; + } - case 7: - if (frame_FDD == 0) { // TDD - if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF7) == - MBSFN_TDD_SF7)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { - if (msi_pos == 5) { - msi_flag = 1; - } + break; - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF7) == - MBSFN_FDD_SF7)) { - mcch_flag = 1; - } + case 6: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if (msi_pos == 4) { + msi_flag = 1; + } - mtch_flag = 1; - } - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { + mcch_flag = 1; + } - break; + mtch_flag = 1; + } + } - case 8: - if (frame_FDD == 0) { //TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig - [j]->subframeAllocation.choice.oneFrame. - buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { - if (msi_pos == 4) { - msi_flag = 1; - } + break; - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF8) == - MBSFN_TDD_SF8)) { - mcch_flag = 1; - } + case 7: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { + if (msi_pos == 3) { + msi_flag = 1; + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF8) == - MBSFN_FDD_SF8)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } else { // FDD + if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; + case 8: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { //TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { + if (msi_pos == 4) { + msi_flag = 1; + } - case 9: - if (frame_FDD == 0) { - if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == - UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.mcch_Offset_r9) - && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo - [i]->mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF9) == - MBSFN_TDD_SF9)) { - mcch_flag = 1; - } + mtch_flag = 1; + } + } else { // FDD + if ((UE_mac_inst[module_idP].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 == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } + } - mtch_flag = 1; - } - } + break; - break; - } // end switch + case 9: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { + if (msi_pos == 5) { + msi_flag = 1; + } - // 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); + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].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 + + // 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) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != 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]; + 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) + mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + else + mtch_mcs = -1; + mch_lcid = (uint8_t)i; + break; + } + } + } + + // 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); + + *sync_area=i; + break; + } + } + } else { // four-frameP format + uint32_t mbsfn_SubframeConfig = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[2] | + (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0]<<16); + uint32_t MCCH_mbsfn_SubframeConfig = /* UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[2] | + (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[1]<<8) | */ + (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]<<16); + + jj=frameP%4; + if ((frameP % mbsfn_period) == (mbsfn_alloc_offset+jj)) { + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + switch (subframe) { + case 1: + if ((mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6)))) { + mcch_flag=1; + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x800000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 2: + if ((mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6)))) { + mcch_flag=1; + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x400000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 3: + if ((mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x200000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + mcch_flag=1; + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 6: + if ((mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x100000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + mcch_flag=1; + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } + } + break; + case 7: + if ((mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x80000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + mcch_flag=1; + } + } + break; + case 8: + if ((mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x40000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + mcch_flag=1; + } + } + break; + }// end switch + } else { + // TODO TDD + } + + mtch_mcs = ue_query_p_mch(module_idP, frameP, subframe, &mtch_flag, &msi_flag, &mch_lcid); + + // 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); + *sync_area=i; + break; + } + } + } + } // end of for - *sync_area = i; - break; - } - } else { // four-frameP format - } - } - } // end of for #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_query_mch); + stop_meas(&UE_mac_inst[module_idP].ue_query_mch); #endif - if ((mcch_flag == 1)) { // || (msi_flag==1)) - *mcch_active = 1; - } + if ((mcch_flag == 1)) { // || (msi_flag==1)) + *mcch_active = 1; + } - if ((mcch_flag == 1) - || ((msi_flag == 1) && (UE_mac_inst[module_idP].mcch_status == 1))) { - return mcch_mcs; - } else if ((mtch_flag == 1) - && (UE_mac_inst[module_idP].msi_status == 1)) { - return UE_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9; + if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ) { + if (msi_flag!=1) { + for (i=0; i<8; i++) + UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = NULL; + for (i=0; i<15; i++) + UE_mac_inst[module_idP].pmch_Config[i] = NULL; + for (i=0; i<28 ;i++) { + UE_mac_inst[module_idP].pmch_lcids[i] = -1; + UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; + UE_mac_inst[module_idP].msi_status_v[i] = 0; + } } else { - return -1; + for (i=0; i<28; i++) { + UE_mac_inst[module_idP].pmch_lcids[i] = -1; + UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; + UE_mac_inst[module_idP].msi_status_v[i] = 0; + } } + return mcch_mcs; + } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status_v[(mch_lcid > 27) ? 27 : mch_lcid] == 1)) { + return mtch_mcs; + } else { + return -1; + } } #endif @@ -2255,7 +2469,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, #endif if (opt_enabled) { - trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, + trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index e12fb80e1bda913de5e770730d3fe9ca97aa9ba6..05ddb4151f69513cb65b06d7aef3f91ec6315054 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -30,6 +30,8 @@ #define PDCP_C //#define DEBUG_PDCP_FIFO_FLUSH_SDU +#define MBMS_MULTICAST_OUT + #include "assertions.h" #include "hashtable.h" #include "pdcp.h" @@ -66,6 +68,17 @@ extern int otg_enabled; #include "common/ran_context.h" extern RAN_CONTEXT_t RC; +#ifdef MBMS_MULTICAST_OUT +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <netinet/ip.h> +# include <netinet/udp.h> +# include <unistd.h> + +static int mbms_socket = -1; +#endif + //----------------------------------------------------------------------------- /* * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken @@ -349,16 +362,10 @@ boolean_t pdcp_data_req( * Ask sublayer to transmit data and check return value * to see if RLC succeeded */ -#ifdef PDCP_MSG_PRINT - int i=0; - LOG_F(PDCP,"[MSG] PDCP DL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); - for (i = 0; i < pdcp_pdu_size; i++) { - LOG_F(PDCP,"%02x ", ((uint8_t*)pdcp_pdu_p->data)[i]); - } + LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, + "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); - LOG_F(PDCP,"\n"); -#endif rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,sourceL2Id @@ -405,9 +412,9 @@ boolean_t pdcp_data_req( * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK * so we return TRUE afterwards */ - + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ - if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) break; } @@ -461,17 +468,8 @@ pdcp_data_ind( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN); - -#ifdef PDCP_MSG_PRINT - int i=0; - LOG_F(PDCP,"[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); - - for (i = 0; i < sdu_buffer_sizeP; i++) { - LOG_F(PDCP,"%02x ", ((uint8_t*)sdu_buffer_pP->data)[i]); - } - - LOG_F(PDCP,"\n"); -#endif + LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP, + "[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); #if T_TRACER if (ctxt_pP->enb_flag != ENB_FLAG_NO) @@ -758,11 +756,26 @@ pdcp_data_ind( packet_forwarded = FALSE; #endif +#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; + + 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; + } +#endif + if (FALSE == packet_forwarded) { new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), __func__); if (new_sdu_p) { - if (pdcp_p->rlc_mode == RLC_MODE_AM ) { + if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) { pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; } @@ -803,7 +816,6 @@ pdcp_data_ind( } - } /* Print octets of incoming data in hexadecimal form */ LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", @@ -839,13 +851,14 @@ pdcp_data_ind( #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) - else { - AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - } - + else { + AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + } #endif + } + free_mem_block(sdu_buffer_pP, __func__); if (ctxt_pP->enb_flag) { @@ -1458,8 +1471,12 @@ rrc_pdcp_config_asn1_req ( for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; - lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + if (MBMS_SessionInfo_p->sessionId_r9) + lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + else + lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; mch_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string +// mch_id = j; // can set the mch_id = i if (ctxt_pP->enb_flag) { @@ -1480,6 +1497,14 @@ rrc_pdcp_config_asn1_req ( } } + LOG_D(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], + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2], + drb_id, + action); + pdcp_config_req_asn1 ( ctxt_pP, NULL, // unused for MBMS @@ -2018,6 +2043,12 @@ void pdcp_layer_init(void) #endif } +#ifdef MBMS_MULTICAST_OUT + mbms_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (mbms_socket == -1) + LOG_W(PDCP, "Could not create RAW socket, MBMS packets will not be put to the network\n"); +#endif + LOG_I(PDCP, "PDCP layer has been initialized\n"); pdcp_output_sdu_bytes_to_write=0; @@ -2068,6 +2099,12 @@ void pdcp_layer_cleanup (void) { list_free (&pdcp_sdu_list); hashtable_destroy(pdcp_coll_p); +#ifdef MBMS_MULTICAST_OUT + if(mbms_socket != -1) { + close(mbms_socket); + mbms_socket = -1; + } +#endif } #ifdef PDCP_USE_RT_FIFO diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index b9e605ca24dbea29d60d414b835386c8cc9924c2..92409d96dcfc4f0eb877a33af061f87480a0440a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -760,10 +760,10 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), - pc5s_header.inst, - pc5s_header.rb_id, + pc5s_header->inst, + pc5s_header->rb_id, rab_id, - pc5s_header.data_size); + pc5s_header->data_size); pdcp_data_req( &ctxt, @@ -787,10 +787,10 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), - pc5s_header.inst, - pc5s_header.rb_id, + pc5s_header->inst, + pc5s_header->rb_id, rab_id, - pc5s_header.data_size); + pc5s_header->data_size); LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index ff49b2d056f12f2e07a6a642322411e0841c5398..8c557188a2a2e115300b7ea9d15ef4032da49e1e 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -208,7 +208,7 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_ #define rlc_mbms_ue_get_lcid_by_rb_id(uE_mOD,rB_iD) rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] #define rlc_mbms_ue_set_lcid_by_rb_id(uE_mOD,rB_iD,lOG_cH_iD) do { \ - AssertFatal(rB_iD<NB_RB_MAX, "INVALID RB ID %u", rB_iD); \ + AssertFatal(rB_iD<NB_RB_MBMS_MAX, "INVALID RB ID %u", rB_iD); \ rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \ } while (0); diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index aa00ffb773c876f4c8e99edac83394794e457822..8977e422b60591d100fd809aa36643c090469cb2 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -414,9 +414,13 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; - mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + if (MBMS_SessionInfo_p->sessionId_r9) + mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; + else + mbms_session_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; lc_id = mbms_session_id; mbms_service_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string +// mbms_service_id = j; // can set the mch_id = i if (ctxt_pP->enb_flag) { diff --git a/openair2/NETWORK_DRIVER/LITE/common.c b/openair2/NETWORK_DRIVER/LITE/common.c index 0d616d5764fa16e47ec5971b8f81346c54d110c8..2ae6f5279d12ce5f2be1f2b1d36ee59d5ddfbef2 100644 --- a/openair2/NETWORK_DRIVER/LITE/common.c +++ b/openair2/NETWORK_DRIVER/LITE/common.c @@ -333,7 +333,7 @@ void oai_nw_drv_common_class_wireless2ip(uint16_t dlen, printk("\n"); #endif //OAI_DRV_DEBUG_RECEIVE - netif_rx(skb); + netif_rx_ni(skb); #ifdef OAI_DRV_DEBUG_RECEIVE printk("[OAI_IP_DRV][%s] end\n",__FUNCTION__); #endif diff --git a/openair2/NETWORK_DRIVER/MESH/classifier.c b/openair2/NETWORK_DRIVER/MESH/classifier.c index 985bab946ecffc9241661b447e735fa09ab0d32e..a22ac2f20045b4457b9ec6adaeed72d931a0555a 100644 --- a/openair2/NETWORK_DRIVER/MESH/classifier.c +++ b/openair2/NETWORK_DRIVER/MESH/classifier.c @@ -410,7 +410,7 @@ struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb, #endif //NAS_DEBUG_CLASS //if ((dst = (unsigned int*)&(((struct rt6_info *)skbdst)->rt6i_gateway)) == 0){ - if ((dst = ((struct iphdr*)(skb_network_header(skb)))->daddr) == 0) { + if ( (dst = &((struct iphdr*)(skb_network_header(skb)))->daddr) == NULL) { printk("nas_CLASS_cx6: dst addr is null \n"); p = p->next; @@ -475,7 +475,7 @@ struct cx_entity *nas_CLASS_cx4(struct sk_buff *skb, if (skb!=NULL) { daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr; - if (daddr!=NULL) { + if (daddr!=0) { #ifdef NAS_DEBUG_CLASS printk("[NAS][CLASS][IPv4] Searching for %d.%d.%d.%d\n", diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c index d380b8a4d829cf31bf1369996d05de279cab73a5..738f05ad9922f4f17221e817f33df7a3e747ab96 100644 --- a/openair2/NETWORK_DRIVER/MESH/common.c +++ b/openair2/NETWORK_DRIVER/MESH/common.c @@ -53,17 +53,14 @@ void nas_COMMON_receive(uint16_t dlen, struct sk_buff *skb; struct ipversion *ipv; struct nas_priv *gpriv=netdev_priv(nasdev[inst]); - uint32_t odaddr,osaddr; //int i; unsigned char protocol; - unsigned char /**addr,*/ *daddr,*saddr,*ifaddr /*,sn*/; //struct udphdr *uh; //struct tcphdr *th; - uint16_t *cksum,check; struct iphdr *network_header; @@ -114,11 +111,12 @@ void nas_COMMON_receive(uint16_t dlen, // Make the third byte of both the source and destination equal to the fourth of the destination - + unsigned char * ifaddr, *saddr, daddr; daddr = (unsigned char *)&((struct iphdr *)skb->data)->daddr; odaddr = ((struct iphdr *)skb->data)->daddr; // sn = addr[3]; saddr = (unsigned char *)&((struct iphdr *)skb->data)->saddr; + uint32_t odaddr,osaddr; osaddr = ((struct iphdr *)skb->data)->saddr; if (daddr[0] == saddr[0]) {// same network @@ -219,6 +217,7 @@ void nas_COMMON_receive(uint16_t dlen, case IPPROTO_TCP: + uint16_t *cksum,check; cksum = (uint16_t*)&(((struct tcphdr*)(((char *)network_header + (network_header->ihl<<2))))->check); //check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, tcp_hdrlen(skb), IPPROTO_TCP, ~(*cksum)); @@ -309,7 +308,7 @@ void nas_COMMON_receive(uint16_t dlen, printk("\n"); #endif //NAS_DEBUG_RECEIVE - netif_rx(skb); + netif_rx_ni(skb); #ifdef NAS_DEBUG_RECEIVE printk("NAS_COMMON_RECEIVE: end\n"); #endif diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index f5d31742bc400c4cc055d8950ae633c65b9beec0..8b95e05cfcf063b8591fbd8af296b602af82e77e 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -241,7 +241,7 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1796) netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -306,7 +306,7 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1796) netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -324,7 +324,7 @@ static const struct net_device_ops nasmesh_netdev_ops = { .ndo_set_mac_address = NULL, .ndo_set_config = nas_set_config, .ndo_do_ioctl = nas_CTL_ioctl, -#if RHEL_RELEASE_CODE>=1797 +#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1797) .extended.ndo_change_mtu = nas_change_mtu, #else .ndo_change_mtu = nas_change_mtu, diff --git a/openair2/NETWORK_DRIVER/MESH/mesh.c b/openair2/NETWORK_DRIVER/MESH/mesh.c index 367e34cc4fb519265ad568e60292af048d0241c5..ed87bc05f89ae52f100881aa742d70b2789ae60a 100644 --- a/openair2/NETWORK_DRIVER/MESH/mesh.c +++ b/openair2/NETWORK_DRIVER/MESH/mesh.c @@ -30,7 +30,7 @@ ***************************************************************************/ - +#include <linux/version.h> #include "local.h" #include "proto_extern.h" @@ -155,10 +155,18 @@ void nas_mesh_start_default_sclassifier(struct cx_entity *cx,struct rb_entity *r } //--------------------------------------------------------------------------- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +void nas_mesh_timer(struct timer_list *t) +#else void nas_mesh_timer(unsigned long data) +#endif { //--------------------------------------------------------------------------- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) + struct nas_priv *gpriv=from_timer(gpriv, t, timer); + #else struct nas_priv *gpriv=(struct nas_priv *) data; + #endif uint8_t cxi; struct cx_entity *cx; struct rb_entity *rb; @@ -166,10 +174,14 @@ void nas_mesh_timer(unsigned long data) #ifdef NAS_DEBUG_TIMER printk("NAS_MESH_TIMER - begin \n"); #endif - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) +timer_setup(&gpriv->timer, nas_mesh_timer, 0); + mod_timer(&gpriv->timer, jiffies+NAS_TIMER_TICK); + #else (gpriv->timer).function=nas_mesh_timer; (gpriv->timer).expires=jiffies+NAS_TIMER_TICK; (gpriv->timer).data=data; + #endif return; diff --git a/openair2/NETWORK_DRIVER/MESH/proto_extern.h b/openair2/NETWORK_DRIVER/MESH/proto_extern.h index 844c5b41a4a3d9a9f99e454ef93d51977f37af05..2eae034257f291610ad0f765af37c5bda116b5cd 100644 --- a/openair2/NETWORK_DRIVER/MESH/proto_extern.h +++ b/openair2/NETWORK_DRIVER/MESH/proto_extern.h @@ -195,7 +195,6 @@ void nas_mesh_init(int inst //!< Instance ID ); -void nas_mesh_timer(unsigned long data); int nas_mesh_DC_receive(struct cx_entity *cx,struct nas_priv *gpriv); int nas_mesh_GC_receive(struct nas_priv *gpriv); diff --git a/openair2/NETWORK_DRIVER/MESH/tool.c b/openair2/NETWORK_DRIVER/MESH/tool.c index 2e8e68a17cfb821f44c72bdae0fed1754c7099e5..a8d359f9ff9a0851cc76a7fd0709a85293d1f8e5 100644 --- a/openair2/NETWORK_DRIVER/MESH/tool.c +++ b/openair2/NETWORK_DRIVER/MESH/tool.c @@ -679,11 +679,11 @@ void print_TOOL_pk_all(struct sk_buff *skb) switch (ntohs(skb->protocol)) { case ETH_P_IPV6: - print_TOOL_pk_ipv6((struct ipv6hdr *)skb->network_header); + print_TOOL_pk_ipv6((struct ipv6hdr *)skb_network_header(skb)); break; case ETH_P_IP: - print_TOOL_pk_ipv4((struct iphdr *)skb->network_header); + print_TOOL_pk_ipv4((struct iphdr *)skb_network_header(skb)); break; } } diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 84f425ef3c004646069f1e0496620a6cca4327a9..b21ca5f2dcc7bd9c8fab015f9f95d5b546fa4b77 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -222,7 +222,7 @@ skb_p->mark = rb_idP; printk("\n"); #endif //OAI_DRV_DEBUG_RECEIVE - netif_rx(skb_p); + netif_rx_ni(skb_p); #ifdef OAI_DRV_DEBUG_RECEIVE printk("[UE_IP_DRV][%s] end\n",__FUNCTION__); #endif diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index a7c96a8a22f201d19fe1dc2e63eaa59009745a92..d201732177733f67cc61cfc0ff877d06b21f7c6f 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -43,9 +43,6 @@ #include "flexran_agent_extern.h" -//#define RRC_DATA_REQ_DEBUG -//#define DEBUG_RRC 1 - extern RAN_CONTEXT_t RC; @@ -68,10 +65,9 @@ mac_rrc_data_req( uint8_t sfn = (uint8_t)((frameP>>2)&0xff); -#ifdef DEBUG_RRC - int i; - LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); -#endif + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); + } eNB_RRC_INST *rrc; rrc_eNB_carrier_data_t *carrier; @@ -96,15 +92,15 @@ mac_rrc_data_req( RC.rrc[Mod_idP]->carrier[CC_id].SIB1, RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1); -#ifdef DEBUG_RRC - LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP); + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP); - for (i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1; i++) { - LOG_T(RRC,"%x.",buffer_pP[i]); - } + for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); + } - LOG_T(RRC,"\n"); -#endif + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1); } // All RFN mod 8 transmit SIB2-3 in SF 5 @@ -113,15 +109,15 @@ mac_rrc_data_req( RC.rrc[Mod_idP]->carrier[CC_id].SIB23, RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23); -#ifdef DEBUG_RRC - LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP); + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP); - for (i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23; i++) { - LOG_T(RRC,"%x.",buffer_pP[i]); - } + for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); + } - LOG_T(RRC,"\n"); -#endif + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ return(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23); } else { return(0); @@ -193,20 +189,17 @@ mac_rrc_data_req( RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); -#ifdef DEBUG_RRC - LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); - for (i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) { - LOG_T(RRC,"%x.",buffer_pP[i]); - } + for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); + } - LOG_T(RRC,"\n"); -#endif + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ - return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); - // } - //else - //return(0); + return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); } #endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -329,7 +322,7 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, rntiP, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } -// rrc_mac_remove_ue(Mod_instP,rntiP); + rrc_mac_remove_ue(Mod_instP,rntiP); } void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP, diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index d3527b8a17e619119399ab1d557c1e4a89b2d653..3b7219af42913d844ca30f96a8029cc85aab60a6 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -42,7 +42,6 @@ #endif //#define RRC_DATA_REQ_DEBUG -//#define DEBUG_RRC 1 @@ -61,10 +60,7 @@ mac_rrc_data_req_ue( //-------------------------------------------------------------------------- { -#ifdef DEBUG_RRC - int i; - LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); -#endif + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 373a3efa48b81426d0032aa2372627be31478545..d70550c82da87d81b9ca023af7210e11b8e26cb3 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -91,7 +91,6 @@ #define msg printf #endif -//#define XER_PRINT typedef struct xer_sprint_string_s { char *string; @@ -346,8 +345,13 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, { // SystemInformation_t systemInformation; - PLMN_IdentityInfo_t PLMN_identity_info; - MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; +#if defined(ENABLE_ITTI) + int num_plmn = configuration->num_plmn; +#else + int num_plmn = 1; +#endif + PLMN_IdentityInfo_t PLMN_identity_info[num_plmn]; + MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; asn_enc_rval_t enc_rval; SchedulingInfo_t schedulingInfo; SIB_Type_t sib_type; @@ -355,6 +359,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, uint8_t *buffer = carrier->SIB1; BCCH_DL_SCH_Message_t *bcch_message = &carrier->siblock1; SystemInformationBlockType1_t **sib1 = &carrier->sib1; + int i; memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_t)); @@ -364,66 +369,67 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, *sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1; - memset(&PLMN_identity_info,0,sizeof(PLMN_IdentityInfo_t)); + memset(PLMN_identity_info,0,num_plmn * sizeof(PLMN_IdentityInfo_t)); memset(&schedulingInfo,0,sizeof(SchedulingInfo_t)); memset(&sib_type,0,sizeof(SIB_Type_t)); + /* as per TS 36.311, up to 6 PLMN_identity_info are allowed in list -> add one by one */ + for (i = 0; i < configuration->num_plmn; ++i) { + PLMN_identity_info[i].plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); + memset(PLMN_identity_info[i].plmn_Identity.mcc,0,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); - - PLMN_identity_info.plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info.plmn_Identity.mcc)); - memset(PLMN_identity_info.plmn_Identity.mcc,0,sizeof(*PLMN_identity_info.plmn_Identity.mcc)); - - asn_set_empty(&PLMN_identity_info.plmn_Identity.mcc->list);//.size=0; + asn_set_empty(&PLMN_identity_info[i].plmn_Identity.mcc->list);//.size=0; #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; + dummy_mcc[i][0] = (configuration->mcc[i] / 100) % 10; + dummy_mcc[i][1] = (configuration->mcc[i] / 10) % 10; + dummy_mcc[i][2] = (configuration->mcc[i] / 1) % 10; #else - dummy_mcc[0] = 0; - dummy_mcc[1] = 0; - dummy_mcc[2] = 1; + dummy_mcc[i][0] = 0; + dummy_mcc[i][1] = 0; + dummy_mcc[i][2] = 1; #endif - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[0]); - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[1]); - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[2]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][2]); - PLMN_identity_info.plmn_Identity.mnc.list.size=0; - PLMN_identity_info.plmn_Identity.mnc.list.count=0; + PLMN_identity_info[i].plmn_Identity.mnc.list.size=0; + PLMN_identity_info[i].plmn_Identity.mnc.list.count=0; #if defined(ENABLE_ITTI) - if (configuration->mnc >= 100) { - dummy_mnc[0] = (configuration->mnc / 100) % 10; - dummy_mnc[1] = (configuration->mnc / 10) % 10; - dummy_mnc[2] = (configuration->mnc / 1) % 10; - } else { - if (configuration->mnc_digit_length == 2) { - dummy_mnc[0] = (configuration->mnc / 10) % 10; - dummy_mnc[1] = (configuration->mnc / 1) % 10; - dummy_mnc[2] = 0xf; + if (configuration->mnc[i] >= 100) { + dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 10; + dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10; } else { - dummy_mnc[0] = (configuration->mnc / 100) % 100; - dummy_mnc[1] = (configuration->mnc / 10) % 10; - dummy_mnc[2] = (configuration->mnc / 1) % 10; + if (configuration->mnc_digit_length[i] == 2) { + dummy_mnc[i][0] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][1] = (configuration->mnc[i] / 1) % 10; + dummy_mnc[i][2] = 0xf; + } else { + dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 100; + dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10; + } } - } #else - dummy_mnc[0] = 0; - dummy_mnc[1] = 1; - dummy_mnc[2] = 0xf; + dummy_mnc[i][0] = 0; + dummy_mnc[i][1] = 1; + dummy_mnc[i][2] = 0xf; #endif - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[0]); - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][1]); - if (dummy_mnc[2] != 0xf) { - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[2]); - } + if (dummy_mnc[i][2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][2]); + } - //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); - PLMN_identity_info.cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; + //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); + PLMN_identity_info[i].cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; - ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info); + ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info[i]); + } // 16 bits @@ -1356,9 +1362,9 @@ uint8_t do_SIB23(uint8_t Mod_id, } #endif -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); + } enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message, NULL, (void*)bcch_message, @@ -1610,9 +1616,9 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio break; } -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, @@ -1674,10 +1680,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension)); - if(usim_test == 0) - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 2; - else - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1; + rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME = NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME)); @@ -2168,9 +2171,9 @@ do_RRCConnectionSetup( #endif -#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_DL_CCCH_Message, (void*)&dl_ccch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, @@ -2243,9 +2246,9 @@ do_SecurityModeCommand( dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, NULL, (void*)&dl_dcch_msg, @@ -2323,9 +2326,9 @@ do_UECapabilityEnquiry( ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, NULL, (void*)&dl_dcch_msg, @@ -2542,9 +2545,9 @@ do_RRCConnectionReconfiguration( enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)&dl_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)&dl_dcch_msg); + } #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) @@ -2745,9 +2748,9 @@ do_RRCConnectionReestablishment( rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nonCriticalExtension = 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_DL_CCCH_Message, (void*)&dl_ccch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, @@ -2807,9 +2810,9 @@ do_RRCConnectionReestablishmentReject( // RRCConnectionReestablishmentReject rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; -#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_DL_CCCH_Message, (void*)&dl_ccch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, @@ -2870,9 +2873,9 @@ do_RRCConnectionReject( /* let's put a wait time of 1s for the moment */ rrcConnectionReject->criticalExtensions.choice.c1.choice.rrcConnectionReject_r8.waitTime = 1; -#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_DL_CCCH_Message, (void*)&dl_ccch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, @@ -3064,9 +3067,9 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, */ ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->pmch_InfoList_r9.list,pmch_Info_1); -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_MCCH_Message,(void*)mcch_message); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_MCCH_Message,(void*)mcch_message); + } enc_rval = uper_encode_to_buffer(&asn_DEF_MCCH_Message, NULL, (void*)mcch_message, @@ -3317,6 +3320,7 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin &paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI); paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI.bits_unused = 0; } else if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_imsi) { + paging_record_p->ue_Identity.present = PagingUE_Identity_PR_imsi; IMSI_Digit_t imsi_digit[21]; for (j = 0; j< ue_paging_identity.choice.imsi.length; j++) { /* IMSI size */ imsi_digit[j] = (IMSI_Digit_t)ue_paging_identity.choice.imsi.buffer[j]; @@ -3342,9 +3346,9 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_PCCH_Message, (void*)&pcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_PCCH_Message, (void*)&pcch_msg); + } return((enc_rval.encoded+7)/8); } @@ -3507,9 +3511,9 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) } UECapability.UE_EUTRA_Capability = UE_EUTRA_Capability; -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_UE_EUTRA_Capability,(void *)UE_EUTRA_Capability); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_UE_EUTRA_Capability,(void *)UE_EUTRA_Capability); + } enc_rval = uper_encode_to_buffer(&asn_DEF_UE_EUTRA_Capability, NULL, (void*)UE_EUTRA_Capability, diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c index cdfc1ac0f355ef068e18d677ddf2e4ccf371b00f..20962f3ca159741224898017637a3400df005c90 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c @@ -136,7 +136,7 @@ uint8_t do_MIB_NB_IoT( carrier->MIB_NB_IoT, 100); if(enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -382,9 +382,9 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); -#ifdef XER_PRINT //generate xml files - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); + } enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, @@ -394,7 +394,7 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, 100); if (enc_rval.encoded > 0){ - LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC,"ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -667,9 +667,9 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, sib3_NB_part); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); + } enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, NULL, (void*)bcch_message, @@ -887,9 +887,9 @@ uint8_t do_RRCConnectionSetup_NB_IoT( rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT; rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = 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_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, @@ -897,7 +897,7 @@ uint8_t do_RRCConnectionSetup_NB_IoT( 100); if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -939,16 +939,16 @@ uint8_t do_SecurityModeCommand_NB_IoT( = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; //only changed "asn_DEF_DL_DCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, NULL, (void*)&dl_dcch_msg_NB_IoT, buffer, 100); if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -1001,16 +1001,16 @@ uint8_t do_UECapabilityEnquiry_NB_IoT( //no ue_CapabilityRequest (list of RAT_Type) //only changed "asn_DEF_DL_DCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, NULL, (void*)&dl_dcch_msg_NB_IoT, buffer, 100); if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -1105,14 +1105,14 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( buffer, RRC_BUF_SIZE); if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed %s, %li\n", + LOG_E(RRC, "ASN1 message encoding failed %s, %li\n", enc_rval.failed_type->name, enc_rval.encoded); } //changed only asn_DEF_DL_DCCH_Message_NB -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); + } //#if defined(ENABLE_ITTI) //# if !defined(DISABLE_XER_SPRINT)... @@ -1143,16 +1143,16 @@ uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; //Only change in "asn_DEF_DL_CCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, buffer, 100); if (enc_rval.encoded <= 0) { - LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC,"ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -1214,16 +1214,16 @@ uint8_t do_RRCConnectionReject_NB_IoT( RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; //Only Modified "asn_DEF_DL_CCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); + } enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, buffer, 100); if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %ld)!\n", + LOG_E(RRC, "ASN1 message encoding failed (%s, %ld)!\n", enc_rval.failed_type->name, enc_rval.encoded); } @@ -1351,13 +1351,13 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( RRC_BUF_SIZE); if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\n", + LOG_E(RRC, "ASN1 message encoding failed (%s, %li)!\n", enc_rval.failed_type->name, enc_rval.encoded); } -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); + } #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index c23bf12d52a8b533bb54f6023025ee1566fba317..b111f77871c1292afa40a366b8b2506dcfd2e23b 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -99,10 +99,6 @@ int send_ue_information = 0; // for malloc_clear #include "PHY/defs_UE.h" -//#define XER_PRINT - - - extern void pdcp_config_set_security( const protocol_ctxt_t* const ctxt_pP, pdcp_t * const pdcp_pP, @@ -733,9 +729,9 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co (uint8_t*)Srb_info->Rx_buffer.Payload, 100,0,0); -#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_DL_CCCH_Message,(void*)dl_ccch_msg); + } #if defined(ENABLE_ITTI) # if defined(DISABLE_ITTI_XER_PRINT) @@ -1931,9 +1927,9 @@ rrc_ue_process_securityModeCommand( AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + } #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) @@ -2042,9 +2038,9 @@ rrc_ue_process_ueCapabilityEnquiry( AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + } #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) @@ -2429,9 +2425,9 @@ rrc_ue_decode_dcch( (uint8_t*)Buffer, RRC_BUF_SIZE,0,0); -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)dl_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)dl_dcch_msg); + } #if defined(ENABLE_ITTI) # if defined(DISABLE_ITTI_XER_PRINT) @@ -4560,9 +4556,9 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB return -1; } -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_MCCH_Message, (void*)mcch); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_MCCH_Message, (void*)mcch); + } if (mcch->message.present == MCCH_MessageType_PR_c1) { LOG_D(RRC,"[UE %d] Found mcch message \n", @@ -4594,10 +4590,30 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB //----------------------------------------------------------------------------- void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) { + uint8_t i; protocol_ctxt_t ctxt; LOG_I(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d is %d\n", ue_mod_idP, frameP, mbsfn_sync_area, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9.list.count); + + // Configure commonSF_Alloc + for(i=0; i< UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.count;i++){ + LOG_W(RRC,"[UE %d] Frame %d, commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x,%x,%x)\n", + ue_mod_idP, frameP, + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationPeriod<<1, + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationOffset, + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[0], + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[1], + UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[2]); + UE_mac_inst[ue_mod_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]; + } + LOG_W(RRC,"[UE %d] Frame %d, commonSF_AllocPeriod_r9 %drf \n", + ue_mod_idP, frameP, + 4<<UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9); + + // Configure commonSF_AllocPeriod + UE_mac_inst[ue_mod_idP].commonSF_AllocPeriod_r9 = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9; + // store to MAC/PHY necessary parameters for receiving MTCHs rrc_mac_config_req_ue(ue_mod_idP,0,eNB_index, @@ -5558,9 +5574,9 @@ void *rrc_control_socket_thread_fct(void *arg) //process the message switch (sl_ctrl_msg_recv->type) { case SESSION_INIT_REQ: -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - LOG_UI(RRC,"Received SessionInitializationRequest on socket from ProSe App (msg type: %d)\n", sl_ctrl_msg_recv->type); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + LOG_UI(RRC,"Received SessionInitializationRequest on socket from ProSe App (msg type: %d)\n", sl_ctrl_msg_recv->type); + } //TODO: get SL_UE_STATE from lower layer LOG_I(RRC,"Send UEStateInformation to ProSe App \n"); @@ -5579,12 +5595,12 @@ LOG_DEBUG_END exit(EXIT_FAILURE); } -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; - ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; - LOG_UI(RRC,"[UEStateInformation] msg type: %d\n",ptr_ctrl_msg->type); - LOG_UI(RRC,"[UEStateInformation] UE state: %d\n",ptr_ctrl_msg->sidelinkPrimitive.ue_state); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_UI(RRC,"[UEStateInformation] msg type: %d\n",ptr_ctrl_msg->type); + LOG_UI(RRC,"[UEStateInformation] UE state: %d\n",ptr_ctrl_msg->sidelinkPrimitive.ue_state); + } /* if (enable_notification > 0) { //create thread to send status notification (for testing purpose, status notification will be sent e.g., every 20 seconds) pthread_t notification_thread; @@ -5599,12 +5615,12 @@ LOG_DEBUG_END sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id; groupL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id; -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - LOG_UI(RRC,"[GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); - LOG_UI(RRC,"[GroupCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); - LOG_UI(RRC,"[GroupCommunicationEstablishReq] group Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); - LOG_UI(RRC,"[GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress)); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + LOG_UI(RRC,"[GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_UI(RRC,"[GroupCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); + LOG_UI(RRC,"[GroupCommunicationEstablishReq] group Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); + LOG_UI(RRC,"[GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress)); + } //store sourceL2Id/groupL2Id UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; @@ -5764,20 +5780,20 @@ LOG_DEBUG_END exit(EXIT_FAILURE); } -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; - ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; - LOG_UI(RRC,"[GroupCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); - LOG_UI(RRC,"[GroupCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_UI(RRC,"[GroupCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); + LOG_UI(RRC,"[GroupCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); + } break; case GROUP_COMMUNICATION_RELEASE_REQ: printf("-----------------------------------\n"); -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - LOG_UI(RRC,"[GroupCommunicationReleaseRequest] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); - LOG_UI(RRC,"[GroupCommunicationReleaseRequest] Slrb Id: %i\n",sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + LOG_UI(RRC,"[GroupCommunicationReleaseRequest] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_UI(RRC,"[GroupCommunicationReleaseRequest] Slrb Id: %i\n",sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id); + } //reset groupL2ID from MAC LAYER UE_rrc_inst[module_id].groupL2Id = 0x00000000; sourceL2Id = UE_rrc_inst[module_id].sourceL2Id; @@ -5849,11 +5865,11 @@ LOG_DEBUG_END sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.sourceL2Id; destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.destinationL2Id; -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - LOG_UI(RRC,"[DirectCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); - LOG_UI(RRC,"[DirectCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); - LOG_UI(RRC,"[DirectCommunicationEstablishReq] destination Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + LOG_UI(RRC,"[DirectCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_UI(RRC,"[DirectCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); + LOG_UI(RRC,"[DirectCommunicationEstablishReq] destination Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); + } //store sourceL2Id/destinationL2Id UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; @@ -6013,27 +6029,27 @@ LOG_DEBUG_END } -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; - ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; - LOG_UI(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); - LOG_UI(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + struct sidelink_ctrl_element *ptr_ctrl_msg = NULL; + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_UI(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); + LOG_UI(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); + } break; case PC5S_ESTABLISH_REQ: - type = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type; - sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id; -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - LOG_UI(RRC,"[PC5EstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); - LOG_UI(RRC,"[PC5EstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type); //RX/TX - LOG_UI(RRC,"[PC5EstablishReq] source Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id); -LOG_DEBUG_END + type = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type; + sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id; + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + LOG_UI(RRC,"[PC5EstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_UI(RRC,"[PC5EstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type); //RX/TX + LOG_UI(RRC,"[PC5EstablishReq] source Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id); + } if (type > 0) { destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id; -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) - LOG_UI(RRC,"[PC5EstablishReq] destination Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id); -LOG_DEBUG_END + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ + LOG_UI(RRC,"[PC5EstablishReq] destination Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id); + } } //store sourceL2Id/destinationL2Id @@ -6244,9 +6260,9 @@ LOG_DEBUG_END case PC5_DISCOVERY_MESSAGE: -LOG_DEBUG_BEGIN(DEBUG_CTRLSOCKET) + if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)){ LOG_UI(RRC,"[PC5DiscoveryMessage] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); -LOG_DEBUG_END + } //prepare SL_Discovery buffer if (UE_rrc_inst) { memcpy((void*)&UE_rrc_inst[module_id].SL_Discovery[0].Tx_buffer.Payload[0], (void*)&sl_ctrl_msg_recv->sidelinkPrimitive.pc5_discovery_message.payload[0], PC5_DISCOVERY_PAYLOAD_SIZE); diff --git a/openair2/RRC/LTE/rrc_common.c b/openair2/RRC/LTE/rrc_common.c index d18c43d6cf38261bec43af35689d61aad8df0c0f..cf0196441e21d118e4ff8e64830bd85de27aa052 100644 --- a/openair2/RRC/LTE/rrc_common.c +++ b/openair2/RRC/LTE/rrc_common.c @@ -43,7 +43,6 @@ #include "rrc_eNB_UE_context.h" #include "common/ran_context.h" -#define DEBUG_RRC 1 extern RAN_CONTEXT_t RC; extern UE_MAC_INST *UE_mac_inst; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index e21cb9255a6a0cc7cb275b3c21230383ae987820..ae87075489f970602c2e34f0e04492368ef7a97d 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -699,13 +699,6 @@ typedef struct eNB_RRC_INST_s { #if defined(ENABLE_ITTI) RrcConfigurationReq configuration; #endif - // other PLMN parameters - /// Mobile country code - int mcc; - /// Mobile network code - int mnc; - /// number of mnc digits - int mnc_digit_length; // other RAN parameters int srb1_timer_poll_retransmit; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index b0b444084c19b7d106a81c6246c1b5883bb6c6de..00f814b8b17de3f56721bb1847c58b91ad3004e2 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -85,6 +85,8 @@ # else # include "../../S1AP/s1ap_eNB.h" # endif +#else +# define EPC_MODE_ENABLED 0 #endif #include "pdcp.h" @@ -100,7 +102,6 @@ #include "SIMULATION/TOOLS/sim.h" // for taus -//#define XER_PRINT extern RAN_CONTEXT_t RC; @@ -839,11 +840,6 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* protocol_ctxt_t ctxt; -#if !defined(ENABLE_USE_MME) - module_id_t ue_module_id; - /* avoid gcc warnings */ - (void)ue_module_id; -#endif rnti_t rnti = ue_context_pP->ue_context.rnti; if (enb_mod_idP >= NB_eNB_INST) { LOG_I(RRC, "eNB inst invalid (%d/%d) for UE %x!\n",enb_mod_idP, NB_eNB_INST,rnti); @@ -858,20 +854,21 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0,enb_mod_idP); LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", enb_mod_idP, rnti); -#if defined(ENABLE_USE_MME) - if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && - (mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti); - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: connection with ue lost - /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) - * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before - * triggering the S1 UE Context Release Request procedure - * in order to allow the UE to perform the NAS recovery - * procedure, see TS 23.401 [17]. - */ - return; + if(EPC_MODE_ENABLED) { + + if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && + (mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: connection with ue lost + /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) + * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before + * triggering the S1 UE Context Release Request procedure + * in order to allow the UE to perform the NAS recovery + * procedure, see TS 23.401 [17]. + */ + return; } -#endif + } // add UE info to freeList LOG_I(RRC, "put UE %x into freeList\n", rnti); put_UE_in_freelist(enb_mod_idP, rnti, 1); @@ -1018,17 +1015,13 @@ rrc_eNB_process_RRCConnectionSetupComplete( T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); -#if defined(ENABLE_USE_MME) - if (EPC_MODE_ENABLED == 1) { // Forward message to S1AP layer rrc_eNB_send_S1AP_NAS_FIRST_REQ( ctxt_pP, ue_context_pP, rrcConnectionSetupComplete); - } else -#endif - { + } else { // RRC loop back (no S1AP), send SecurityModeCommand to UE rrc_eNB_generate_SecurityModeCommand( ctxt_pP, @@ -1058,16 +1051,8 @@ rrc_eNB_generate_SecurityModeCommand( ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.integrity_algorithm); -#ifdef RRC_MSG_PRINT - uint16_t i=0; - LOG_F(RRC,"[MSG] RRC Security Mode Command\n"); - - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", @@ -1166,9 +1151,6 @@ rrc_eNB_generate_RRCConnectionReject( ) //----------------------------------------------------------------------------- { -#ifdef RRC_MSG_PRINT - int cnt; -#endif T(T_ENB_RRC_CONNECTION_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -1177,15 +1159,10 @@ rrc_eNB_generate_RRCConnectionReject( do_RRCConnectionReject(ctxt_pP->module_id, (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRCConnectionReject\n"); - - for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) { - LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->Srb0.Tx_buffer.Payload)[cnt]); - } - - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC, + (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + "[MSG] RRCConnectionReject\n"); MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, @@ -1230,17 +1207,11 @@ rrc_eNB_generate_RRCConnectionReestablishment( rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), SRB_configList, &ue_context_pP->ue_context.physicalConfigDedicated); - -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRCConnectionReestablishment\n"); - - for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) { - LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload)[cnt]); - } - - LOG_F(RRC,"\n"); -#endif - + LOG_DUMPMSG(RRC,DEBUG_RRC, + (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + "[MSG] RRCConnectionReestablishment\n" + ); // configure SRB1 for UE if (*SRB_configList != NULL) { @@ -1356,10 +1327,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( struct SRB_ToAddMod *SRB2_config = NULL; struct DRB_ToAddMod *DRB_config = NULL; int i = 0; -# if defined(ENABLE_USE_MME) - int j = 0; - hashtable_rc_t h_rc; -#endif uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; MeasObjectToAddModList_t *MeasObj_list = NULL; @@ -1450,59 +1417,61 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.Srb1.Active = 1; //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; -# if defined(ENABLE_USE_MME) - rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL; - uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; - eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]; - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p); - if (h_rc == HASH_TABLE_OK) { - rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; +#if defined(ENABLE_USE_MME) + hashtable_rc_t h_rc; + int j; + rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL; + uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; + eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]; + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p); + if (h_rc == HASH_TABLE_OK) { + rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; + } } - } - if (ue_initial_id != 0) { - h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p); - if (h_rc == HASH_TABLE_OK) { - rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; + if (ue_initial_id != 0) { + h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p); + if (h_rc == HASH_TABLE_OK) { + rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; + } } - } - gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + gtpv1u_enb_create_tunnel_req_t create_tunnel_req; - /* Save e RAB information for later */ - memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); + /* Save e RAB information for later */ + memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); - for (j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) { - create_tunnel_req.eps_bearer_id[j] = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; - create_tunnel_req.sgw_S1u_teid[j] = ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + for ( j = 0, i = 0; i < NB_RB_MAX; i++) { + if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) { + create_tunnel_req.eps_bearer_id[j] = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + create_tunnel_req.sgw_S1u_teid[j] = ue_context_pP->ue_context.e_rab[i].param.gtp_teid; - memcpy(&create_tunnel_req.sgw_addr[j], - &ue_context_pP->ue_context.e_rab[i].param.sgw_addr, - sizeof(transport_layer_addr_t)); - j++; + memcpy(&create_tunnel_req.sgw_addr[j], + &ue_context_pP->ue_context.e_rab[i].param.sgw_addr, + sizeof(transport_layer_addr_t)); + j++; + } } - } - create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above - create_tunnel_req.num_tunnels = j; + create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above + create_tunnel_req.num_tunnels = j; - gtpv1u_update_s1u_tunnel( - ctxt_pP->instance, - &create_tunnel_req, - reestablish_rnti); + gtpv1u_update_s1u_tunnel( + ctxt_pP->instance, + &create_tunnel_req, + reestablish_rnti); #endif /* Update RNTI in ue_context */ ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else ue_context_pP->ue_context.rnti = ctxt_pP->rnti; -# if defined(ENABLE_USE_MME) - uint8_t send_security_mode_command = FALSE; - rrc_pdcp_config_security( - ctxt_pP, - ue_context_pP, - send_security_mode_command); - LOG_D(RRC, "set security successfully \n"); +#if defined(ENABLE_USE_MME) + uint8_t send_security_mode_command = FALSE; + rrc_pdcp_config_security( + ctxt_pP, + ue_context_pP, + send_security_mode_command); + LOG_D(RRC, "set security successfully \n"); #endif // Measurement ID list MeasId_list = CALLOC(1, sizeof(*MeasId_list)); @@ -1869,15 +1838,9 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( , (SCellToAddMod_r10_t*)NULL #endif ); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration\n"); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); - //////////////////////////////////////// -#endif #if defined(ENABLE_ITTI) @@ -1977,9 +1940,6 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( ) //----------------------------------------------------------------------------- { -#ifdef RRC_MSG_PRINT - int cnt; -#endif int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); if(UE_id != -1){ RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; @@ -1997,15 +1957,11 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( do_RRCConnectionReestablishmentReject(ctxt_pP->module_id, (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRCConnectionReestablishmentReject\n"); - - for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) { - LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload)[cnt]); - } + LOG_DUMPMSG(RRC,DEBUG_RRC, + (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + "[MSG] RRCConnectionReestablishmentReject\n"); - LOG_F(RRC,"\n"); -#endif MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, @@ -2336,15 +2292,8 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co #endif ); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Connection Reconfiguration\n"); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); - //////////////////////////////////////// -#endif #if defined(ENABLE_ITTI) @@ -2606,15 +2555,8 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons #endif ); - -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); - //////////////////////////////////////// -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration\n"); #if defined(ENABLE_ITTI) @@ -2731,15 +2673,8 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ #endif ); ue_context_pP->ue_context.e_rab_release_command_flag = 1; - -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); - //////////////////////////////////////// -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration\n"); #if defined(ENABLE_ITTI) /* Free all NAS PDUs */ @@ -3460,15 +3395,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons , (SCellToAddMod_r10_t*)NULL #endif ); - -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); - //////////////////////////////////////// -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration\n"); #if defined(ENABLE_ITTI) @@ -4052,15 +3980,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt , (SCellToAddMod_r10_t*)NULL #endif ); - -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); - for (i = 0; i < size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - LOG_F(RRC,"\n"); - //////////////////////////////////////// -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration\n"); #if defined(ENABLE_ITTI) @@ -5438,11 +5359,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( #ifdef PDCP_USE_NETLINK int oip_ifup = 0; int dest_ip_offset = 0; - module_id_t ue_module_id = -1; /* avoid gcc warnings */ (void)oip_ifup; (void)dest_ip_offset; - (void)ue_module_id; #endif uint8_t *kRRCenc = NULL; @@ -5585,6 +5504,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id + 1); // fourth octet if (oip_ifup == 0) { // interface is up --> send a config the DRB + module_id_t ue_module_id; dest_ip_offset = 8; LOG_I(OIP, "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", @@ -5754,16 +5674,10 @@ rrc_eNB_generate_RRCConnectionSetup( SRB_configList, &ue_context_pP->ue_context.physicalConfigDedicated); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Setup\n"); - - for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) { - LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->Srb0.Tx_buffer.Payload)[cnt]); - } - - LOG_F(RRC,"\n"); - ////////////////////////////////// -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC, + (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + "[MSG] RRC Connection Setup\n"); // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE @@ -6111,15 +6025,10 @@ rrc_eNB_decode_ccch( T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reestablishment Request\n"); - - for (i = 0; i < Srb_info->Rx_buffer.payload_size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Srb_info->Rx_buffer.Payload)[i]); - } + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), + Srb_info->Rx_buffer.payload_size, + "[MSG] RRC Connection Reestablishment Request\n"); - LOG_F(RRC,"\n"); -#endif LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) --> RRC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); @@ -6336,15 +6245,10 @@ rrc_eNB_decode_ccch( T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Request\n"); - - for (i = 0; i < Srb_info->Rx_buffer.payload_size; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Srb_info->Rx_buffer.Payload)[i]); - } + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), + Srb_info->Rx_buffer.payload_size, + "[MSG] RRC Connection Request\n"); - LOG_F(RRC,"\n"); -#endif LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB --- MAC_DATA_IND (rrcConnectionRequest on SRB0) --> RRC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); @@ -6631,36 +6535,7 @@ rrc_eNB_decode_dcch( sdu_sizeP, 0, 0); - /* -#if defined(ENABLE_ITTI) -# if defined(DISABLE_ITTI_XER_PRINT) - { - MessageDef *message_p; - - message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_UL_DCCH_MESSAGE); - memcpy(&message_p->ittiMsg, (void *)ul_dcch_msg, sizeof(RrcUlDcchMessage)); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, message_p); - } -# else - { - char message_string[10000]; - size_t message_string_size; - if ((message_string_size = - xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg)) >= 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized(TASK_RRC_ENB, RRC_UL_DCCH, message_string_size + sizeof(IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif - */ { for (i = 0; i < sdu_sizeP; i++) { LOG_T(RRC, "%x.", Rx_sdu[i]); @@ -6714,15 +6589,9 @@ rrc_eNB_decode_dcch( LOG_I(RRC, "Processing RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reconfiguration Complete\n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Rx_sdu),sdu_sizeP, + "[MSG] RRC Connection Reconfiguration Complete\n"); - LOG_F(RRC,"\n"); -#endif MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -6745,42 +6614,42 @@ rrc_eNB_decode_dcch( RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) { /*NN: revise the condition */ /*FK: left the condition as is for the case MME is used (S1 mode) but setting dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/ -#if defined(ENABLE_USE_MME) - if (ue_context_p->ue_context.Status == RRC_RECONFIGURED){ - dedicated_DRB = 1; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - //clear - int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); - if(UE_id == -1){ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); - break; - } - if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1){ - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - dedicated_DRB = 2; - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; - } - } else { - dedicated_DRB = 0; - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - } - ue_context_p->ue_context.reestablishment_xid = -1; -#else - dedicated_DRB = 1; - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); -#endif + if (EPC_MODE_ENABLED) { + if (ue_context_p->ue_context.Status == RRC_RECONFIGURED){ + dedicated_DRB = 1; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + //clear + int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); + if(UE_id == -1){ + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + break; + } + if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1){ + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + dedicated_DRB = 2; + RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; + } + } else { + dedicated_DRB = 0; + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + } + ue_context_p->ue_context.reestablishment_xid = -1; + } else { + dedicated_DRB = 1; + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + } rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP, @@ -6789,14 +6658,13 @@ rrc_eNB_decode_dcch( //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); } } #if defined(ENABLE_ITTI) -# if defined(ENABLE_USE_MME) - if (EPC_MODE_ENABLED == 1) { +#if defined(ENABLE_USE_MME) if (dedicated_DRB == 1){ // rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, // ue_context_p, @@ -6861,14 +6729,12 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } } } - } +#endif #else // establish a dedicated bearer if (dedicated_DRB == 0 ) { // ue_context_p->ue_context.e_rab[0].status = E_RAB_STATUS_ESTABLISHED; rrc_eNB_reconfigure_DRBs(ctxt_pP,ue_context_p); } - -#endif #endif break; @@ -6876,15 +6742,8 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection Reestablishment Complete\n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Connection Reestablishment Complete\n"); MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -6945,7 +6804,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (mac_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } @@ -6963,15 +6822,8 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { LOG_I(RRC, "Processing RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Connection SetupComplete\n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Connection SetupComplete\n"); MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -7005,7 +6857,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } @@ -7023,15 +6875,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { LOG_I(RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Security Mode Complete\n"); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Security Mode Complete\n"); - for (i = 0; i < sdu_sizeP; i++) eNB->pusch_vars[UE_id]{ - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - - LOG_F(RRC,"\n"); -#endif MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -7053,9 +6899,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); + } // confirm with PDCP about the security mode for DCCH //rrc_pdcp_config_req (enb_mod_idP, frameP, 1,CONFIG_ACTION_SET_SECURITY_MODE, (ue_mod_idP * NB_RB_MAX) + DCCH, 0x77); // continue the procedure @@ -7068,15 +6914,8 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { T(T_ENB_RRC_SECURITY_MODE_FAILURE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC Security Mode Failure\n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Security Mode Failure\n"); MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -7094,9 +6933,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); + } // cancel the security mode in PDCP // followup with the remaining procedure @@ -7112,15 +6951,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { LOG_I(RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC UECapablility Information \n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC UECapablility Information\n"); MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -7142,9 +6975,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); + } 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); @@ -7161,9 +6994,9 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { 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); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); + } if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n", @@ -7174,22 +7007,22 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ue_context_p->ue_context.UE_Capability = 0; } -#if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { - if (EPC_MODE_ENABLED == 1) { - rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } -#else - ue_context_p->ue_context.nb_of_e_rabs = 1; - for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++){ - ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; - ue_context_p->ue_context.e_rab[i].param.e_rab_id = 1+i; - ue_context_p->ue_context.e_rab[i].param.qos.qci=9; + if (EPC_MODE_ENABLED == 1) { + rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, + ue_context_p, + ul_dcch_msg); + } + } else { + ue_context_p->ue_context.nb_of_e_rabs = 1; + for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++){ + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; + ue_context_p->ue_context.e_rab[i].param.e_rab_id = 1+i; + ue_context_p->ue_context.e_rab[i].param.qos.qci=9; + } + ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs; } - ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs; -#endif rrc_eNB_generate_defaultRRCConnectionReconfiguration(ctxt_pP, ue_context_p, @@ -7212,16 +7045,8 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } LOG_D(RRC,"[MSG] RRC UL Information Transfer \n"); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] RRC UL Information Transfer \n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - - LOG_F(RRC,"\n"); -#endif - + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC UL Information Transfer \n"); MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -7233,15 +7058,11 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ue_context_p->ue_context.rnti, sdu_sizeP); -#if defined(ENABLE_USE_MME) - if (EPC_MODE_ENABLED == 1) { rrc_eNB_send_S1AP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg); } - -#endif break; case UL_DCCH_MessageType__c1_PR_counterCheckResponse: @@ -7307,15 +7128,8 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); -#ifdef RRC_MSG_PRINT - LOG_F(RRC,"[MSG] SidelinkUEInformation\n"); - - for (i = 0; i < sdu_sizeP; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)Rx_sdu)[i]); - } - - LOG_F(RRC,"\n"); -#endif + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC SidelinkUEInformation \n"); MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, @@ -7387,29 +7201,24 @@ void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP, rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0); } - //----------------------------------------------------------------------------- -void* -rrc_enb_task( - void* args_p -) -//----------------------------------------------------------------------------- -{ - MessageDef *msg_p; - const char *msg_name_p; - instance_t instance; - int result; - SRB_INFO *srb_info_p; - int CC_id; - - protocol_ctxt_t ctxt; - +void rrc_enb_init(void) { pthread_mutex_init(&lock_ue_freelist, NULL); pthread_mutex_init(&rrc_release_freelist, NULL); memset(&rrc_release_info,0,sizeof(RRC_release_list_t)); - 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(void *notUsed) { + MessageDef *msg_p; + const char *msg_name_p; + instance_t instance; + int result; + SRB_INFO *srb_info_p; + int CC_id; + + protocol_ctxt_t ctxt; + // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); @@ -7549,9 +7358,28 @@ rrc_enb_task( result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); if (result != EXIT_SUCCESS) { LOG_I(RRC, "Failed to free memory (%d)!\n",result); - continue; } msg_p = NULL; + return NULL; +} + +//----------------------------------------------------------------------------- +void* +rrc_enb_task( + void* args_p +) +//----------------------------------------------------------------------------- +{ + rrc_enb_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); + } } #endif diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 36e0645795b07e3ee10ea668f2abd6b174b9505b..d225b6eae0a48c77ba4bf580e6dda295a84347c0 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -467,43 +467,20 @@ rrc_pdcp_config_security( &kRRCint); #if !defined(USRP_REC_PLAY) -#define DEBUG_SECURITY 1 + SET_LOG_DUMP(DEBUG_SECURITY) ; #endif -#if defined (DEBUG_SECURITY) -#undef msg -#define msg printf - if (print_keys ==1 ) { - print_keys =0; - int i; - msg("\nKeNB:"); - - for(i = 0; i < 32; i++) { - msg("%02x", ue_context_pP->ue_context.kenb[i]); - } - - msg("\n"); - - msg("\nKRRCenc:"); - - for(i = 0; i < 32; i++) { - msg("%02x", kRRCenc[i]); - } + if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { + if (print_keys ==1 ) { + print_keys =0; - msg("\n"); - - msg("\nKRRCint:"); - - for(i = 0; i < 32; i++) { - msg("%02x", kRRCint[i]); + LOG_DUMPMSG(RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kenb, 32,"\nKeNB:" ); + LOG_DUMPMSG(RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" ); + LOG_DUMPMSG(RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" ); } - - msg("\n"); - } -#endif //DEBUG_SECURITY key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); @@ -778,17 +755,20 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( ue_context_pP->ue_context.rnti); } + /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ + int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity - 1; + S1AP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity; + if (rrcConnectionSetupComplete->registeredMME != NULL) { /* Fill GUMMEI */ struct RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME; - //int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity; S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; if (r_mme->plmn_Identity != NULL) { if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { /* Use first indicated PLMN MCC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[0]; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity]; LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, @@ -797,20 +777,16 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( if (r_mme->plmn_Identity->mnc.list.count > 0) { /* Use first indicated PLMN MNC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[0]; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, ue_context_pP->ue_context.rnti); } } else { - // const Enb_properties_array_t *enb_properties_p = NULL; - // enb_properties_p = enb_config_get(); - - // actually the eNB configuration contains only one PLMN (can be up to 6) - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = rrc->mcc; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = rrc->mnc; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = rrc->mnc_digit_length; + S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mcc = rrc->configuration.mcc[selected_plmn_identity]; + S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc = rrc->configuration.mnc[selected_plmn_identity]; + S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc_len = rrc->configuration.mnc_digit_length[selected_plmn_identity]; } S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec); @@ -945,16 +921,8 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( S1AP_DOWNLINK_NAS (msg_p).nas_pdu.length, S1AP_DOWNLINK_NAS (msg_p).nas_pdu.buffer); -#ifdef RRC_MSG_PRINT - int i=0; - LOG_F(RRC,"[MSG] RRC DL Information Transfer\n"); + LOG_DUMPMSG(RRC,DEBUG_RRC,buffer,length,"[MSG] RRC DL Information Transfer\n"); - for (i = 0; i < length; i++) { - LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); - } - - LOG_F(RRC,"\n"); -#endif /* * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. */ @@ -1881,125 +1849,127 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) { LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]); - if (RC.rrc[instance]->configuration.mcc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc - && RC.rrc[instance]->configuration.mnc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc - && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) { - for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type; - /* get nB from configuration */ - /* get default DRX cycle from configuration */ - Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; - if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) { - continue; - } - Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; - /* set T = min(Tc,Tue) */ - T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; - /* set pcch_nB = PCCH-Config->nB */ - pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; - switch (pcch_nB) { - case PCCH_Config__nB_fourT: - Ns = 4; - break; - case PCCH_Config__nB_twoT: - Ns = 2; - break; - default: - Ns = 1; - break; - } - /* set N = min(T,nB) */ - if (pcch_nB > PCCH_Config__nB_oneT) { - switch (pcch_nB) { - case PCCH_Config__nB_halfT: - N = T/2; - break; - case PCCH_Config__nB_quarterT: - N = T/4; - break; - case PCCH_Config__nB_oneEighthT: - N = T/8; - break; - case PCCH_Config__nB_oneSixteenthT: - N = T/16; - break; - case PCCH_Config__nB_oneThirtySecondT: - N = T/32; - break; - default: - /* pcch_nB error */ - LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", - instance, pcch_nB); - return (-1); - } - } else { - N = T; - } - - /* insert data to UE_PF_PO or update data in UE_PF_PO */ - pthread_mutex_lock(&ue_pf_po_mutex); - uint16_t i = 0; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) - || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { - /* set T = min(Tc,Tue) */ - UE_PF_PO[CC_id][i].T = T; - /* set UE_ID */ - UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value; - /* calculate PF and PO */ - /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */ - UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); - /* set PO */ - /* i_s = floor(UE_ID/N) mod Ns */ - i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); - if (Ns == 1) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0; - } else if (Ns==2) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s); - } else if (Ns==4) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); + for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) { + if (RC.rrc[instance]->configuration.mcc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc + && RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc + && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) { + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type; + /* get nB from configuration */ + /* get default DRX cycle from configuration */ + Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; + if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) { + continue; + } + Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; + /* set T = min(Tc,Tue) */ + T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; + /* set pcch_nB = PCCH-Config->nB */ + pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; + switch (pcch_nB) { + case PCCH_Config__nB_fourT: + Ns = 4; + break; + case PCCH_Config__nB_twoT: + Ns = 2; + break; + default: + Ns = 1; + break; + } + /* set N = min(T,nB) */ + if (pcch_nB > PCCH_Config__nB_oneT) { + switch (pcch_nB) { + case PCCH_Config__nB_halfT: + N = T/2; + break; + case PCCH_Config__nB_quarterT: + N = T/4; + break; + case PCCH_Config__nB_oneEighthT: + N = T/8; + break; + case PCCH_Config__nB_oneSixteenthT: + N = T/16; + break; + case PCCH_Config__nB_oneThirtySecondT: + N = T/32; + break; + default: + /* pcch_nB error */ + LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", + instance, pcch_nB); + return (-1); } - if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { - //paging exist UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); - } else { - /* set enable_flag */ - UE_PF_PO[CC_id][i].enable_flag = TRUE; - //paging new UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } else { + N = T; + } + + /* insert data to UE_PF_PO or update data in UE_PF_PO */ + pthread_mutex_lock(&ue_pf_po_mutex); + uint8_t i = 0; + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) + || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { + /* set T = min(Tc,Tue) */ + UE_PF_PO[CC_id][i].T = T; + /* set UE_ID */ + UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value; + /* calculate PF and PO */ + /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */ + UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); + /* set PO */ + /* i_s = floor(UE_ID/N) mod Ns */ + i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); + if (Ns == 1) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0; + } else if (Ns==2) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s); + } else if (Ns==4) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); + } + if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { + //paging exist UE log + LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } else { + /* set enable_flag */ + UE_PF_PO[CC_id][i].enable_flag = TRUE; + //paging new UE log + LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } + break; } - break; - } - } - pthread_mutex_unlock(&ue_pf_po_mutex); - - uint32_t length; - uint8_t buffer[RRC_BUF_SIZE]; - uint8_t *message_buffer; - /* Transfer data to PDCP */ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); - /* Create message for PDCP (DLInformationTransfer_t) */ - length = do_Paging (instance, - buffer, - S1AP_PAGING_IND(msg_p).ue_paging_identity, - S1AP_PAGING_IND(msg_p).cn_domain); - if(length == -1) - { - LOG_I(RRC, "do_Paging error"); - return -1; + } + pthread_mutex_unlock(&ue_pf_po_mutex); + + uint32_t length; + uint8_t buffer[RRC_BUF_SIZE]; + uint8_t *message_buffer; + /* Transfer data to PDCP */ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_Paging (instance, + buffer, + S1AP_PAGING_IND(msg_p).ue_paging_identity, + S1AP_PAGING_IND(msg_p).cn_domain); + if(length == -1) + { + LOG_I(RRC, "do_Paging error"); + return -1; + } + message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length); + /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */ + memcpy (message_buffer, buffer, length); + RRC_PCCH_DATA_REQ (message_p).sdu_size = length; + RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer; + RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */ + RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; + RRC_PCCH_DATA_REQ (message_p).ue_index = i; + RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; + LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); + itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); } - message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length); - /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */ - memcpy (message_buffer, buffer, length); - RRC_PCCH_DATA_REQ (message_p).sdu_size = length; - RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer; - RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */ - RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; - RRC_PCCH_DATA_REQ (message_p).ue_index = i; - RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; - LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); - itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); } } } diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h index 6c19fa9c7076202b934664657e2e9cc3c3c1508a..59200fb9cc4250c6e9cd13f457b779fd6ed0e757 100644 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -75,7 +75,7 @@ extern uint32_t timeToTrigger_ms[16]; extern float RSRP_meas_mapping[98]; extern float RSRQ_meas_mapping[35]; -extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; +extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; extern pthread_mutex_t ue_pf_po_mutex; extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2]; diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index e16391aef10d483778f661628ffbd11710bdf7a6..de16f45c2a718fcb6d583cbdaa92378be2442f51 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -336,6 +336,10 @@ rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* ue_context_pP); #if defined(ENABLE_ITTI) + +void rrc_enb_init(void); +void *rrc_enb_process_itti_msg(void *); + /**\brief RRC eNB task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_enb_task(void *args_p); diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h index 8a718581014a8c9d87fbf5ccffa8c76b1e7db732..028a59f7d96915928827a8c24090f40a7efc7c7a 100644 --- a/openair2/RRC/LTE/rrc_vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -36,7 +36,7 @@ #include "COMMON/mac_rrc_primitives.h" #include "LAYER2/MAC/mac.h" -UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; +UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; pthread_mutex_t ue_pf_po_mutex; UE_RRC_INST *UE_rrc_inst; #include "LAYER2/MAC/mac_extern.h" diff --git a/openair2/UTIL/LISTS/list.h b/openair2/UTIL/LISTS/list.h index bf4d7e7580efed434dc3df51396004231445ad7a..818df2be26d0c74c4e862ceaf660fd6be8708929 100644 --- a/openair2/UTIL/LISTS/list.h +++ b/openair2/UTIL/LISTS/list.h @@ -44,6 +44,8 @@ #include<linux/types.h> #include<stdlib.h> #include<sys/queue.h> +#include <string.h> + #include "UTIL/MEM/mem_block.h" @@ -103,4 +105,37 @@ void totable (double*, struct list*); int compare (const void * a, const void * b); int32_t calculate_median(struct list *loc_list); + +typedef struct { + size_t size; + size_t mallocedSize; + size_t atomSize; + size_t increment; +} varArray_t; + +static inline varArray_t * initVarArray(size_t increment, size_t atomSize) { + varArray_t * tmp=malloc(sizeof(varArray_t)+increment*atomSize); + tmp->size=0; + tmp->atomSize=atomSize; + tmp->mallocedSize=increment; + tmp->increment=increment; + return(tmp); +} + +static inline void * dataArray(varArray_t * input) { + return input+1; +} + +static inline void appendVarArray(varArray_t * input, void* data) { + if (input->size>=input->mallocedSize) { + input->mallocedSize+=input->increment; + input=realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize); + } + memcpy((uint8_t*)(input+1)+input->atomSize*input->size++, data, input->atomSize); +} + +static inline void freeVarArray(varArray_t * input) { + free(input); +} + #endif diff --git a/openair2/UTIL/MEM/mem_block.c b/openair2/UTIL/MEM/mem_block.c index 6d1a289f08ea4ac93583a8fb910d6999ac565382..0150ef00cdaf208120828c54840d80545b6908ca 100644 --- a/openair2/UTIL/MEM/mem_block.c +++ b/openair2/UTIL/MEM/mem_block.c @@ -61,6 +61,7 @@ uint32_t counters[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* * initialize all ures */ +extern mem_pool *memBlockVar; void * pool_buffer_init (void) { @@ -68,6 +69,7 @@ pool_buffer_init (void) uint32_t index, mb_index, pool_index; mem_pool *memory = (mem_pool *) &mem_block_var; + memBlockVar=malloc(sizeof(mem_pool)); int pool_sizes[14] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS, MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS, MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS, diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h index a0455899e3a3cfeb23f936c8fb03c2a289c5fa72..18ded1a5990da3297c9abde96dc8615443fe329c 100644 --- a/openair2/UTIL/MEM/mem_block.h +++ b/openair2/UTIL/MEM/mem_block.h @@ -32,12 +32,17 @@ # define __MEM_BLOCK_H__ #include <stdint.h> +#include <stddef.h> +#ifdef __cplusplus +extern "C" { +#endif #include "openair2/COMMON/platform_constants.h" //----------------------------------------------------------------------------- typedef struct mem_block_t { struct mem_block_t *next; struct mem_block_t *previous; + size_t size; unsigned char pool_id; unsigned char *data; } mem_block_t; @@ -173,7 +178,10 @@ typedef struct { } mem_pool; -mem_pool mem_block_var; - +mem_pool *memBlockVar; +#define mem_block_var (*memBlockVar) +#ifdef __cplusplus +} +#endif #endif diff --git a/openair2/UTIL/OPT/README.txt b/openair2/UTIL/OPT/README.txt index 7193733d0098a16f4230701a4cf0fc758209ed45..c56aeda93d96902b490d583c034f6101abecd540 100644 --- a/openair2/UTIL/OPT/README.txt +++ b/openair2/UTIL/OPT/README.txt @@ -1,9 +1,13 @@ -2012 07 10 - Working version How to configure wireshark for dissecting LTE protocols: - start the wireshark as a sudoers +- goto analyze->enabled prototols + => enable mac_lte_udp and rlc_lte_udp - goto edit/preferences and expand Protocols - select UDP and check "try heuristic sub-dissectors first" - select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info" - select RLC-LTE, and check all the options except the "May see RLC headers only", and set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM. + +How to use +- start eNB or UE with option -W (or -P if you want to make a pcap file) - capture on local interface "lo" - filter out the ICMP/DNS/TCP messages (e.g. "!icmp && !dns && !tcp") diff --git a/openair2/UTIL/OPT/mac_pcap.h b/openair2/UTIL/OPT/mac_pcap.h index f1d4b324923f844fc5ba5b45f2ab505c3837acfd..48b31bb3c07395b2b0d6382166356f717706d9d0 100644 --- a/openair2/UTIL/OPT/mac_pcap.h +++ b/openair2/UTIL/OPT/mac_pcap.h @@ -42,11 +42,4 @@ typedef struct MAC_Context_Info_t { unsigned int subframesSinceCaptureStart; } MAC_Context_Info_t; -pcap_hdr_t file_header = { - 0xa1b2c3d4, /* magic number */ - 2, 4, /* version number is 2.4 */ - 0, /* timezone */ - 0, /* sigfigs - apparently all tools do this */ - 65535, /* snaplen - this should be long enough */ - MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */ -}; + diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index c9340f258e9700baee412b73940e9a946676a589..b4ff3b5006bbf4b5ad9b1d4bdc4ac7c731a9ae1a 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -55,6 +55,16 @@ This header file must be included */ #include "PHY/impl_defs_lte.h" #endif +#define PACKET_MAC_LTE_DEFAULT_UDP_PORT (9999) + +typedef uint8_t guint8; +typedef uint16_t guint16; +typedef uint32_t guint32; +typedef guint8 gboolean; + +#include "packet-mac-lte.h" +#include "mac_pcap.h" + #ifdef OCP_FRAMEWORK #include <enums.h> #else @@ -74,7 +84,7 @@ typedef enum radio_type_e { extern trace_mode_t opt_type; extern char in_ip[40]; -extern char in_path[100]; +extern char in_path[FILENAME_MAX]; /** * function def @@ -84,7 +94,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe, int oob_event, int oob_event_value); -int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p); +int init_opt(char *path, char *ip); void terminate_opt(void); diff --git a/openair2/UTIL/OPT/packet-mac-lte.h b/openair2/UTIL/OPT/packet-mac-lte.h index d0bb60f6b5cdb942ef7581ba868066434cf9b1fb..4dfbe7912ec484a174567cac076d70627550ebe4 100644 --- a/openair2/UTIL/OPT/packet-mac-lte.h +++ b/openair2/UTIL/OPT/packet-mac-lte.h @@ -1,41 +1,36 @@ /* packet-mac-lte.h * * Martin Mathieson - * $Id: packet-mac-lte.h 42240 2012-04-25 20:02:12Z pascal $ * * Wireshark - Network traffic analyzer * By Gerald Combs <gerald@wireshark.org> * Copyright 1998 Gerald Combs * + * SPDX-License-Identifier: GPL-2.0-or-later + * * This header file may also be distributed under * the terms of the BSD Licence as follows: * * Copyright (C) 2009 Martin Mathieson. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE + * SPDX-License-Identifier: BSD-2-Clause */ + + /* + this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 + Date: Wed Aug 22 14:36:20 2018 +0200 + modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature + */ + + +#include "ws_symbol_export.h" + +/** data structure to hold time values with nanosecond resolution*/ +typedef struct { + time_t secs; + int nsecs; +} nstime_t; -#ifndef PACKET_MAC_LTE_H_ -#define PACKET_MAC_LTE_H_ /* radioType */ #define FDD_RADIO 1 @@ -45,105 +40,190 @@ #define DIRECTION_UPLINK 0 #define DIRECTION_DOWNLINK 1 -/* SR: no need to declare following part: */ +/* rntiType */ +#define WS_NO_RNTI 0 +#define WS_P_RNTI 1 +#define WS_RA_RNTI 2 +#define WS_C_RNTI 3 +#define WS_SI_RNTI 4 +#define WS_SPS_RNTI 5 +#define WS_M_RNTI 6 +#define WS_SL_BCH_RNTI 7 +#define WS_SL_RNTI 8 +#define WS_SC_RNTI 9 +#define WS_G_RNTI 10 + typedef enum mac_lte_oob_event { - ltemac_send_preamble, - ltemac_send_sr, - ltemac_sr_failure + ltemac_send_preamble, + ltemac_send_sr, + ltemac_sr_failure } mac_lte_oob_event; typedef enum mac_lte_dl_retx { - dl_retx_no, - dl_retx_yes, - dl_retx_unknown + dl_retx_no, + dl_retx_yes, + dl_retx_unknown } mac_lte_dl_retx; typedef enum mac_lte_crc_status { - crc_fail = 0, - crc_success = 1, - crc_high_code_rate = 2, - crc_pdsch_lost = 3, - crc_duplicate_nonzero_rv = 4 + crc_fail = 0, + crc_success = 1, + crc_high_code_rate = 2, + crc_pdsch_lost = 3, + crc_duplicate_nonzero_rv = 4, + crc_false_dci = 5 } mac_lte_crc_status; +/* N.B. for SCellIndex-r13 extends to 31 */ +typedef enum mac_lte_carrier_id { + carrier_id_primary, + carrier_id_secondary_1, + carrier_id_secondary_2, + carrier_id_secondary_3, + carrier_id_secondary_4, + carrier_id_secondary_5, + carrier_id_secondary_6, + carrier_id_secondary_7 +} mac_lte_carrier_id; + +typedef enum mac_lte_ce_mode { + no_ce_mode = 0, + ce_mode_a = 1, + ce_mode_b = 2 +} mac_lte_ce_mode; + +typedef enum mac_lte_nb_mode { + no_nb_mode = 0, + nb_mode = 1 +} mac_lte_nb_mode; + /* Context info attached to each LTE MAC frame */ -typedef struct mac_lte_info { - /* Needed for decode */ - guint8 radioType; - guint8 direction; - guint8 rntiType; - - /* Extra info to display */ - guint16 rnti; - guint16 ueid; - - /* Timing info */ - guint16 sysframeNumber; - guint16 subframeNumber; - - /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */ - gboolean subframeNumberOfGrantPresent; - guint16 subframeNumberOfGrant; - - /* Flag set only if doing PHY-level data test - i.e. there may not be a - well-formed MAC PDU so just show as raw data */ - gboolean isPredefinedData; - - /* Length of DL PDU or UL grant size in bytes */ - guint16 length; - - /* UL only. 0=newTx, 1=first-retx, etc */ - guint8 reTxCount; - guint8 isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */ - - /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set */ - gboolean isExtendedBSRSizes; - - /* DL only. Status of CRC check */ - mac_lte_crc_status crcStatusValid; - - /* DL only. Is this known to be a retransmission? */ - mac_lte_dl_retx dl_retx; - - /* More Physical layer info (see direction above for which side of union to use) */ - union { - struct mac_lte_ul_phy_info { - guint8 present; /* Remaining UL fields are present and should be displayed */ - guint8 modulation_type; - guint8 tbs_index; - guint8 resource_block_length; - guint8 resource_block_start; - guint8 harq_id; - gboolean ndi; - } ul_info; - struct mac_lte_dl_phy_info { - guint8 present; /* Remaining UL fields are present and should be displayed */ - guint8 dci_format; - guint8 resource_allocation_type; - guint8 aggregation_level; - guint8 mcs_index; - guint8 redundancy_version_index; - guint8 resource_block_length; - mac_lte_crc_status crc_status; - guint8 harq_id; - gboolean ndi; - guint8 transport_block; /* 1..2 */ - } dl_info; - } detailed_phy_info; - - /* Relating to out-of-band events */ - /* N.B. dissector will only look to these fields if length is 0... */ - mac_lte_oob_event oob_event; - guint8 rapid; - guint8 rach_attempt_number; -#define MAX_SRs 20 - guint16 number_of_srs; - guint16 oob_ueid[MAX_SRs]; - guint16 oob_rnti[MAX_SRs]; +typedef struct mac_lte_info +{ + /* Needed for decode */ + guint8 radioType; + guint8 direction; + guint8 rntiType; + + /* Extra info to display */ + guint16 rnti; + guint16 ueid; + + /* Timing info */ + guint16 sysframeNumber; + guint16 subframeNumber; + + /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */ + gboolean subframeNumberOfGrantPresent; + guint16 subframeNumberOfGrant; + + /* Flag set only if doing PHY-level data test - i.e. there may not be a + well-formed MAC PDU so just show as raw data */ + gboolean isPredefinedData; + + /* Length of DL PDU or UL grant size in bytes */ + guint16 length; + + /* 0=newTx, 1=first-retx, etc */ + guint8 reTxCount; + guint8 isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */ + + /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set */ + gboolean isExtendedBSRSizes; + + /* UL only. Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */ + gboolean isSimultPUCCHPUSCHPCell; + + /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */ + gboolean isSimultPUCCHPUSCHPSCell; + + /* Status of CRC check. For UE it is DL only. For eNodeB it is UL + only. For an analyzer, it is present for both DL and UL. */ + gboolean crcStatusValid; + mac_lte_crc_status crcStatus; + + /* Carrier ID */ + mac_lte_carrier_id carrierId; + + /* DL only. Is this known to be a retransmission? */ + mac_lte_dl_retx dl_retx; + + /* DL only. CE mode to be used for RAR decoding */ + mac_lte_ce_mode ceMode; + + /* DL and UL. NB-IoT mode of the UE */ + mac_lte_nb_mode nbMode; + + /* UL only, for now used for CE mode A RAR decoding */ + guint8 nUlRb; + + /* More Physical layer info (see direction above for which side of union to use) */ + union { + struct mac_lte_ul_phy_info + { + guint8 present; /* Remaining UL fields are present and should be displayed */ + guint8 modulation_type; + guint8 tbs_index; + guint8 resource_block_length; + guint8 resource_block_start; + guint8 harq_id; + gboolean ndi; + } ul_info; + struct mac_lte_dl_phy_info + { + guint8 present; /* Remaining DL fields are present and should be displayed */ + guint8 dci_format; + guint8 resource_allocation_type; + guint8 aggregation_level; + guint8 mcs_index; + guint8 redundancy_version_index; + guint8 resource_block_length; + guint8 harq_id; + gboolean ndi; + guint8 transport_block; /* 0..1 */ + } dl_info; + } detailed_phy_info; + + /* Relating to out-of-band events */ + /* N.B. dissector will only look to these fields if length is 0... */ + mac_lte_oob_event oob_event; + guint8 rapid; + guint8 rach_attempt_number; + #define MAX_SRs 20 + guint16 number_of_srs; + guint16 oob_ueid[MAX_SRs]; + guint16 oob_rnti[MAX_SRs]; } mac_lte_info; -/* Accessor function to check if a frame was considered to be ReTx */ -//int is_mac_lte_frame_retx(packet_info *pinfo, guint8 direction); + +typedef struct mac_lte_tap_info { + /* Info from context */ + guint16 rnti; + guint16 ueid; + guint8 rntiType; + guint8 isPredefinedData; + gboolean crcStatusValid; + mac_lte_crc_status crcStatus; + guint8 direction; + + guint8 isPHYRetx; + guint16 ueInTTI; + + nstime_t mac_lte_time; + + /* Number of bytes (which part is used depends upon context settings) */ + guint32 single_number_of_bytes; + guint32 bytes_for_lcid[11]; + guint32 sdus_for_lcid[11]; + guint8 number_of_rars; + guint8 number_of_paging_ids; + + /* Number of padding bytes includes padding subheaders and trailing padding */ + guint16 padding_bytes; + guint16 raw_length; +} mac_lte_tap_info; + + /*****************************************************************/ /* UDP framing format */ @@ -153,12 +233,10 @@ typedef struct mac_lte_info { /* and implemented by this dissector, using the definitions */ /* below. A link to an example program showing you how to encode */ /* these headers and send LTE MAC PDUs on a UDP socket is */ -/* provided at http://wiki.wireshark.org/MAC-LTE */ +/* provided at https://wiki.wireshark.org/MAC-LTE */ /* */ -/* A heuristic dissecter (enabled by a preference) will */ -/* recognise a signature at the beginning of these frames . */ -/* Until someone is using this format, suggestions for changes */ -/* are welcome. */ +/* A heuristic dissector (enabled by a preference) will */ +/* recognise a signature at the beginning of these frames. */ /*****************************************************************/ @@ -177,7 +255,7 @@ typedef struct mac_lte_info { to show you display/filter/plot/add-custom-columns on these fields, so should be added if available. The format is to have the tag, followed by the value (there is no length field, - its implicit from the tag) */ + it's implicit from the tag) */ #define MAC_LTE_RNTI_TAG 0x02 /* 2 bytes, network order */ @@ -185,8 +263,8 @@ typedef struct mac_lte_info { #define MAC_LTE_UEID_TAG 0x03 /* 2 bytes, network order */ -#define MAC_LTE_SUBFRAME_TAG 0x04 -/* 2 bytes, network order */ +#define MAC_LTE_FRAME_SUBFRAME_TAG 0x04 +/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */ #define MAC_LTE_PREDEFINED_DATA_TAG 0x05 /* 1 byte */ @@ -200,29 +278,101 @@ typedef struct mac_lte_info { #define MAC_LTE_EXT_BSR_SIZES_TAG 0x08 /* 0 byte */ -#define MAC_LTE_OOB_EVENT_TAG 0x09 -/* 3 byte */ +#define MAC_LTE_SEND_PREAMBLE_TAG 0x09 +/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */ + +#define MAC_LTE_CARRIER_ID_TAG 0x0A +/* 1 byte */ + +#define MAC_LTE_PHY_TAG 0x0B +/* variable length, length (1 byte) then depending on direction + in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte), + RB start (1 byte), HARQ id (1 byte), NDI (1 byte) + in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte), + MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte), + HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */ + +#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG 0x0C +/* 0 byte */ + +#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D +/* 0 byte */ + +#define MAC_LTE_CE_MODE_TAG 0x0E +/* 1 byte containing mac_lte_ce_mode enum value */ + +#define MAC_LTE_NB_MODE_TAG 0x0F +/* 1 byte containing mac_lte_nb_mode enum value */ + +#define MAC_LTE_N_UL_RB_TAG 0x10 +/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */ + +#define MAC_LTE_SR_TAG 0x11 +/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */ + /* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU continues until the end of the frame) */ #define MAC_LTE_PAYLOAD_TAG 0x01 -/* Set details of an LCID -> drb channel mapping. To be called from - configuration protocol (e.g. RRC) */ -/*void set_mac_lte_channel_mapping(guint16 ueid, guint8 lcid, - guint8 srbid, guint8 drbid, - guint8 rlcMode, guint8 um_sn_length, - guint8 ul_priority); -*/ -/* Functions to be called from outside this module (e.g. in a plugin, where mac_lte_info - isn't available) to get/set per-packet data */ -//mac_lte_info *get_mac_lte_proto_data(packet_info *pinfo); -//void set_mac_lte_proto_data(packet_info *pinfo, mac_lte_info *p_mac_lte_info); - -/* Function to attempt to populate p_mac_lte_info using framing definition above */ -/*gboolean dissect_mac_lte_context_fields(struct mac_lte_info *p_mac_lte_info, tvbuff_t *tvb, - gint *p_offset); -*/ - -#endif /* PACKET_MAC_LTE_H_ */ +/* Type to store parameters for configuring LCID->RLC channel settings for DRB */ +/* Some are optional, and may not be seen (e.g. on reestablishment) */ +typedef struct drb_mapping_t +{ + guint16 ueid; /* Mandatory */ + guint8 drbid; /* Mandatory */ + gboolean lcid_present; + guint8 lcid; /* Part of LogicalChannelConfig - optional */ + gboolean rlcMode_present; + guint8 rlcMode; /* Part of RLC config - optional */ + gboolean rlc_ul_ext_li_field; /* Part of RLC config - optional */ + gboolean rlc_dl_ext_li_field; /* Part of RLC config - optional */ + gboolean rlc_ul_ext_am_sn; /* Part of RLC config - optional */ + gboolean rlc_dl_ext_am_sn; /* Part of RLC config - optional */ + gboolean um_sn_length_present; + guint8 um_sn_length; /* Part of RLC config - optional */ + gboolean ul_priority_present; + guint8 ul_priority; /* Part of LogicalChannelConfig - optional */ + gboolean pdcp_sn_size_present; + guint8 pdcp_sn_size; /* Part of pdcp-Config - optional */ +} drb_mapping_t; + + + +/* Dedicated DRX config. Used to verify that a sensible config is given. + Also, beginning to configure MAC with this config and (optionally) show + DRX config and state (cycles/timers) attached to each UL/DL PDU! */ +typedef struct drx_config_t { + gboolean configured; + guint32 frameNum; + guint32 previousFrameNum; + + guint32 onDurationTimer; + guint32 inactivityTimer; + guint32 retransmissionTimer; + guint32 longCycle; + guint32 cycleOffset; + /* Optional Short cycle */ + gboolean shortCycleConfigured; + guint32 shortCycle; + guint32 shortCycleTimer; +} drx_config_t; + +/* RRC can indicate whether simultaneous PUCCH/PUSCH is used */ +typedef enum { + SIMULT_PUCCH_PUSCH_PCELL = 0, + SIMULT_PUCCH_PUSCH_PSCELL +} simult_pucch_pusch_cell_type; +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 2f7dac3d1ed9a7a568af2ecae00d86b58529e7ad..a1e53671682a10f0f984cbcd831b98c0116378e2 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -95,26 +95,22 @@ what about the implementation int opt_enabled=0; -#define PACKET_MAC_LTE_DEFAULT_UDP_PORT (9999) - -typedef uint8_t guint8; -typedef uint16_t guint16; -typedef uint32_t guint32; -typedef guint8 gboolean; - -#include "packet-mac-lte.h" -#include "mac_pcap.h" - //static unsigned char g_PDUBuffer[1600]; //static unsigned int g_PDUOffset; - char in_ip[40]; -char in_path[100]; +char in_path[FILENAME_MAX]; FILE *file_fd = NULL; +pcap_hdr_t file_header = { + 0xa1b2c3d4, /* magic number */ + 2, 4, /* version number is 2.4 */ + 0, /* timezone */ + 0, /* sigfigs - apparently all tools do this */ + 65535, /* snaplen - this should be long enough */ + MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */ +}; trace_mode_t opt_type = OPT_NONE; -static radio_type_t radio_type; static unsigned int subframesSinceCaptureStart; static int g_socksd = -1;/* UDP socket used for sending frames */ @@ -237,22 +233,13 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, guint8 oob_event, guint8 oob_event_value, uint8_t *pdu_buffer, unsigned int pdu_buffer_size) { - #ifdef JUMBO_FRAME - static unsigned char frameBuffer[9000]; - #else - static unsigned char frameBuffer[1600]; - #endif - static unsigned int frameOffset; + unsigned char frameBuffer[9000]; + unsigned int frameOffset; ssize_t bytesSent; frameOffset = 0; uint16_t tmp16; - /********************************************************************/ - /* Fixed start to each frame (allowing heuristic dissector to work) */ - /* Not NULL terminated */ - memset(frameBuffer+frameOffset, 0, sizeof(mac_lte_info)+pdu_buffer_size + 8); - memcpy(frameBuffer+frameOffset, MAC_LTE_START_STRING, strlen(MAC_LTE_START_STRING)); frameOffset += strlen(MAC_LTE_START_STRING); @@ -279,7 +266,7 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, frameOffset += 2; /* Subframe number */ - frameBuffer[frameOffset++] = MAC_LTE_SUBFRAME_TAG; + frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG; tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F memcpy(frameBuffer+frameOffset, &tmp16, 2); frameOffset += 2; @@ -313,26 +300,29 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, if (pdu_buffer_size==0) { switch (oob_event) { case ltemac_send_preamble : - LOG_D(OPT,"oob ltemac_send_preamble event %02x." + LOG_D(OPT,"ltemac_send_preamble event %02x." //"%02x." "%02x.%02x\n", - MAC_LTE_OOB_EVENT_TAG, + MAC_LTE_SEND_PREAMBLE_TAG, //ltemac_send_preamble, rnti, oob_event_value); //frameBuffer[frameOffset++]=0; //frameBuffer[frameOffset++]=0; //frameBuffer[frameOffset++]=0; - frameBuffer[frameOffset++] = MAC_LTE_OOB_EVENT_TAG; + frameBuffer[frameOffset++] = MAC_LTE_SEND_PREAMBLE_TAG; //frameBuffer[frameOffset++]=ltemac_send_preamble; frameBuffer[frameOffset++]=rnti; // is the preamble frameBuffer[frameOffset++]=oob_event_value; break; case ltemac_send_sr: - frameBuffer[frameOffset++]=ltemac_send_sr; + frameBuffer[frameOffset++]=MAC_LTE_SR_TAG ; frameOffset+=2; + frameBuffer[frameOffset++]=rnti; + frameOffset++; frameBuffer[frameOffset++]=oob_event_value; + frameOffset++; break; case ltemac_sr_failure: @@ -394,7 +384,7 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, offset += 2; /* Subframe number */ - context_header[offset++] = MAC_LTE_SUBFRAME_TAG; + context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG; tmp16 = htons(context->subFrameNumber); memcpy(context_header+offset, &tmp16, 2); offset += 2; @@ -423,21 +413,27 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, return 1; } - +#include <common/ran_context.h> +extern RAN_CONTEXT_t RC; +#include <openair1/PHY/phy_extern_ue.h> /* Remote serveraddress (where Wireshark is running) */ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, int oob_event_value) { MAC_Context_Info_t pdu_context; - + int radioType=FDD_RADIO; + if (RC.eNB[0][0]!=NULL) + radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; + if (PHY_vars_UE_g[0][0] != NULL) + radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; switch (opt_type) { case OPT_WIRESHARK : if (g_socksd == -1) { return; } - SendFrame(radio_type, + SendFrame( radioType, (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber, 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus @@ -450,7 +446,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, return; } - pdu_context.radioType = radio_type; + pdu_context.radioType = radioType; pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK; pdu_context.rntiType = rntiType; @@ -470,7 +466,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, } } /*---------------------------------------------------*/ -int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p) +int init_opt(char *path, char *ip) { uint16_t in_port; subframesSinceCaptureStart = 0; @@ -489,13 +485,7 @@ int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p) strcpy( in_ip, "127.0.0.1" ); } - if (port != NULL) { - in_port = atoi(port); - } else { - in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT; - } - - radio_type = radio_type_p; + in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT; // trace_mode switch (opt_type) { diff --git a/openair2/UTIL/OPT/ws_compiler_tests.h b/openair2/UTIL/OPT/ws_compiler_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..46a4ab6099d2d9a2826f42f2884eae962efedff1 --- /dev/null +++ b/openair2/UTIL/OPT/ws_compiler_tests.h @@ -0,0 +1,138 @@ +/* ws_compiler_tests.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef __WS_COMPILER_TESTS_H__ +#define __WS_COMPILER_TESTS_H__ + +/* + * This was introduced by Clang: + * + * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute + * + * in some version (which version?); it has been picked up by GCC 5.0. + */ +#ifndef __has_attribute + /* + * It's a macro, so you can check whether it's defined to check + * whether it's supported. + * + * If it's not, define it to always return 0, so that we move on to + * the fallback checks. + */ + #define __has_attribute(x) 0 +#endif + +/* + * Note that the C90 spec's "6.8.1 Conditional inclusion" and the + * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say: + * + * Prior to evaluation, macro invocations in the list of preprocessing + * tokens that will become the controlling constant expression are + * replaced (except for those macro names modified by the defined unary + * operator), just as in normal text. If the token "defined" is + * generated as a result of this replacement process or use of the + * "defined" unary operator does not match one of the two specified + * forms prior to macro replacement, the behavior is undefined. + * + * so you shouldn't use defined() in a #define that's used in #if or + * #elif. Some versions of Clang, for example, will warn about this. + * + * Instead, we check whether the pre-defined macros for particular + * compilers are defined and, if not, define the "is this version XXX + * or a later version of this compiler" macros as 0. + */ + +/* + * Check whether this is GCC major.minor or a later release, or some + * compiler that claims to be "just like GCC" of that version or a + * later release. + */ + +#if !defined(__GNUC__) + #define WS_IS_AT_LEAST_GNUC_VERSION(major, minor) 0 +#else + #define WS_IS_AT_LEAST_GNUC_VERSION(major, minor) \ + (__GNUC__ > (major) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#endif + +/* + * Check whether this is Clang major.minor or a later release. + */ + +#if !defined(__clang__) + #define WS_IS_AT_LEAST_CLANG_VERSION(major, minor) 0 +#else + #define WS_IS_AT_LEAST_CLANG_VERSION(major, minor) \ + (__clang_major__ > (major) || \ + (__clang_major__ == (major) && __clang_minor__ >= (minor))) +#endif + +/* + * Check whether this is Sun C/SunPro C/Oracle Studio major.minor + * or a later release. + * + * The version number in __SUNPRO_C is encoded in hex BCD, with the + * uppermost hex digit being the major version number, the next + * one or two hex digits being the minor version number, and + * the last digit being the patch version. + * + * It represents the *compiler* version, not the product version; + * see + * + * https://sourceforge.net/p/predef/wiki/Compilers/ + * + * for a partial mapping, which we assume continues for later + * 12.x product releases. + */ + +#if !defined(__SUNPRO_C) + #define WS_IS_AT_LEAST_SUNC_VERSION(major, minor) 0 +#else + #define WS_SUNPRO_VERSION_TO_BCD(major, minor) \ + (((minor) >= 10) ? \ + (((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \ + (((major) << 8) | ((minor) << 4))) + #define WS_IS_AT_LEAST_SUNC_VERSION(major, minor) \ + (__SUNPRO_C >= WS_SUNPRO_VERSION_TO_BCD((major), (minor))) +#endif + +/* + * Check whether this is IBM XL C major.minor or a later release. + * + * The version number in __xlC__ has the major version in the + * upper 8 bits and the minor version in the lower 8 bits. + */ + +#if !defined(__xlC__) + #define WS_IS_AT_LEAST_XL_C_VERSION(major, minor) 0 +#else + #define WS_IS_AT_LEAST_XL_C_VERSION(major, minor) \ + (__xlC__ >= (((major) << 8) | (minor))) +#endif + +/* + * Check whether this is HP aC++/HP C major.minor or a later release. + * + * The version number in __HP_aCC is encoded in zero-padded decimal BCD, + * with the "A." stripped off, the uppermost two decimal digits being + * the major version number, the next two decimal digits being the minor + * version number, and the last two decimal digits being the patch version. + * (Strip off the A., remove the . between the major and minor version + * number, and add two digits of patch.) + */ + +#if !defined(__HP_aCC) + #define WS_IS_AT_LEAST_HP_C_VERSION(major, minor) 0 +#else + #define WS_IS_AT_LEAST_HP_C_VERSION(major, minor) \ + (__HP_aCC >= ((major)*10000 + (minor)*100)) +#endif + +#endif /* __WS_COMPILER_TESTS_H__ */ diff --git a/openair2/UTIL/OPT/ws_symbol_export.h b/openair2/UTIL/OPT/ws_symbol_export.h new file mode 100644 index 0000000000000000000000000000000000000000..4c7a2f710af741a948163a0efb7892af7be5a662 --- /dev/null +++ b/openair2/UTIL/OPT/ws_symbol_export.h @@ -0,0 +1,202 @@ +/* + * Cross platform defines for exporting symbols from shared libraries + * + * Wireshark - Network traffic analyzer + * By Balint Reczey <balint@balintreczey.hu> + * Copyright 2013 Balint Reczey + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "ws_compiler_tests.h" + +/** Reset symbol export behavior. + * If you {un}define WS_BUILD_DLL on the fly you'll have to define this + * as well. + */ +#ifdef RESET_SYMBOL_EXPORT + +#ifdef SYMBOL_EXPORT_H +#undef SYMBOL_EXPORT_H +#endif + +#ifdef WS_DLL_PUBLIC +#undef WS_DLL_PUBLIC +#endif + +#ifdef WS_DLL_PUBLIC_DEF +#undef WS_DLL_PUBLIC_DEF +#endif + +#ifdef WS_DLL_LOCAL +#undef WS_DLL_LOCAL +#endif + +#endif /* RESET_SYMBOL_EXPORT */ + +#ifndef SYMBOL_EXPORT_H +#define SYMBOL_EXPORT_H + +/* + * NOTE: G_HAVE_GNUC_VISIBILITY is defined only if all of + * + * __attribute__ ((visibility ("hidden"))) + * + * __attribute__ ((visibility ("internal"))) + * + * __attribute__ ((visibility ("protected"))) + * + * __attribute__ ((visibility ("default"))) + * + * are supported, and at least some versions of GCC from Apple support + * "default" and "hidden" but not "internal" or "protected", so it + * shouldn't be used to determine whether "hidden" or "default" is + * supported. + * + * This also means that we shouldn't use G_GNUC_INTERNAL instead of + * WS_DLL_LOCAL, as GLib uses G_HAVE_GNUC_VISIBILITY to determine + * whether to use __attribute__ ((visibility ("hidden"))) for + * G_GNUC_INTERNAL, and that will not use it even with compilers + * that support it. + */ + +/* Originally copied from GCC Wiki at http://gcc.gnu.org/wiki/Visibility */ +#if defined _WIN32 || defined __CYGWIN__ + /* Compiling for Windows, so we use the Windows DLL declarations. */ + #ifdef WS_BUILD_DLL + /* + * Building a DLL; for all definitions, we want dllexport, and + * (presumably so source from DLL and source from a program using the + * DLL can both include a header that declares APIs and exported data + * for the DLL), for declarations, either dllexport or dllimport will + * work (they mean the same thing for a declaration when building a DLL). + */ + #ifdef __GNUC__ + /* GCC */ + #define WS_DLL_PUBLIC_DEF __attribute__ ((dllexport)) + #else /* ! __GNUC__ */ + /* + * Presumably MSVC. + * Note: actually gcc seems to also support this syntax. + */ + #define WS_DLL_PUBLIC_DEF __declspec(dllexport) + #endif /* __GNUC__ */ + #else /* WS_BUILD_DLL */ + /* + * Building a program; we should only see declarations, not definitions, + * with WS_DLL_PUBLIC, and they all represent APIs or data imported + * from a DLL, so use dllimport. + * + * For functions, export shouldn't be necessary; for data, it might + * be necessary, e.g. if what's declared is an array whose size is + * not given in the declaration. + */ + #ifdef __GNUC__ + /* GCC */ + #define WS_DLL_PUBLIC_DEF __attribute__ ((dllimport)) + #elif ! (defined ENABLE_STATIC) /* ! __GNUC__ */ + /* + * Presumably MSVC, and we're not building all-static. + * Note: actually gcc seems to also support this syntax. + */ + #define WS_DLL_PUBLIC_DEF __declspec(dllimport) + #else /* ! __GNUC__ && ENABLE_STATIC */ + /* + * Presumably MSVC, and we're building all-static, so we're + * not building any DLLs. + */ + #define WS_DLL_PUBLIC_DEF + #endif /* __GNUC__ */ + #endif /* WS_BUILD_DLL */ + + /* + * Symbols in a DLL are *not* exported unless they're specifically + * flagged as exported, so, for a non-static but non-exported + * symbol, we don't have to do anything. + */ + #define WS_DLL_LOCAL +#else /* defined _WIN32 || defined __CYGWIN__ */ + /* + * Compiling for UN*X, where the dllimport and dllexport stuff + * is neither necessary nor supported; just specify the + * visibility if we have a compiler that supports doing so. + */ + #if WS_IS_AT_LEAST_GNUC_VERSION(3,4) \ + || WS_IS_AT_LEAST_XL_C_VERSION(12,0) + /* + * GCC 3.4 or later, or some compiler asserting compatibility with + * GCC 3.4 or later, or XL C 13.0 or later, so we have + * __attribute__((visibility()). + */ + + /* + * Symbols exported from libraries. + */ + #define WS_DLL_PUBLIC_DEF __attribute__ ((visibility ("default"))) + + /* + * Non-static symbols *not* exported from libraries. + */ + #define WS_DLL_LOCAL __attribute__ ((visibility ("hidden"))) + #elif WS_IS_AT_LEAST_SUNC_VERSION(5,5) + /* + * Sun C 5.5 or later, so we have __global and __hidden. + * (Sun C 5.9 and later also have __attribute__((visibility()), + * but there's no reason to prefer it with Sun C.) + */ + + /* + * Symbols exported from libraries. + */ + #define WS_DLL_PUBLIC_DEF __global + + /* + * Non-static symbols *not* exported from libraries. + */ + #define WS_DLL_LOCAL __hidden + #else + /* + * We have neither a way to make stuff not explicitly marked as + * visible invisible outside a library nor a way to make stuff + * explicitly marked as local invisible outside the library. + */ + + /* + * Symbols exported from libraries. + */ + #define WS_DLL_PUBLIC_DEF + + /* + * Non-static symbols *not* exported from libraries. + */ + #define WS_DLL_LOCAL + #endif +#endif + +/* + * You *must* use this for exported data *declarations*; if you use + * WS_DLL_PUBLIC_DEF, some compilers, such as MSVC++, will complain + * about array definitions with no size. + * + * You must *not* use this for exported data *definitions*, as that + * will, for some compilers, cause warnings about items being initialized + * and declared extern. + * + * Either can be used for exported *function* declarations and definitions. + */ +#define WS_DLL_PUBLIC WS_DLL_PUBLIC_DEF extern + +#endif /* SYMBOL_EXPORT_H */ + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */ diff --git a/openair2/X2AP/x2ap_common.c b/openair2/X2AP/x2ap_common.c index 2ac875155d6294cf1bd815f960164ae4cdc59c58..cc2954f77bcfb212874add515e90f82d76fdb483 100644 --- a/openair2/X2AP/x2ap_common.c +++ b/openair2/X2AP/x2ap_common.c @@ -66,7 +66,7 @@ ssize_t x2ap_generate_initiating_message( pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; pdu.choice.initiatingMessage.procedureCode = procedureCode; pdu.choice.initiatingMessage.criticality = criticality; - ANY_fromType_aper(&pdu.choice.initiatingMessage.value, td, sptr); + ANY_fromType_aper((ANY_t *)&pdu.choice.initiatingMessage.value, td, sptr); if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)&pdu); @@ -98,7 +98,7 @@ ssize_t x2ap_generate_successfull_outcome( pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; pdu.choice.successfulOutcome.procedureCode = procedureCode; pdu.choice.successfulOutcome.criticality = criticality; - ANY_fromType_aper(&pdu.choice.successfulOutcome.value, td, sptr); + ANY_fromType_aper((ANY_t *)&pdu.choice.successfulOutcome.value, td, sptr); if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)&pdu); @@ -130,7 +130,7 @@ ssize_t x2ap_generate_unsuccessfull_outcome( pdu.present = X2AP_X2AP_PDU_PR_unsuccessfulOutcome; pdu.choice.successfulOutcome.procedureCode = procedureCode; pdu.choice.successfulOutcome.criticality = criticality; - ANY_fromType_aper(&pdu.choice.successfulOutcome.value, td, sptr); + ANY_fromType_aper((ANY_t *)&pdu.choice.successfulOutcome.value, td, sptr); if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)&pdu); diff --git a/openair2/X2AP/x2ap_common.h b/openair2/X2AP/x2ap_common.h index 1a4889f0f01699cb307b8e1c30b08351a1a4df36..a2f903a73725f812b44314e02408ad40ceed145f 100644 --- a/openair2/X2AP/x2ap_common.h +++ b/openair2/X2AP/x2ap_common.h @@ -28,12 +28,12 @@ #include "X2AP_InitiatingMessage.h" #include "X2AP_SuccessfulOutcome.h" #include "X2AP_UnsuccessfulOutcome.h" -#include "X2AP_ProtocolIE-Field.h" #include "X2AP_ProtocolIE-FieldPair.h" #include "X2AP_ProtocolIE-ContainerPair.h" #include "X2AP_ProtocolExtensionField.h" #include "X2AP_ProtocolExtensionContainer.h" #include "X2AP_asn_constant.h" +#include "intertask_interface.h" #ifndef X2AP_COMMON_H_ #define X2AP_COMMON_H_ @@ -57,15 +57,16 @@ #define FALSE 0 #endif -extern int asn_debug; extern int asn1_xer_print; #if defined(ENB_MODE) -# include "log.h" +# include "common/utils/LOG/log.h" +# define X2AP_INFO(x, args...) LOG_I(X2AP, x, ##args) # define X2AP_ERROR(x, args...) LOG_E(X2AP, x, ##args) # define X2AP_WARN(x, args...) LOG_W(X2AP, x, ##args) # define X2AP_DEBUG(x, args...) LOG_D(X2AP, x, ##args) #else +# define X2AP_INFO(x, args...) do { fprintf(stdout, "[X2AP][I]"x, ##args); } while(0) # define X2AP_ERROR(x, args...) do { fprintf(stdout, "[X2AP][E]"x, ##args); } while(0) # define X2AP_WARN(x, args...) do { fprintf(stdout, "[X2AP][W]"x, ##args); } while(0) # define X2AP_DEBUG(x, args...) do { fprintf(stdout, "[X2AP][D]"x, ##args); } while(0) @@ -86,15 +87,13 @@ extern int asn1_xer_print; if (mandatory) DevAssert(ie != NULL); \ } while(0) -//Forward declaration -struct x2ap_message_s; - /** \brief Function callback prototype. **/ typedef int (*x2ap_message_decoded_callback)( + instance_t instance, uint32_t assocId, uint32_t stream, - struct x2ap_message_s *message); + X2AP_X2AP_PDU_t *pdu); /** \brief Encode a successfull outcome message \param buffer pointer to buffer in which data will be encoded diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c new file mode 100644 index 0000000000000000000000000000000000000000..d12dfa881979b9a3841471ed236b64ff4475c621 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB.c @@ -0,0 +1,467 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <arpa/inet.h> + +#include "intertask_interface.h" + +#include "x2ap_eNB.h" +#include "x2ap_eNB_defs.h" +#include "x2ap_eNB_management_procedures.h" +#include "x2ap_eNB_handler.h" +#include "x2ap_eNB_generate_messages.h" +#include "x2ap_common.h" + +#include "queue.h" +#include "assertions.h" +#include "conversions.h" + +struct x2ap_enb_map; +struct x2ap_eNB_data_s; + +RB_PROTOTYPE(x2ap_enb_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id); + +static +void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); + +static +void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +static +void x2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind); + +static +void x2ap_eNB_handle_register_eNB(instance_t instance, + x2ap_register_enb_req_t *x2ap_register_eNB); +static +void x2ap_eNB_register_eNB(x2ap_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_X2C, + int multi_sd); + + +static +void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { + + int result; + + DevAssert(sctp_data_ind != NULL); + + x2ap_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 x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) +{ + 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); + + /* 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) { + x2ap_enb_data_p = x2ap_get_eNB(instance_p, sctp_new_association_resp->assoc_id, + sctp_new_association_resp->ulp_cnx_id); + if (x2ap_enb_data_p != NULL) { + /* some sanity check - to be refined at some point */ + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); + abort(); + } + x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; + x2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams; + return; + } + } + + 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) { + X2AP_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); + + x2ap_handle_x2_setup_message(x2ap_enb_data_p, + sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + + 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); +} + +static +void x2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) +{ + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_enb_data_p; + +printf("x2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance); +dump_trees(); + DevAssert(sctp_new_association_ind != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + x2ap_enb_data_p = x2ap_get_eNB(instance_p, sctp_new_association_ind->assoc_id, -1); + if (x2ap_enb_data_p != NULL) abort(); +// DevAssert(x2ap_enb_data_p != NULL); + if (x2ap_enb_data_p == NULL) { + /* Create new eNB descriptor */ + x2ap_enb_data_p = calloc(1, sizeof(*x2ap_enb_data_p)); + DevAssert(x2ap_enb_data_p != NULL); + + x2ap_enb_data_p->cnx_id = x2ap_eNB_fetch_add_global_cnx_id(); + + x2ap_enb_data_p->x2ap_eNB_instance = instance_p; + + /* Insert the new descriptor in list of known eNB + * but not yet associated. + */ + RB_INSERT(x2ap_enb_map, &instance_p->x2ap_enb_head, x2ap_enb_data_p); + x2ap_enb_data_p->state = X2AP_ENB_STATE_CONNECTED; + instance_p->x2_target_enb_nb++; + if (instance_p->x2_target_enb_pending_nb > 0) { + instance_p->x2_target_enb_pending_nb--; + } + } else { + X2AP_WARN("x2ap_enb_data_p already exists\n"); + } + +printf("x2ap_eNB_handle_sctp_association_ind at 2\n"); +dump_trees(); + /* Update parameters */ + x2ap_enb_data_p->assoc_id = sctp_new_association_ind->assoc_id; + x2ap_enb_data_p->in_streams = sctp_new_association_ind->in_streams; + x2ap_enb_data_p->out_streams = sctp_new_association_ind->out_streams; + +printf("x2ap_eNB_handle_sctp_association_ind at 3\n"); +dump_trees(); +} + +int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t enb_port_for_X2C) +{ + // 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_X2AP, SCTP_INIT_MSG_MULTI_REQ); + sctp_init = &message->ittiMsg.sctp_init_multi; + + sctp_init->port = enb_port_for_X2C; + sctp_init->ppid = X2AP_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 x2ap_eNB_register_eNB(x2ap_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_X2C, + int multi_sd) +{ + + MessageDef *message = NULL; + sctp_new_association_req_multi_t *sctp_new_association_req = NULL; + x2ap_eNB_data_t *x2ap_enb_data = NULL; + + DevAssert(instance_p != NULL); + DevAssert(target_eNB_ip_address != NULL); + + message = itti_alloc_new_message(TASK_X2AP, SCTP_NEW_ASSOCIATION_REQ_MULTI); + + sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; + + sctp_new_association_req->port = enb_port_for_X2C; + sctp_new_association_req->ppid = X2AP_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 */ + x2ap_enb_data = calloc(1, sizeof(*x2ap_enb_data)); + DevAssert(x2ap_enb_data != NULL); + + x2ap_enb_data->cnx_id = x2ap_eNB_fetch_add_global_cnx_id(); + sctp_new_association_req->ulp_cnx_id = x2ap_enb_data->cnx_id; + + x2ap_enb_data->assoc_id = -1; + x2ap_enb_data->x2ap_eNB_instance = instance_p; + + /* Insert the new descriptor in list of known eNB + * but not yet associated. + */ + RB_INSERT(x2ap_enb_map, &instance_p->x2ap_enb_head, x2ap_enb_data); + x2ap_enb_data->state = X2AP_ENB_STATE_WAITING; + instance_p->x2_target_enb_nb ++; + instance_p->x2_target_enb_pending_nb ++; + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message); +} + +static +void x2ap_eNB_handle_register_eNB(instance_t instance, + x2ap_register_enb_req_t *x2ap_register_eNB) +{ + x2ap_eNB_instance_t *new_instance; + + DevAssert(x2ap_register_eNB != NULL); + + /* Look if the provided instance already exists */ + new_instance = x2ap_eNB_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same eNB */ + DevCheck(new_instance->eNB_id == x2ap_register_eNB->eNB_id, new_instance->eNB_id, x2ap_register_eNB->eNB_id, 0); + DevCheck(new_instance->cell_type == x2ap_register_eNB->cell_type, new_instance->cell_type, x2ap_register_eNB->cell_type, 0); + DevCheck(new_instance->tac == x2ap_register_eNB->tac, new_instance->tac, x2ap_register_eNB->tac, 0); + DevCheck(new_instance->mcc == x2ap_register_eNB->mcc, new_instance->mcc, x2ap_register_eNB->mcc, 0); + DevCheck(new_instance->mnc == x2ap_register_eNB->mnc, new_instance->mnc, x2ap_register_eNB->mnc, 0); + X2AP_WARN("eNB[%d] already registered\n", instance); + } + else { + new_instance = calloc(1, sizeof(x2ap_eNB_instance_t)); + DevAssert(new_instance != NULL); + + RB_INIT(&new_instance->x2ap_enb_head); + + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->eNB_name = x2ap_register_eNB->eNB_name; + new_instance->eNB_id = x2ap_register_eNB->eNB_id; + new_instance->cell_type = x2ap_register_eNB->cell_type; + new_instance->tac = x2ap_register_eNB->tac; + new_instance->mcc = x2ap_register_eNB->mcc; + new_instance->mnc = x2ap_register_eNB->mnc; + new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length; + + new_instance->num_cc = x2ap_register_eNB->num_cc; + + for (int i = 0; i< x2ap_register_eNB->num_cc; i++){ + new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; + new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i]; + new_instance->uplink_frequency_offset[i] = x2ap_register_eNB->uplink_frequency_offset[i]; + new_instance->Nid_cell[i] = x2ap_register_eNB->Nid_cell[i]; + new_instance->N_RB_DL[i] = x2ap_register_eNB->N_RB_DL[i]; + new_instance->frame_type[i] = x2ap_register_eNB->frame_type[i]; + new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i]; + new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i]; + } + + DevCheck(x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS, + X2AP_MAX_NB_ENB_IP_ADDRESS, x2ap_register_eNB->nb_x2, 0); + memcpy(new_instance->target_enb_x2_ip_address, + x2ap_register_eNB->target_enb_x2_ip_address, + x2ap_register_eNB->nb_x2 * sizeof(net_ip_address_t)); + + new_instance->nb_x2 = x2ap_register_eNB->nb_x2; + new_instance->enb_x2_ip_address = x2ap_register_eNB->enb_x2_ip_address; + new_instance->sctp_in_streams = x2ap_register_eNB->sctp_in_streams; + new_instance->sctp_out_streams = x2ap_register_eNB->sctp_out_streams; + new_instance->enb_port_for_X2C = x2ap_register_eNB->enb_port_for_X2C; + + /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ + x2ap_eNB_insert_new_instance(new_instance); + + X2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n", + instance, + x2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", + x2ap_register_eNB->eNB_id); + /* initiate the SCTP listener */ + if (x2ap_eNB_init_sctp(new_instance,&x2ap_register_eNB->enb_x2_ip_address,x2ap_register_eNB->enb_port_for_X2C) < 0 ) { + X2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n"); + return; + } + X2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n", + instance, x2ap_register_eNB->eNB_id); + } +} + +static +void x2ap_eNB_handle_sctp_init_msg_multi_cnf( + instance_t instance_id, + sctp_init_msg_multi_cnf_t *m) +{ + x2ap_eNB_instance_t *instance; + int index; + + DevAssert(m != NULL); + + instance = x2ap_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) { + X2AP_ERROR("Error: be sure to properly configure X2 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_x2; index++) { + + X2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n", + instance_id, instance->eNB_id); + x2ap_eNB_register_eNB(instance, + &instance->target_enb_x2_ip_address[index], + &instance->enb_x2_ip_address, + instance->sctp_in_streams, + instance->sctp_out_streams, + instance->enb_port_for_X2C, + instance->multi_sd); + } +} + +void *x2ap_task(void *arg) +{ + MessageDef *received_msg = NULL; + int result; + + X2AP_DEBUG("Starting X2AP layer\n"); + + x2ap_eNB_prepare_internal_data(); + + itti_mark_task_ready(TASK_X2AP); + + while (1) { + itti_receive_msg(TASK_X2AP, &received_msg); + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + X2AP_WARN(" *** Exiting X2AP thread\n"); + itti_exit_task(); + break; + + case X2AP_REGISTER_ENB_REQ: + x2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_REGISTER_ENB_REQ(received_msg)); + 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); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_NEW_ASSOCIATION_IND: + x2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_DATA_IND: + x2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + default: + X2AP_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; +} + + diff --git a/openair2/X2AP/x2ap.h b/openair2/X2AP/x2ap_eNB.h similarity index 82% rename from openair2/X2AP/x2ap.h rename to openair2/X2AP/x2ap_eNB.h index 89e8540b97c75c3563cca8cbd899f4bf71db1701..1a19416122d0918fa20896b6f580c858758db90e 100644 --- a/openair2/X2AP/x2ap.h +++ b/openair2/X2AP/x2ap_eNB.h @@ -30,10 +30,12 @@ #ifndef X2AP_H_ #define X2AP_H_ -typedef struct x2ap_config_s { -} x2ap_config_t; +#define X2AP_SCTP_PPID (27) ///< X2AP SCTP Payload Protocol Identifier (PPID) +#include "x2ap_eNB_defs.h" -extern x2ap_config_t x2ap_config; +int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, + net_ip_address_t *local_ip_addr, + uint32_t enb_port_for_X2C); void *x2ap_task(void *arg); diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..f156d96d175beab05523d01625cd34324bc1e1a5 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -0,0 +1,127 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 <stdio.h> + +#include "assertions.h" +#include "intertask_interface.h" +#include "x2ap_common.h" +#include "x2ap_eNB_decoder.h" + +static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage.procedureCode) { + + case X2AP_ProcedureCode_id_x2Setup: + asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); + break; + + default: + X2AP_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 x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome.procedureCode) { + case X2AP_ProcedureCode_id_x2Setup: + asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + 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); + return -1; + } + + return 0; +} + +static int x2ap_eNB_decode_unsuccessful_outcome(X2AP_X2AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome.procedureCode) { + case X2AP_ProcedureCode_id_x2Setup: + asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_unsuccessfuloutcome_message!\n"); + break; + + default: + X2AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome.procedureCode); + return -1; + } + + return 0; +} + +int x2ap_eNB_decode_pdu(X2AP_X2AP_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_X2AP_X2AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + + xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu); + + if (dec_ret.code != RC_OK) { + X2AP_ERROR("Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case X2AP_X2AP_PDU_PR_initiatingMessage: + return x2ap_eNB_decode_initiating_message(pdu); + + case X2AP_X2AP_PDU_PR_successfulOutcome: + return x2ap_eNB_decode_successful_outcome(pdu); + + case X2AP_X2AP_PDU_PR_unsuccessfulOutcome: + return x2ap_eNB_decode_unsuccessful_outcome(pdu); + + default: + X2AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + + return -1; +} diff --git a/common/utils/itti/tasks_def.h b/openair2/X2AP/x2ap_eNB_decoder.h similarity index 81% rename from common/utils/itti/tasks_def.h rename to openair2/X2AP/x2ap_eNB_decoder.h index d54d09a26aee84822bb4714ab0857869682f1da5..9ce9ea3d40ef039a9c36c45163bdeb2969b0b9fb 100644 --- a/common/utils/itti/tasks_def.h +++ b/openair2/X2AP/x2ap_eNB_decoder.h @@ -19,7 +19,11 @@ * contact@openairinterface.org */ -// This task is mandatory and must always be placed in first position -TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10) +#ifndef X2AP_ENB_DECODER_H_ +#define X2AP_ENB_DECODER_H_ + +int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +__attribute__ ((warn_unused_result)); + +#endif /* X2AP_ENB_DECODER_H_ */ -// Dummy file for the generic intertask interface definition. Actual definition should be in top level build directory. diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..3014290206913e516b046bfc5dbab94fa64397b1 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -0,0 +1,195 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 <stdint.h> + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#ifndef X2AP_ENB_DEFS_H_ +#define X2AP_ENB_DEFS_H_ + +#define X2AP_ENB_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + X2AP_ENB_STATE_DISCONNECTED = 0x0, + + /* State waiting for x2 Setup response message if the target eNB accepts or + * X2 Setup failure if rejects the eNB. + */ + X2AP_ENB_STATE_WAITING = 0x1, + + /* The eNB is successfully connected to another eNB. */ + X2AP_ENB_STATE_CONNECTED = 0x2, + + /* X2AP is ready, and the eNB is successfully connected to another eNB. */ + X2AP_ENB_STATE_READY = 0x3, + + X2AP_ENB_STATE_OVERLOAD = 0x4, + + X2AP_ENB_STATE_RESETTING = 0x5, + + /* Max number of states available */ + X2AP_ENB_STATE_MAX, +} x2ap_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 x2ap_eNB_instance_s; + +/* This structure describes association of a eNB to another eNB */ +typedef struct x2ap_eNB_data_s { + /* eNB descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(x2ap_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). */ + //x2ap_load_state_t overload_state; + + /* Current eNB->eNB X2AP association state */ + x2ap_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/X2AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Only meaningfull in virtual mode */ + struct x2ap_eNB_instance_s *x2ap_eNB_instance; +} x2ap_eNB_data_t; + +typedef struct x2ap_eNB_instance_s { + /* used in simulation to store multiple eNB instances*/ + STAILQ_ENTRY(x2ap_eNB_instance_s) x2ap_eNB_entries; + + /* Number of target eNBs requested by eNB (tree size) */ + uint32_t x2_target_enb_nb; + /* Number of target eNBs for which association is pending */ + uint32_t x2_target_enb_pending_nb; + /* Number of target eNB successfully associated to eNB */ + uint32_t x2_target_enb_associated_nb; + /* Tree of X2AP eNB associations ordered by association ID */ + RB_HEAD(x2ap_enb_map, x2ap_eNB_data_s) x2ap_enb_head; + + /* Tree of UE ordered by eNB_ue_x2ap_id's */ + // RB_HEAD(x2ap_ue_map, x2ap_eNB_ue_context_s) x2ap_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; + + /* 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_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS]; + uint8_t nb_x2; + net_ip_address_t enb_x2_ip_address; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + uint32_t enb_port_for_X2C; + int multi_sd; +} x2ap_eNB_instance_t; + +typedef struct { + /* List of served eNBs + * Only used for virtual mode + */ + STAILQ_HEAD(x2ap_eNB_instances_head_s, x2ap_eNB_instance_s) x2ap_eNB_instances_head; + /* Nb of registered eNBs */ + uint8_t nb_registered_eNBs; + + /* Generate a unique connexion id used between X2AP and SCTP */ + uint16_t global_cnx_id; +} x2ap_eNB_internal_data_t; + +int x2ap_eNB_compare_assoc_id(struct x2ap_eNB_data_s *p1, struct x2ap_eNB_data_s *p2); + +/* Generate the tree management functions */ +struct x2ap_eNB_map; +struct x2ap_eNB_data_s; +RB_PROTOTYPE(x2ap_eNB_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id); + + +#endif /* X2AP_ENB_DEFS_H_ */ + diff --git a/openair3/UTILS/log.c b/openair2/X2AP/x2ap_eNB_encoder.c similarity index 60% rename from openair3/UTILS/log.c rename to openair2/X2AP/x2ap_eNB_encoder.c index 5ddebd415c7e83f79248c7cbae5023641b5b84fe..1eb617a7f1ddec817a88648fe25ddbef2ac9ad7c 100644 --- a/openair3/UTILS/log.c +++ b/openair2/X2AP/x2ap_eNB_encoder.c @@ -19,25 +19,36 @@ * contact@openairinterface.org */ -#if HAVE_CONFIG_H -# include "config.h" -#endif +#include <stdio.h> +#include <string.h> +#include <stdint.h> -#include "log.h" +#include "assertions.h" +#include "conversions.h" +#include "intertask_interface.h" +#include "x2ap_common.h" +#include "x2ap_eNB_encoder.h" -/* mme log */ -int log_enabled = 0; - -int log_init(const mme_config_t *mme_config_p, - log_specific_init_t specific_init) +int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) { - if (mme_config_p->verbosity_level == 1) { - log_enabled = 1; - } else if (mme_config_p->verbosity_level == 2) { - log_enabled = 1; - } else { - log_enabled = 0; + ssize_t encoded; + + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)pdu); } - return specific_init(mme_config_p->verbosity_level); + encoded = aper_encode_to_new_buffer(&asn_DEF_X2AP_X2AP_PDU, 0, pdu, (void **)buffer); + + if (encoded < 0) { + return -1; + } + + *len = encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, pdu); + return encoded; } diff --git a/common/utils/itti/timer_messages_def.h b/openair2/X2AP/x2ap_eNB_encoder.h similarity index 83% rename from common/utils/itti/timer_messages_def.h rename to openair2/X2AP/x2ap_eNB_encoder.h index 761034730d236136692f3d879aa44f252acc205c..04c77583b4f27c05fcc723100784bf418bf26c3a 100644 --- a/common/utils/itti/timer_messages_def.h +++ b/openair2/X2AP/x2ap_eNB_encoder.h @@ -19,4 +19,10 @@ * contact@openairinterface.org */ -MESSAGE_DEF(TIMER_HAS_EXPIRED, MESSAGE_PRIORITY_MED_PLUS, timer_has_expired_t, timer_has_expired) +#ifndef X2AP_ENB_ENCODER_H_ +#define X2AP_ENB_ENCODER_H_ + +int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +__attribute__ ((warn_unused_result)); + +#endif /* X2AP_ENB_ENCODER_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c new file mode 100644 index 0000000000000000000000000000000000000000..9c5a281506730409d8cf9b7048e4d68b90e826a7 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -0,0 +1,405 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 "x2ap_common.h" +#include "x2ap_eNB.h" +#include "x2ap_eNB_generate_messages.h" +#include "x2ap_eNB_encoder.h" + +#include "x2ap_eNB_itti_messaging.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +int x2ap_eNB_generate_x2_setup_request( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_X2SetupRequest_t *out; + X2AP_X2SetupRequest_IEs_t *ie; + X2AP_PLMN_Identity_t *plmn; + ServedCells__Member *servedCellMember; + X2AP_GU_Group_ID_t *gu; + + 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_x2Setup; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_X2SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.X2SetupRequest; + + /* mandatory */ + ie = (X2AP_X2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_X2SetupRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_X2SetupRequest_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 = X2AP_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); + X2AP_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 = (X2AP_X2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_X2SetupRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_ServedCells; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_X2SetupRequest_IEs__value_PR_ServedCells; + { + for (int i = 0; i<instance_p->num_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 = (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->servedCellInfo.broadcastPLMNs.list, plmn); + } + + if (instance_p->frame_type[i] == FDD) { + servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_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 = X2AP_Transmission_Bandwidth_bw6; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } + } + else { + AssertFatal(0,"X2Setuprequest not supported for TDD!"); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + } + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_X2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_X2SetupRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_GUGroupIDList; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_X2SetupRequest_IEs__value_PR_GUGroupIDList; + { + gu = (X2AP_GU_Group_ID_t *)calloc(1, sizeof(X2AP_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 (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode 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_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_X2SetupResponse_t *out; + X2AP_X2SetupResponse_IEs_t *ie; + X2AP_PLMN_Identity_t *plmn; + ServedCells__Member *servedCellMember; + X2AP_GU_Group_ID_t *gu; + + x2ap_eNB_instance_t *instance_p; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(x2ap_eNB_data_p != NULL); + + /* get the eNB instance */ + instance_p = x2ap_eNB_data_p->x2ap_eNB_instance; + + DevAssert(instance_p != NULL); + + /* 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_x2Setup; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_X2SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.X2SetupResponse; + + /* mandatory */ + ie = (X2AP_X2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_X2SetupResponse_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_X2SetupResponse_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 = X2AP_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); + X2AP_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 = (X2AP_X2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_X2SetupResponse_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_ServedCells; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_X2SetupResponse_IEs__value_PR_ServedCells; + { + for (int i = 0; i<instance_p->num_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 = (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->servedCellInfo.broadcastPLMNs.list, plmn); + } + + if (instance_p->frame_type[i] == FDD) { + servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_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 = X2AP_Transmission_Bandwidth_bw6; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } + } + else { + AssertFatal(0,"X2Setupresponse not supported for TDD!"); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); + } + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_X2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_X2SetupResponse_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_GUGroupIDList; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_X2SetupResponse_IEs__value_PR_GUGroupIDList; + { + gu = (X2AP_GU_Group_ID_t *)calloc(1, sizeof(X2AP_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 (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 setup response\n"); + return -1; + } + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_READY; + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/successfulOutcome 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_x2_setup_failure(instance_t instance, + uint32_t assoc_id, + X2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_X2SetupFailure_t *out; + X2AP_X2SetupFailure_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.unsuccessfulOutcome.procedureCode = X2AP_ProcedureCode_id_x2Setup; + pdu.choice.unsuccessfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = X2AP_UnsuccessfulOutcome__value_PR_X2SetupFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.X2SetupFailure; + + /* mandatory */ + ie = (X2AP_X2SetupFailure_IEs_t *)calloc(1, sizeof(X2AP_X2SetupFailure_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Cause; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_X2SetupFailure_IEs__value_PR_Cause; + + x2ap_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 = (X2AP_X2SetupFailure_IEs_t *)calloc(1, sizeof(X2AP_X2SetupFailure_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_TimeToWait; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_X2SetupFailure_IEs__value_PR_TimeToWait; + + if (time_to_wait > -1) { + ie->value.choice.TimeToWait = time_to_wait; + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 setup failure\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, + MSC_X2AP_TARGET_ENB, NULL, 0, + "0 X2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", + assoc_id, cause_type, cause_value); + + x2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0); + + return ret; +} + +int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, + X2AP_Cause_PR cause_type, + long cause_value) +{ + + DevAssert (cause_p != NULL); + cause_p->present = cause_type; + + switch (cause_type) { + case X2AP_Cause_PR_radioNetwork: + cause_p->choice.misc = cause_value; + break; + + case X2AP_Cause_PR_transport: + cause_p->choice.misc = cause_value; + break; + + case X2AP_Cause_PR_protocol: + cause_p->choice.misc = cause_value; + break; + + case X2AP_Cause_PR_misc: + cause_p->choice.misc = cause_value; + break; + + default: + return -1; + } + + return 0; +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h new file mode 100644 index 0000000000000000000000000000000000000000..a72b37e743da4ff24bdd8cd827ec0ffaeec47713 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -0,0 +1,44 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 X2AP_ENB_GENERATE_MESSAGES_H_ +#define X2AP_ENB_GENERATE_MESSAGES_H_ + +#include "x2ap_eNB_defs.h" +#include "x2ap_common.h" + +int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p, + x2ap_eNB_data_t *x2ap_enb_data_p); + +int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_enb_data_p); + +int x2ap_eNB_generate_x2_setup_failure(instance_t instance, + uint32_t assoc_id, + X2AP_Cause_PR cause_type, + long cause_value, + long time_to_wait); + +int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, + X2AP_Cause_PR cause_type, + long cause_value); + +#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ + diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..a16a3da5a8ac9d3b5fd998875fed3e61cd8cc5fc --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -0,0 +1,432 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 <stdint.h> + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "x2ap_common.h" +#include "x2ap_eNB_defs.h" +#include "x2ap_eNB_handler.h" +#include "x2ap_eNB_decoder.h" + +#include "x2ap_eNB_management_procedures.h" +#include "x2ap_eNB_generate_messages.h" + +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + +static +int x2ap_eNB_handle_x2_setup_request (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); +static +int x2ap_eNB_handle_x2_setup_response (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); +static +int x2ap_eNB_handle_x2_setup_failure (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +/* Handlers matrix. Only eNB related procedure present here */ +x2ap_message_decoded_callback x2ap_messages_callback[][3] = { + { 0, 0, 0 }, /* handoverPreparation */ + { 0, 0, 0 }, /* handoverCancel */ + { 0, 0, 0 }, /* loadIndication */ + { 0, 0, 0 }, /* errorIndication */ + { 0, 0, 0 }, /* snStatusTransfer */ + { 0, 0, 0 }, /* uEContextRelease */ + { x2ap_eNB_handle_x2_setup_request, x2ap_eNB_handle_x2_setup_response, x2ap_eNB_handle_x2_setup_failure }, /* x2Setup */ + { 0, 0, 0 }, /* reset */ + { 0, 0, 0 }, /* eNBConfigurationUpdate */ + { 0, 0, 0 }, /* resourceStatusReportingInitiation */ + { 0, 0, 0 }, /* resourceStatusReporting */ + { 0, 0, 0 }, /* privateMessage */ + { 0, 0, 0 }, /* mobilitySettingsChange */ + { 0, 0, 0 }, /* rLFIndication */ + { 0, 0, 0 }, /* handoverReport */ + { 0, 0, 0 }, /* cellActivation */ + { 0, 0, 0 }, /* x2Release */ + { 0, 0, 0 }, /* x2APMessageTransfer */ + { 0, 0, 0 }, /* x2Removal */ + { 0, 0, 0 }, /* seNBAdditionPreparation */ + { 0, 0, 0 }, /* seNBReconfigurationCompletion */ + { 0, 0, 0 }, /* meNBinitiatedSeNBModificationPreparation */ + { 0, 0, 0 }, /* seNBinitiatedSeNBModification */ + { 0, 0, 0 }, /* meNBinitiatedSeNBRelease */ + { 0, 0, 0 }, /* seNBinitiatedSeNBRelease */ + { 0, 0, 0 }, /* seNBCounterCheck */ + { 0, 0, 0 } /* retrieveUEContext */ +}; + +char *x2ap_direction2String(int x2ap_dir) { +static char *x2ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(x2ap_direction_String[x2ap_dir]); +} + +void x2ap_handle_x2_setup_message(x2ap_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 == X2AP_ENB_STATE_CONNECTED) { + enb_desc_p->state = X2AP_ENB_STATE_DISCONNECTED; + + if (enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb > 0) { + /* Decrease associated eNB number */ + enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb --; + } + + /* If there are no more associated eNB, inform eNB app */ + if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_X2AP, X2AP_DEREGISTERED_ENB_IND); + X2AP_DEREGISTERED_ENB_IND(message_p).nb_x2 = 0; + itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p); + } + } + } else { + /* Check that at least one setup message is pending */ + DevCheck(enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0, + enb_desc_p->x2ap_eNB_instance->instance, + enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb, 0); + + if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0) { + /* Decrease pending messages number */ + enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb --; + } + + /* If there are no more pending messages, inform eNB app */ + if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_X2AP, X2AP_REGISTER_ENB_CNF); + X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb; + itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p); + } + } +} + + +int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t *const data, const uint32_t data_length) +{ + X2AP_X2AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + if (x2ap_eNB_decode_pdu(&pdu, data, data_length) < 0) { + X2AP_ERROR("Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(x2ap_messages_callback) / (3 * sizeof( + x2ap_message_decoded_callback)) + || (pdu.present > X2AP_X2AP_PDU_PR_unsuccessfulOutcome)) { + X2AP_ERROR("[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_X2AP_X2AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (x2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + X2AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + x2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + ret = (*x2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return ret; +} + +int +x2ap_eNB_handle_x2_setup_request(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_X2SetupRequest_t *x2SetupRequest; + X2AP_X2SetupRequest_IEs_t *ie; + + x2ap_eNB_data_t *x2ap_eNB_data; + uint32_t eNB_id = 0; + + DevAssert (pdu != NULL); + x2SetupRequest = &pdu->choice.initiatingMessage.value.choice.X2SetupRequest; + + /* + * 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 + */ + 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_X2SetupRequest_IEs_t, ie, x2SetupRequest, + X2AP_ProtocolIE_ID_id_GlobalENB_ID, true); + + if (ie->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->value.choice.GlobalENB_ID.eNB_ID.choice.home_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); + X2AP_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); + 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); + + DevAssert(x2ap_eNB_data->x2ap_eNB_instance != NULL); + x2ap_eNB_generate_x2_setup_failure (x2ap_eNB_data->x2ap_eNB_instance->instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + return -1; + } + /* + * TODO: call the reset procedure + */ + } + + return x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data); +} + +static +int x2ap_eNB_handle_x2_setup_response(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_X2SetupResponse_t *x2SetupResponse; + X2AP_X2SetupResponse_IEs_t *ie; + + x2ap_eNB_data_t *x2ap_eNB_data; + uint32_t eNB_id = 0; + + DevAssert (pdu != NULL); + x2SetupResponse = &pdu->choice.successfulOutcome.value.choice.X2SetupResponse; + + /* + * We received a new valid X2 Setup Response on a stream != 0. + * * * * This should not happen -> reject eNB x2 setup response. + */ + + if (stream != 0) { + X2AP_ERROR("Received new x2 setup response on stream != 0\n"); + } + + if ((x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0)) == NULL) { + X2AP_ERROR("[SCTP %d] Received X2 setup response for non existing " + "eNB context\n", assoc_id); + return -1; + } + + X2AP_DEBUG("Received a new X2 setup response\n"); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse, + X2AP_ProtocolIE_ID_id_GlobalENB_ID, true); + + if (ie->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->value.choice.GlobalENB_ID.eNB_ID.choice.home_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); + X2AP_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); + 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) { + /* + * ??: Send an overload cause... + */ + 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; + /* + * TODO: call the reset procedure + */ + } + + /* 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. + */ + x2ap_eNB_data->state = X2AP_ENB_STATE_READY; + x2ap_eNB_data->x2ap_eNB_instance->x2_target_enb_associated_nb ++; + x2ap_handle_x2_setup_message(x2ap_eNB_data, 0); + + return 0; +} + +static +int x2ap_eNB_handle_x2_setup_failure(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_X2SetupFailure_t *x2SetupFailure; + X2AP_X2SetupFailure_IEs_t *ie; + + x2ap_eNB_data_t *x2ap_eNB_data; + + DevAssert(pdu != NULL); + + x2SetupFailure = &pdu->choice.unsuccessfulOutcome.value.choice.X2SetupFailure; + + /* + * We received a new valid X2 Setup Failure on a stream != 0. + * * * * This should not happen -> reject eNB x2 setup failure. + */ + + if (stream != 0) { + X2AP_WARN("[SCTP %d] Received x2 setup failure on stream != 0 (%d)\n", + assoc_id, stream); + } + + if ((x2ap_eNB_data = x2ap_get_eNB (NULL, assoc_id, 0)) == NULL) { + X2AP_ERROR("[SCTP %d] Received X2 setup failure for non existing " + "eNB context\n", assoc_id); + return -1; + } + + X2AP_DEBUG("Received a new X2 setup failure\n"); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure, + X2AP_ProtocolIE_ID_id_Cause, true); + + + // need a FSM to handle all cases + if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) && + (ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) { + X2AP_WARN("Received X2 setup failure for eNB ... eNB is not ready\n"); + } else { + X2AP_ERROR("Received x2 setup failure for eNB... please check your parameters\n"); + } + + x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING; + x2ap_handle_x2_setup_message(x2ap_eNB_data, 0); + + return 0; +} diff --git a/openair3/UTILS/log.h b/openair2/X2AP/x2ap_eNB_handler.h similarity index 73% rename from openair3/UTILS/log.h rename to openair2/X2AP/x2ap_eNB_handler.h index 7b712df755437a9048c7204618ae5d4832c49f29..0f93859a84213e273c3a19eac0dd158d1616212e 100644 --- a/openair3/UTILS/log.h +++ b/openair2/X2AP/x2ap_eNB_handler.h @@ -19,19 +19,15 @@ * contact@openairinterface.org */ -#include "mme_config.h" +#ifndef X2AP_ENB_HANDLERS_H_ +#define X2AP_ENB_HANDLERS_H_ -#ifndef LOG_H_ -#define LOG_H_ +#include "x2ap_eNB_defs.h" -/* asn1c debug */ -extern int asn_debug; -extern int asn1_xer_print; -extern int fd_g_debug_lvl; +void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); -typedef int (*log_specific_init_t)(int log_level); +int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); -int log_init(const mme_config_t *mme_config, - log_specific_init_t specific_init); +#endif /* X2AP_ENB_HANDLERS_H_ */ -#endif /* LOG_H_ */ diff --git a/openair2/X2AP/x2ap.c b/openair2/X2AP/x2ap_eNB_itti_messaging.c similarity index 50% rename from openair2/X2AP/x2ap.c rename to openair2/X2AP/x2ap_eNB_itti_messaging.c index 8002867e15c31c8b78ada0894c9bbef20ae2cef1..d8e1e19afeeae608e1d44b18784ca1ec0aa293a6 100644 --- a/openair2/X2AP/x2ap.c +++ b/openair2/X2AP/x2ap_eNB_itti_messaging.c @@ -19,53 +19,38 @@ * contact@openairinterface.org */ -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> - - #include "intertask_interface.h" -#include "x2ap.h" - -#include "assertions.h" -#include "conversions.h" - +#include "x2ap_eNB_itti_messaging.h" -void *x2ap_task(void *arg) +void x2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) { - MessageDef *received_msg = NULL; - int result; + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; - X2AP_DEBUG("Starting X2AP layer\n"); + message_p = itti_alloc_new_message(TASK_X2AP, SCTP_DATA_REQ); - x2ap_prepare_internal_data(); + sctp_data_req = &message_p->ittiMsg.sctp_data_req; - itti_mark_task_ready(TASK_X2AP); + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; - while (1) { - itti_receive_msg(TASK_X2AP, &received_msg); - - switch (ITTI_MSG_ID(received_msg)) { - case TERMINATE_MESSAGE: - X2AP_WARN(" *** Exiting X2AP thread\n"); - itti_exit_task(); - break; + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} - default: - X2AP_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); +void x2ap_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; - received_msg = NULL; - } + message_p = itti_alloc_new_message(TASK_X2AP, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; - return NULL; + itti_send_msg_to_task(TASK_SCTP, instance, message_p); } - diff --git a/common/utils/itti/messages_types.h b/openair2/X2AP/x2ap_eNB_itti_messaging.h similarity index 73% rename from common/utils/itti/messages_types.h rename to openair2/X2AP/x2ap_eNB_itti_messaging.h index d390bf0159c18ab58767e44f467fe2b4019c667b..55bf58b6605260c85c70b4d5887f768c42f3e49f 100644 --- a/common/utils/itti/messages_types.h +++ b/openair2/X2AP/x2ap_eNB_itti_messaging.h @@ -19,19 +19,14 @@ * contact@openairinterface.org */ -/* - * messages_types.h - * - * Created on: Oct 14, 2013 - * Author: winckel - */ +#ifndef X2AP_ENB_ITTI_MESSAGING_H_ +#define X2AP_ENB_ITTI_MESSAGING_H_ + +void x2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); -#ifndef MESSAGES_TYPES_H_ -#define MESSAGES_TYPES_H_ -#include "intertask_messages_types.h" -#include "timer_messages_types.h" +void x2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id); -// Dummy file for the generic intertask interface definition. Actual definition should be in top level build directory. -#endif /* MESSAGES_TYPES_H_ */ +#endif /* X2AP_ENB_ITTI_MESSAGING_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c new file mode 100644 index 0000000000000000000000000000000000000000..c2b128ffd312c4c042dc397b992dd62ff6641bc2 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_management_procedures.c @@ -0,0 +1,236 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "x2ap_common.h" +#include "x2ap_eNB_defs.h" +#include "x2ap_eNB.h" + + +#define X2AP_DEBUG_LIST +#ifdef X2AP_DEBUG_LIST +# define X2AP_eNB_LIST_OUT(x, args...) X2AP_DEBUG("[eNB]%*s"x"\n", 4*indent, "", ##args) +#else +# define X2AP_eNB_LIST_OUT(x, args...) +#endif + +static int indent = 0; + + +x2ap_eNB_internal_data_t x2ap_eNB_internal_data; + +RB_GENERATE(x2ap_enb_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id); + +int x2ap_eNB_compare_assoc_id( + struct x2ap_eNB_data_s *p1, struct x2ap_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 x2ap_eNB_fetch_add_global_cnx_id(void) +{ + return ++x2ap_eNB_internal_data.global_cnx_id; +} + +void x2ap_eNB_prepare_internal_data(void) +{ + memset(&x2ap_eNB_internal_data, 0, sizeof(x2ap_eNB_internal_data)); + STAILQ_INIT(&x2ap_eNB_internal_data.x2ap_eNB_instances_head); +} + +void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&x2ap_eNB_internal_data.x2ap_eNB_instances_head, + new_instance_p, x2ap_eNB_entries); +} + +void dump_tree(x2ap_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(t->entry.rbe_left); + dump_tree(t->entry.rbe_right); +} + +void dump_trees(void) +{ +x2ap_eNB_instance_t *zz; +STAILQ_FOREACH(zz, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, + x2ap_eNB_entries) { +printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +dump_tree(zz->x2ap_enb_head.rbh_root); +printf("---------------------------------------------\n"); +} +} + +struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id) +{ + 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(); + + memset(&temp, 0, sizeof(struct x2ap_eNB_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, + x2ap_eNB_entries) { + found = RB_FIND(x2ap_enb_map, &instance_p->x2ap_enb_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(x2ap_enb_map, &instance_p->x2ap_enb_head, &temp); + } + + return NULL; +} + + +x2ap_eNB_instance_t *x2ap_eNB_get_instance(instance_t instance) +{ + x2ap_eNB_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, + x2ap_eNB_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} + + +/// utility functions + +void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref); + +void +x2ap_dump_eNB_list (void) { + x2ap_eNB_instance_t *inst = NULL; + struct x2ap_eNB_data_s *found = NULL; + struct x2ap_eNB_data_s temp; + + memset(&temp, 0, sizeof(struct x2ap_eNB_data_s)); + + STAILQ_FOREACH (inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { + found = RB_FIND(x2ap_enb_map, &inst->x2ap_enb_head, &temp); + x2ap_dump_eNB (found); + } +} + +void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref) { + + if (eNB_ref == NULL) { + return; + } + + X2AP_eNB_LIST_OUT (""); + X2AP_eNB_LIST_OUT ("eNB name: %s", eNB_ref->eNB_name == NULL ? "not present" : eNB_ref->eNB_name); + X2AP_eNB_LIST_OUT ("eNB STATE: %07x", eNB_ref->state); + X2AP_eNB_LIST_OUT ("eNB ID: %07x", eNB_ref->eNB_id); + indent++; + X2AP_eNB_LIST_OUT ("SCTP cnx id: %d", eNB_ref->cnx_id); + X2AP_eNB_LIST_OUT ("SCTP assoc id: %d", eNB_ref->assoc_id); + X2AP_eNB_LIST_OUT ("SCTP instreams: %d", eNB_ref->in_streams); + X2AP_eNB_LIST_OUT ("SCTP outstreams: %d", eNB_ref->out_streams); + indent--; +} + + +x2ap_eNB_data_t * x2ap_is_eNB_id_in_list (const uint32_t eNB_id) +{ + x2ap_eNB_instance_t *inst; + struct x2ap_eNB_data_s *elm; + + STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { + RB_FOREACH(elm, x2ap_enb_map, &inst->x2ap_enb_head) { + if (elm->eNB_id == eNB_id) + return elm; + } + } + return NULL; +} + +x2ap_eNB_data_t * x2ap_is_eNB_assoc_id_in_list (const uint32_t sctp_assoc_id) +{ + x2ap_eNB_instance_t *inst; + struct x2ap_eNB_data_s *found; + struct x2ap_eNB_data_s temp; + + temp.assoc_id = sctp_assoc_id; + temp.cnx_id = -1; + + STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { + found = RB_FIND(x2ap_enb_map, &inst->x2ap_enb_head, &temp); + if (found != NULL){ + if (found->assoc_id == sctp_assoc_id) { + return found; + } + } + } + return NULL; +} + diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.h b/openair2/X2AP/x2ap_eNB_management_procedures.h new file mode 100644 index 0000000000000000000000000000000000000000..b66a6d10356536508f5dad4d44a960da61a7f094 --- /dev/null +++ b/openair2/X2AP/x2ap_eNB_management_procedures.h @@ -0,0 +1,46 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the 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 X2AP_ENB_MANAGEMENT_PROCEDURES_H_ +#define X2AP_ENB_MANAGEMENT_PROCEDURES_H + +void x2ap_eNB_prepare_internal_data(void); + +void dump_trees(void); + +void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p); + +x2ap_eNB_instance_t *x2ap_eNB_get_instance(uint8_t mod_id); + +uint16_t x2ap_eNB_fetch_add_global_cnx_id(void); + +void x2ap_eNB_prepare_internal_data(void); + +x2ap_eNB_data_t* x2ap_is_eNB_id_in_list(uint32_t eNB_id); + +x2ap_eNB_data_t* x2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id); + +struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p, + int32_t assoc_id, + uint16_t cnx_id); + +#endif /* X2AP_ENB_MANAGEMENT_PROCEDURES_H_ */ + diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index b9d81602c267bf6caff08d6d1362ce1812a80b0e..1e2cd85710752e7aff39f0241b56e833ef9e2781 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -33,7 +33,6 @@ #include "assertions.h" #include "intertask_interface.h" -#include "timer.h" #include "msc.h" #include "gtpv1u.h" @@ -50,120 +49,13 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" #include "gtpv1u_eNB_defs.h" +#include "gtpv1u_eNB_task.h" #undef GTP_DUMP_SOCKET -/* -extern boolean_t pdcp_data_req( - const protocol_ctxt_t* const ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t * const sourceL2Id - ,const uint32_t * const destinationL2Id -#endif - ); - - const pdcp_transmission_mode_t modeP); -*/ extern unsigned char NB_eNB_INST; extern RAN_CONTEXT_t RC; -static int -gtpv1u_eNB_send_init_udp( - uint16_t port_number); - -NwGtpv1uRcT -gtpv1u_eNB_log_request( - NwGtpv1uLogMgrHandleT hLogMgr, - uint32_t logLevel, - NwCharT *file, - uint32_t line, - NwCharT *logStr); - -NwGtpv1uRcT -gtpv1u_eNB_send_udp_msg( - NwGtpv1uUdpHandleT udpHandle, - uint8_t *buffer, - uint32_t buffer_len, - uint32_t buffer_offset, - uint32_t peerIpAddr, - uint16_t peerPort); - -NwGtpv1uRcT -gtpv1u_eNB_process_stack_req( - NwGtpv1uUlpHandleT hUlp, - NwGtpv1uUlpApiT *pUlpApi); - -int -data_recv_callback( - uint16_t portP, - uint32_t address, - uint8_t *buffer, - uint32_t length, - void *arg_p); -//int -//gtpv1u_create_tunnel_endpoint( -// gtpv1u_data_t *gtpv1u_data_pP, -// uint8_t ue_idP, -// uint8_t rab_idP, -// char *sgw_ip_addr_pP, -// uint16_t portP); -static NwGtpv1uRcT -gtpv1u_start_timer_wrapper( - NwGtpv1uTimerMgrHandleT tmrMgrHandle, - uint32_t timeoutSec, - uint32_t timeoutUsec, - uint32_t tmrType, - void *timeoutArg, - NwGtpv1uTimerHandleT *hTmr); - -static NwGtpv1uRcT -gtpv1u_stop_timer_wrapper( - NwGtpv1uTimerMgrHandleT tmrMgrHandle, - NwGtpv1uTimerHandleT hTmr); - -int -gtpv1u_initial_req( - gtpv1u_data_t *gtpv1u_data_pP, - teid_t teidP, - tcp_udp_port_t portP, - uint32_t address); - -int -gtpv1u_new_data_req( - uint8_t enb_module_idP, - rnti_t ue_rntiP, - uint8_t rab_idP, - uint8_t *buffer_pP, - uint32_t buf_lenP, - uint32_t buf_offsetP -); - -int -gtpv1u_create_s1u_tunnel( - const instance_t instanceP, - const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP); - -static int -gtpv1u_delete_s1u_tunnel( - const instance_t instanceP, - const gtpv1u_enb_delete_tunnel_req_t * const req_pP); - -static int -gtpv1u_eNB_init(void); - -void * -gtpv1u_eNB_task(void *args); - -//static gtpv1u_data_t gtpv1u_data_g; - #if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 #include <linux/if.h> static int gtpv1u_dump_socket_g; @@ -216,11 +108,11 @@ static void gtpv1u_eNB_write_dump_socket(uint8_t *buffer_pP, uint32_t buffer_len #endif //----------------------------------------------------------------------------- -static int gtpv1u_eNB_send_init_udp(uint16_t port_number) +static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req * req) { // Create and alloc new message MessageDef *message_p; - struct in_addr addr; + struct in_addr addr={0}; message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_INIT); @@ -228,12 +120,10 @@ static int gtpv1u_eNB_send_init_udp(uint16_t port_number) return -1; } - UDP_INIT(message_p).port = port_number; - //LG UDP_INIT(message_p).address = "0.0.0.0"; //ANY address - - addr.s_addr = RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up; + UDP_INIT(message_p).port = req->enb_port_for_S1u_S12_S4_up; + addr.s_addr = req->enb_ip_address_for_S1u_S12_S4_up; UDP_INIT(message_p).address = inet_ntoa(addr); - LOG_I(GTPU, "Tx UDP_INIT IP addr %s (%x)\n", UDP_INIT(message_p).address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); + LOG_I(GTPU, "Tx UDP_INIT IP addr %s (%x)\n", UDP_INIT(message_p).address,UDP_INIT(message_p).port); MSC_LOG_EVENT( MSC_GTPU_ENB, @@ -243,6 +133,16 @@ static int gtpv1u_eNB_send_init_udp(uint16_t port_number) return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p); } +static int gtpv1u_s1_req( + const instance_t instanceP, + const Gtpv1uS1Req * const req) { + memcpy(&RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, + &req->enb_ip_address_for_S1u_S12_S4_up, + sizeof (req->enb_ip_address_for_S1u_S12_S4_up)); + gtpv1u_eNB_send_init_udp(req); + return 0; +} + //----------------------------------------------------------------------------- NwGtpv1uRcT gtpv1u_eNB_log_request(NwGtpv1uLogMgrHandleT hLogMgr, uint32_t logLevel, @@ -1000,23 +900,17 @@ static int gtpv1u_delete_s1u_tunnel( //----------------------------------------------------------------------------- -static int gtpv1u_eNB_init(void) +int gtpv1u_eNB_init(void) { - int ret; NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uUlpEntityT ulp; NwGtpv1uUdpEntityT udp; NwGtpv1uLogMgrEntityT log; NwGtpv1uTimerMgrEntityT tmr; - // enb_properties_p = enb_config_get()->properties[0]; - RC.gtpv1u_data_g = (gtpv1u_data_t*)malloc(sizeof(gtpv1u_data_t)); - memset(RC.gtpv1u_data_g, 0, sizeof(gtpv1u_data_t)); - - RCconfig_gtpu(); - - + RC.gtpv1u_data_g = (gtpv1u_data_t*)calloc(sizeof(gtpv1u_data_t),1); + LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.gtpv1u_data_g); //gtpv1u_data_g.gtpv1u_stack; /* Initialize UE hashtable */ @@ -1025,7 +919,6 @@ static int gtpv1u_eNB_init(void) RC.gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL); AssertFatal(RC.gtpv1u_data_g->teid_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create\n"); // RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U; - RC.gtpv1u_data_g->ip_addr = NULL; //gtpv1u_data_g.udp_data; RC.gtpv1u_data_g->seq_num = 0; @@ -1090,35 +983,21 @@ static int gtpv1u_eNB_init(void) } #endif - ret = gtpv1u_eNB_send_init_udp(RC.gtpv1u_data_g->enb_port_for_S1u_S12_S4_up); - - if (ret < 0) { - return ret; - } LOG_D(GTPU, "Initializing GTPV1U interface for eNB: DONE\n"); return 0; } - //----------------------------------------------------------------------------- -void *gtpv1u_eNB_task(void *args) -{ - int rc = 0; - instance_t instance; - //const char *msg_name_p; - - rc = gtpv1u_eNB_init(); - AssertFatal(rc == 0, "gtpv1u_eNB_init Failed"); - itti_mark_task_ready(TASK_GTPV1_U); - MSC_START_USE(); - - while(1) { +void *gtpv1u_eNB_process_itti_msg(void *notUsed) { /* Trying to fetch a message from the message queue. * If the queue is empty, this function will block till a * message is sent to the task. */ + instance_t instance; MessageDef *received_message_p = NULL; + int rc = 0; + itti_receive_msg(TASK_GTPV1_U, &received_message_p); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN); DevAssert(received_message_p != NULL); @@ -1128,6 +1007,9 @@ void *gtpv1u_eNB_task(void *args) switch (ITTI_MSG_ID(received_message_p)) { + case GTPV1U_ENB_S1_REQ: + gtpv1u_s1_req(instance, &received_message_p->ittiMsg.gtpv1uS1Req); + case GTPV1U_ENB_DELETE_TUNNEL_REQ: { gtpv1u_delete_s1u_tunnel(instance, &received_message_p->ittiMsg.Gtpv1uDeleteTunnelReq); } @@ -1259,6 +1141,22 @@ void *gtpv1u_eNB_task(void *args) AssertFatal(rc == EXIT_SUCCESS, "Failed to free memory (%d)!\n", rc); received_message_p = NULL; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_OUT); + + return NULL; +} + +//----------------------------------------------------------------------------- +void *gtpv1u_eNB_task(void *args) +{ + int rc = 0; + + rc = gtpv1u_eNB_init(); + AssertFatal(rc == 0, "gtpv1u_eNB_init Failed"); + itti_mark_task_ready(TASK_GTPV1_U); + MSC_START_USE(); + + while(1) { + (void) gtpv1u_eNB_process_itti_msg (NULL); } return NULL; diff --git a/openair3/GTPV1-U/gtpv1u_eNB_defs.h b/openair3/GTPV1-U/gtpv1u_eNB_defs.h index ddd996625ef614f7fb91a918c855526810acffb9..db928c4438d927cd333b59ac6caaef3b72513198 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB_defs.h +++ b/openair3/GTPV1-U/gtpv1u_eNB_defs.h @@ -97,8 +97,6 @@ typedef struct gtpv1u_data_s { //RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head; /* Local IP address to use */ in_addr_t enb_ip_address_for_S1u_S12_S4_up; - char *ip_addr; - tcp_udp_port_t enb_port_for_S1u_S12_S4_up; /* UDP internal data */ //udp_data_t udp_data; diff --git a/openair3/GTPV1-U/gtpv1u_eNB_task.h b/openair3/GTPV1-U/gtpv1u_eNB_task.h index 5a7822fe8c7322e12a6a32d231cec8c6af1d1df6..9830ea6169975439e708a840e20e29ea4af91cee 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB_task.h +++ b/openair3/GTPV1-U/gtpv1u_eNB_task.h @@ -29,7 +29,6 @@ #ifndef GTPV1U_ENB_TASK_H_ #define GTPV1U_ENB_TASK_H_ -#include "messages_types.h" /* int @@ -41,6 +40,8 @@ gtpv1u_new_data_req( uint32_t buf_len, uint32_t buf_offset);*/ +int gtpv1u_eNB_init(void); +void *gtpv1u_eNB_process_itti_msg(void*); void *gtpv1u_eNB_task(void *args); int diff --git a/openair3/GTPV1-U/gtpv1u_task.c b/openair3/GTPV1-U/gtpv1u_task.c index 287c22b7e7ab28d162f6b36815b11eb14b629588..e821885ab5198055484b183f12eef1411b243b9a 100644 --- a/openair3/GTPV1-U/gtpv1u_task.c +++ b/openair3/GTPV1-U/gtpv1u_task.c @@ -35,7 +35,6 @@ #include "assertions.h" #include "intertask_interface.h" -#include "timer.h" #include "gtpv1u.h" #include "NwGtpv1u.h" diff --git a/openair3/NAS/COMMON/UTIL/nas_log.c b/openair3/NAS/COMMON/UTIL/nas_log.c deleted file mode 100644 index 6af90c4be871ab88e0a698c0926efd43f9f87b09..0000000000000000000000000000000000000000 --- a/openair3/NAS/COMMON/UTIL/nas_log.c +++ /dev/null @@ -1,273 +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 - */ - -/***************************************************************************** -Source nas_log.c - -Version 0.1 - -Date 2012/02/28 - -Product NAS stack - -Subsystem Utilities - -Author Frederic Maurel - -Description Usefull logging functions - -*****************************************************************************/ - -#include "nas_log.h" -#if defined(NAS_BUILT_IN_UE) && defined(NAS_UE) -int nas_log_func_indent; -#else -#include <stdio.h> // stderr, sprintf, fprintf, vfprintf -#include <stdarg.h> // va_list, va_start, va_end -#include <string.h> // strlen - -/****************************************************************************/ -/**************** E X T E R N A L D E F I N I T I O N S ****************/ -/****************************************************************************/ - -/* ANSI escape codes for colored display */ -#define LOG_BLACK "\033[30m" -#define LOG_RED "\033[31m" -#define LOG_GREEN "\033[32m" -#define LOG_YELLOW "\033[33m" -#define LOG_BLUE "\033[34m" -#define LOG_MAGENTA "\033[35m" -#define LOG_CYAN "\033[36m" -#define LOG_WHITE "\033[37m" -#define LOG_END "\033[0m" -#define LOG_AUTO LOG_END - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -/* ------------------------ - * Internal logging context - * ------------------------ - * Internal logging context consists on: - * - The file name and the line number from where the data have been - * logged. These information are gathered into a string that will - * be displayed as a prefix of the logging trace with the format - * filename[line] - * - The severity level filter - * - The indentation level to convey FUNC logging traces - * - The data definition of each logging trace level: name and mask - * (the mask is used against the severity level filter to enable - * or disable specific logging traces) - */ -typedef struct { -#define LOG_PREFIX_SIZE 118 - char prefix[LOG_PREFIX_SIZE]; - unsigned char filter; - int indent; - const struct { - char* name; - unsigned char mask; - char* color; - } level[]; -} log_context_t; - -/* - * Definition of the logging context - */ -static log_context_t _log_context = { - "", /* prefix */ - 0x00, /* filter */ - 0, /* indent */ - { - { "DEBUG", NAS_LOG_DEBUG, LOG_GREEN }, /* DEBUG */ - { "INFO", NAS_LOG_INFO, LOG_AUTO }, /* INFO */ - { "WARNING", NAS_LOG_WARNING, LOG_BLUE }, /* WARNING */ - { "ERROR", NAS_LOG_ERROR, LOG_RED }, /* ERROR */ - { "", NAS_LOG_FUNC, LOG_AUTO }, /* FUNC_IN */ - { "", NAS_LOG_FUNC, LOG_AUTO }, /* FUNC_OUT */ - } /* level[] */ -}; - -/* Maximum number of bytes into a line of dump logging data */ -#define LOG_DUMP_LINE_SIZE 16 - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: log_init() ** - ** ** - ** Description: Initializes internal logging data ** - ** ** - ** Inputs: filter: Value of the severity level that will be ** - ** used as a filter to enable or disable ** - ** specific logging traces ** - ** Others: None ** - ** ** - ** Outputs: Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void nas_log_init(char filter) -{ - _log_context.filter = filter; -} - -/**************************************************************************** - ** ** - ** Name: log_data() ** - ** ** - ** Description: Defines internal logging data ** - ** ** - ** Inputs: filename: Name of the file from where the data have ** - ** been logged ** - ** line: Number of the line in the file ** - ** Others: None ** - ** ** - ** Outputs: Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void log_data(const char* filename, int line) -{ - int len = strlen(filename) + 2 + 1; //2:[], 1:/0 - if (line > 9999) len+=5; - else if (line > 999) len+=4; - else if (line > 99) len+=3; - else if (line > 9) len+=2; - else len+=1; - if (len > LOG_PREFIX_SIZE) { - snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s:%d", &filename[len - LOG_PREFIX_SIZE], line); - } else { - snprintf(_log_context.prefix, LOG_PREFIX_SIZE, "%s:%d", filename, line); - } -} - -/**************************************************************************** - ** ** - ** Name: log_trace() ** - ** ** - ** Description: Displays logging data ** - ** ** - ** Inputs: severity: Severity level of the logging data ** - ** data: Formated logging data to display ** - ** Others: None ** - ** ** - ** Outputs: Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void log_trace(log_severity_t severity, const char* data, ...) -{ - int i; - - /* Sanity check */ - if (severity > LOG_SEVERITY_MAX) return; - - /* Display only authorized logging traces */ - if (_log_context.level[severity].mask & _log_context.filter) { - va_list argp; - - /* - * First, display internal logging data (logging trace prefix: file - * name and line number from where the data have been logged) and - * the severity level. - */ - fprintf(stderr, "%s%-120.118s%-10s", _log_context.level[severity].color, - _log_context.prefix, _log_context.level[severity].name); - { - /* Next, perform indentation for FUNC logging trace */ - if (severity == FUNC_OUT) { - _log_context.indent--; - } - - for (i=0; i<_log_context.indent; i++) { - fprintf(stderr, " "); - } - - if (severity == FUNC_IN) { - _log_context.indent++; - } - } - - /* Finally, display logging data */ - va_start(argp, data); - vfprintf(stderr, data, argp); - - /* Terminate with line feed character */ - fprintf(stderr, "%s\n", LOG_END); - - va_end(argp); - } -} - -/**************************************************************************** - ** ** - ** Name: log_dump() ** - ** ** - ** Description: Dump logging data ** - ** ** - ** Inputs: data: Logging data to dump ** - ** len: Number of bytes to be dumped ** - ** Others: None ** - ** ** - ** Outputs: Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void log_dump(const char* data, int len) -{ - int i; - - /* Display only authorized logging traces */ - if ( (len > 0) && (NAS_LOG_HEX & _log_context.filter) ) { - int bytes = 0; - - fprintf(stderr, "\n\t"); - - for (i=0; i < len; i++) { - fprintf(stderr, "%.2hx ", (const unsigned char) data[i]); - - /* Add new line when the number of displayed bytes exceeds - * the line's size */ - if ( ++bytes > (LOG_DUMP_LINE_SIZE - 1) ) { - bytes = 0; - fprintf(stderr, "\n\t"); - } - } - - if (bytes % LOG_DUMP_LINE_SIZE) { - fprintf(stderr, "\n"); - } - - fprintf(stderr, "\n"); - fflush(stderr); - } -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ -#endif - diff --git a/openair3/NAS/COMMON/UTIL/nas_log.h b/openair3/NAS/COMMON/UTIL/nas_log.h index c36e0795c7a141b1115d359773b376c7f86c5ec7..b41e34c51be03fe99aeeccfc104a580337e3e4a8 100644 --- a/openair3/NAS/COMMON/UTIL/nas_log.h +++ b/openair3/NAS/COMMON/UTIL/nas_log.h @@ -95,7 +95,7 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -#if defined(NAS_BUILT_IN_UE) && defined(NAS_UE) +#ifdef LOG_E # define LOG_TRACE(s, x, args...) \ do { \ switch (s) { \ @@ -106,54 +106,21 @@ do { \ } \ } while (0) -# define LOG_DUMP(dATA, lEN) \ -do { \ - char buffer[3*lEN + 1]; \ - int i; \ - for (i = 0; i < lEN; i++) \ - sprintf (&buffer[3*i], "%02x ", dATA[i]); \ - LOG_D(NAS, " Dump %d: %s\n", lEN, buffer); \ -} while (0) - -# define LOG_FUNC_IN \ -do { \ - LOG_D(NAS, " %s:%d %*sEntering %s()\n", __FILE__, __LINE__, nas_log_func_indent, "", __FUNCTION__); \ - nas_log_func_indent += 2; \ -} while (0) - -# define LOG_FUNC_OUT \ -do { \ - nas_log_func_indent -= 2; \ - LOG_D(NAS, " %s:%d %*sLeaving %s()\n", __FILE__, __LINE__, nas_log_func_indent, "", __FUNCTION__); \ -} while (0) - -# define LOG_FUNC_RETURN(rETURNcODE) \ -do { \ - nas_log_func_indent -= 2; \ - LOG_D(NAS, " %s:%d %*sLeaving %s(rc = %ld)\n", __FILE__, __LINE__, nas_log_func_indent, "", \ - __FUNCTION__, (long) (rETURNcODE)); \ - return (rETURNcODE); \ -} while (0) +# define LOG_DUMP(dATA, lEN) LOG_DUMPMSG(NAS, DEBUG_NAS,dATA, lEN, " Dump %d:\n", lEN) +# define LOG_FUNC_IN LOG_ENTER(NAS) +# define LOG_FUNC_OUT LOG_END(NAS) +# define LOG_FUNC_RETURN(rETURNcODE) LOG_RETURN(NAS,rETURNcODE) extern int nas_log_func_indent; #else -# define LOG_TRACE log_data(__FILE__, __LINE__); log_trace -# define LOG_DUMP(a, b) log_dump((a),(b)); - -# define LOG_FUNC_IN LOG_TRACE(FUNC_IN, "Entering %s()", __FUNCTION__) -# define LOG_FUNC_OUT LOG_TRACE(FUNC_OUT, "Leaving %s()", __FUNCTION__) -# define LOG_FUNC_RETURN(rETURNcODE) \ -do { \ - LOG_TRACE(FUNC_OUT, "Leaving %s(rc = %ld)", __FUNCTION__, \ - (long) (rETURNcODE)); \ - return (rETURNcODE); \ -} while(0) - -void nas_log_init(char filter); -void log_data(const char* filename, int line); -void log_trace(log_severity_t severity, const char* data, ...); -void log_dump(const char* data, int len); +# define LOG_TRACE(s, x, args...) +# define LOG_DUMP(dATA, lEN) LOG_DUMPMSG(NAS, LOG_DUMP_CHAR,dATA, lEN, " Dump %d:\n", lEN) + +# define LOG_FUNC_IN +# define LOG_FUNC_OUT +# define LOG_FUNC_RETURN(rETURNcODE) return rETURNcODE \ + #endif #endif /* __NAS_LOG_H__*/ diff --git a/openair3/NAS/COMMON/UTIL/nas_timer.c b/openair3/NAS/COMMON/UTIL/nas_timer.c index 0b92ac4d9d55c6b376558f99efbc028ae3effaa5..d92c48f483c25366334ac4a654aa23890056c7e8 100644 --- a/openair3/NAS/COMMON/UTIL/nas_timer.c +++ b/openair3/NAS/COMMON/UTIL/nas_timer.c @@ -46,7 +46,6 @@ Description Timer utilities #if defined(ENABLE_ITTI) # include "intertask_interface.h" -# include "timer.h" #else # include <signal.h> # include <time.h> // clock_gettime diff --git a/openair3/NAS/UE/EMM/SAP/emm_fsm.c b/openair3/NAS/UE/EMM/SAP/emm_fsm.c index d614b9ec7e42a5008c275251c1b6d229ab2b021c..5a715727ad17f3e091b7ca04a01eee113d2ccc59 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_fsm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_fsm.c @@ -208,8 +208,7 @@ emm_fsm_state_t emm_fsm_initialize() { LOG_FUNC_IN; - LOG_FUNC_OUT; - return EMM_NULL; + LOG_FUNC_RETURN(EMM_NULL); } /**************************************************************************** diff --git a/openair3/S1AP/s1ap_common.c b/openair3/S1AP/s1ap_common.c index 7c4f970af2f18d61e626c4a7d8f70d607a8d663c..d31c6e58390917b82c12b836fddd40c0ecf286a6 100644 --- a/openair3/S1AP/s1ap_common.c +++ b/openair3/S1AP/s1ap_common.c @@ -32,26 +32,9 @@ #include "s1ap_common.h" #include "S1AP_S1AP-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, " "); +int asn1_xer_print = 0; - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif void s1ap_handle_criticality(S1AP_Criticality_t criticality) { diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 8a2faa311f6e1e015d8c56654363f7e948a32811..94b3e43bc65b8789e330f25179381e0d2de4ba47 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -31,13 +31,16 @@ #ifndef S1AP_COMMON_H_ #define S1AP_COMMON_H_ -/* Defined in asn_internal.h */ -// extern int asn_debug_indent; -extern int asn_debug; -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...); +#include "common/utils/LOG/log.h" +/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system + Would be cleaner to modify asn_internal.h but it seems to come + from non oai source, with BSD license, so prefer to do that here.. +*/ +#ifdef ASN_DEBUG +# undef ASN_DEBUG #endif +#define ASN_DEBUG( x... ) LOG_I(ASN, x) #include "S1AP_ProtocolIE-Field.h" #include "S1AP_S1AP-PDU.h" diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 2a6db4a5ce4361b08b4a9ffbd573ed6a6d13722e..3edc5be0d5f42e66758dab67e42789d8edcc9d49 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -97,7 +97,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, net_ip_address_t *mme_ip_address, net_ip_address_t *local_ip_addr, uint16_t in_streams, - uint16_t out_streams) + uint16_t out_streams, + uint8_t broadcast_plmn_num, + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) { MessageDef *message_p = NULL; sctp_new_association_req_t *sctp_new_association_req_p = NULL; @@ -126,8 +128,8 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, sizeof(*local_ip_addr)); S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance); - - mme = s1ap_eNB_get_MME_from_instance(instance_p); + + mme = NULL; if ( mme == NULL ) { @@ -139,6 +141,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; + for (int i = 0; i < broadcast_plmn_num; ++i) + s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; s1ap_mme_data_p->s1ap_eNB_instance = instance_p; STAILQ_INIT(&s1ap_mme_data_p->served_gummei); @@ -190,10 +195,14 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * /* Checks if it is a retry on the same eNB */ DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0); DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0); + DevCheck(new_instance->num_plmn == s1ap_register_eNB->num_plmn, new_instance->num_plmn, s1ap_register_eNB->num_plmn, 0); DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0); - DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0); - DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0); - DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0); + for (int i = 0; i < new_instance->num_plmn; i++) + { + DevCheck(new_instance->mcc[i] == s1ap_register_eNB->mcc[i], new_instance->mcc[i], s1ap_register_eNB->mcc[i], 0); + DevCheck(new_instance->mnc[i] == s1ap_register_eNB->mnc[i], new_instance->mnc[i], s1ap_register_eNB->mnc[i], 0); + DevCheck(new_instance->mnc_digit_length[i] == s1ap_register_eNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], s1ap_register_eNB->mnc_digit_length[i], 0); + } DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0); } else { new_instance = calloc(1, sizeof(s1ap_eNB_instance_t)); @@ -208,9 +217,13 @@ 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; - new_instance->mcc = s1ap_register_eNB->mcc; - new_instance->mnc = s1ap_register_eNB->mnc; - new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length; + for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) + { + new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; + new_instance->mnc[i] = s1ap_register_eNB->mnc[i]; + new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i]; + } + new_instance->num_plmn = s1ap_register_eNB->num_plmn; new_instance->default_drx = s1ap_register_eNB->default_drx; /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ @@ -231,7 +244,9 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * &s1ap_register_eNB->mme_ip_address[index], &s1ap_register_eNB->enb_ip_address, s1ap_register_eNB->sctp_in_streams, - s1ap_register_eNB->sctp_out_streams); + s1ap_register_eNB->sctp_out_streams, + s1ap_register_eNB->broadcast_plmn_num[index], + s1ap_register_eNB->broadcast_plmn_index[index]); } } @@ -286,19 +301,20 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -void *s1ap_eNB_task(void *arg) +void s1ap_eNB_init(void) { - MessageDef *received_msg = NULL; - int result; - S1AP_DEBUG("Starting S1AP layer\n"); s1ap_eNB_prepare_internal_data(); itti_mark_task_ready(TASK_S1AP); MSC_START_USE(); +} - while (1) { +void *s1ap_eNB_process_itti_msg(void* notUsed) +{ + MessageDef *received_msg = NULL; + int result; itti_receive_msg(TASK_S1AP, &received_msg); switch (ITTI_MSG_ID(received_msg)) { @@ -413,6 +429,16 @@ void *s1ap_eNB_task(void *arg) AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); received_msg = NULL; + return NULL; +} + + +void *s1ap_eNB_task(void *arg) +{ + s1ap_eNB_init(); + + while (1) { + (void) s1ap_eNB_process_itti_msg(NULL); } return NULL; @@ -448,7 +474,9 @@ static int s1ap_eNB_generate_s1_setup_request( ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID; ie->criticality = S1AP_Criticality_reject; ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID; - MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]], &ie->value.choice.Global_ENB_ID.pLMNidentity); ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID; MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, @@ -479,9 +507,14 @@ static int s1ap_eNB_generate_s1_setup_request( ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t)); INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC); { - plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t)); - MCC_MNC_TO_TBCD(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); - ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn); + for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) { + plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t)); + MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]], + plmn); + ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn); + } } ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta); } diff --git a/openair3/S1AP/s1ap_eNB.h b/openair3/S1AP/s1ap_eNB.h index e122703d82f2dbda6d5cf42b1bcbf08446a270a4..2abbc53ec992f288c14761eb31170e6134a046e0 100644 --- a/openair3/S1AP/s1ap_eNB.h +++ b/openair3/S1AP/s1ap_eNB.h @@ -39,6 +39,8 @@ extern s1ap_eNB_config_t s1ap_config; #define EPC_MODE_ENABLED s1ap_config.mme_enabled +void *s1ap_eNB_process_itti_msg(void*); +void s1ap_eNB_init(void); void *s1ap_eNB_task(void *arg); uint32_t s1ap_generate_eNB_id(void); diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index 11e64703ec1625538daf17f375265e7380c63e85..5bffa0df0cb4c123bef19d44b978cfca7738c8fe 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -154,6 +154,11 @@ typedef struct s1ap_eNB_mme_data_s { /* SCTP association id */ int32_t assoc_id; + /* This is served PLMN IDs communicated to the MME via an index over the + * MCC/MNC array in s1ap_eNB_instance */ + uint8_t broadcast_plmn_num; + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]; + /* Only meaningfull in virtual mode */ struct s1ap_eNB_instance_s *s1ap_eNB_instance; } s1ap_eNB_mme_data_t; @@ -198,9 +203,10 @@ typedef struct s1ap_eNB_instance_s { /* Mobile Country Code * Mobile Network Code */ - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; /* Default Paging DRX of the eNB as defined in TS 36.304 */ paging_drx_t default_drx; diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 9b150fe75163f72223fcf627d7f7b0a073f3fb5e..5c6b208b87336111216ec516b78448b47971aa94 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -1043,7 +1043,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, /* Paging procedure -> stream != 0 */ if (stream == 0) { - S1AP_ERROR("[SCTP %d] Received Paging procedure on stream (%d)\n", + LOG_W(S1AP,"[SCTP %d] Received Paging procedure on stream (%d)\n", assoc_id, stream); return -1; } diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index f2f84de32d5140b7eaee9e5388017790d364d171..80266a4d9ca5546766d0bcbfc81e702f8f6899f9 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -81,6 +81,16 @@ int s1ap_eNB_handle_nas_first_req( instance_p, s1ap_nas_first_req_p->establishment_cause, s1ap_nas_first_req_p->ue_identity.gummei); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->ue_identity.gummei.mcc, + s1ap_nas_first_req_p->ue_identity.gummei.mnc, + s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, + s1ap_nas_first_req_p->ue_identity.gummei.mme_code); + } } if (mme_desc_p == NULL) { @@ -89,18 +99,53 @@ int s1ap_eNB_handle_nas_first_req( mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code( instance_p, s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity, s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, + s1ap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); + } + } + } + + if (mme_desc_p == NULL) { + /* Select MME based on the selected PLMN identity, received through RRC + * Connection Setup Complete */ + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); } } if (mme_desc_p == NULL) { /* - * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the - * highest capacity. + * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN + * identity, selects the MME with the highest capacity. */ mme_desc_p = s1ap_eNB_nnsf_select_mme( instance_p, s1ap_nas_first_req_p->establishment_cause); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id); + } } if (mme_desc_p == NULL) { @@ -124,6 +169,7 @@ int s1ap_eNB_handle_nas_first_req( ue_desc_p->mme_ref = mme_desc_p; ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id; ue_desc_p->eNB_instance = instance_p; + ue_desc_p->selected_plmn_identity = s1ap_nas_first_req_p->selected_plmn_identity; do { struct s1ap_eNB_ue_context_s *collision_p; @@ -172,9 +218,9 @@ int s1ap_eNB_handle_nas_first_req( ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TAI; /* Assuming TAI is the TAI from the cell */ INT16_TO_OCTET_STRING(instance_p->tac, &ie->value.choice.TAI.tAC); - MCC_MNC_TO_PLMNID(instance_p->mcc, - instance_p->mnc, - instance_p->mnc_digit_length, + MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.TAI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); @@ -191,9 +237,9 @@ int s1ap_eNB_handle_nas_first_req( MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, 0, // Cell ID &ie->value.choice.EUTRAN_CGI.cell_ID); - MCC_MNC_TO_TBCD(instance_p->mcc, - instance_p->mnc, - instance_p->mnc_digit_length, + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); @@ -473,17 +519,11 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, MSC_LOG_RX_DISCARDED_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME, - (const char *)NULL, NULL, + 0, MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), enb_ue_s1ap_id, mme_ue_s1ap_id); - /* TODO: fix this log - the original version is suspicious (twice downlink_NAS_transport_p->eNB_UE_S1AP_ID?) */ - /*S1AP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context eNB_UE_S1AP_ID: 0x%"PRIx32" %u\n", - assoc_id, - downlink_NAS_transport_p->eNB_UE_S1AP_ID, - downlink_NAS_transport_p->eNB_UE_S1AP_ID);*/ S1AP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context eNB_UE_S1AP_ID: 0x%lx\n", assoc_id, enb_ue_s1ap_id); @@ -518,11 +558,10 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, MSC_LOG_RX_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME, - (const char *)NULL, NULL, + 0, MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - enb_ue_s1ap_id, + assoc_id, mme_ue_s1ap_id); S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, @@ -615,9 +654,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->criticality = S1AP_Criticality_ignore; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc, - s1ap_eNB_instance_p->mnc, - s1ap_eNB_instance_p->mnc_digit_length, + s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], &ie->value.choice.EUTRAN_CGI.pLMNidentity); //#warning "TODO get cell id from RRC" MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, @@ -631,9 +670,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->criticality = S1AP_Criticality_ignore; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TAI; MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc, - s1ap_eNB_instance_p->mnc, - s1ap_eNB_instance_p->mnc_digit_length, + s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], &ie->value.choice.TAI.pLMNidentity); TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 8b7d65cb011194b3846dea521bf0e6bcd0c4bd89..63dc92b5e260e33c82a3dd076788b4761b1d763c 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -90,9 +90,9 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, } struct s1ap_eNB_mme_data_s * -s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause, - uint8_t mme_code) +s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; @@ -100,7 +100,7 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { struct served_gummei_s *gummei_p = NULL; - + struct plmn_identity_s *served_plmn_p = NULL; if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { /* The association between MME and eNB is not ready for the moment, * go to the next known MME. @@ -135,30 +135,106 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, } } + /* Looking for served GUMMEI PLMN Identity selected matching the one provided by the UE */ + STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { + STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { + if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && + (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + break; + } + } + /* if found, we can stop the outer loop, too */ + if (served_plmn_p) break; + } + /* if we didn't find such a served PLMN, go on with the next MME */ + if (!served_plmn_p) continue; + if (current_capacity < mme_data_p->relative_mme_capacity) { /* We find a better MME, keep a reference to it */ current_capacity = mme_data_p->relative_mme_capacity; mme_highest_capacity_p = mme_data_p; } + } + + return mme_highest_capacity_p; +} + +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity, + uint8_t mme_code) +{ + struct s1ap_eNB_mme_data_s *mme_data_p = NULL; + + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + struct served_gummei_s *gummei_p = NULL; + + if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { + /* The association between MME and eNB is not ready for the moment, + * go to the next known MME. + */ + if (mme_data_p->state == S1AP_ENB_OVERLOAD) { + /* MME is overloaded. We have to check the RRC establishment + * cause and take decision to the select this MME depending on + * the overload state. + */ + if ((cause == RRC_CAUSE_MO_DATA) + && (mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((mme_data_p->overload_state == S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA) + || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the MME + * even if it is in overload state. + */ + } else { + /* The MME is not overloaded, association is simply not ready. */ + continue; + } + } /* Looking for MME code matching the one provided by NAS */ STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { struct mme_code_s *mme_code_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { + if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && + (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + break; + } + } STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) { if (mme_code_p->mme_code == mme_code) { - return mme_data_p; + break; } } + + /* The MME matches the parameters provided by the NAS layer -> + * the MME is knwown and the association is ready. + * Return the reference to the MME to use it for this UE. + */ + if (mme_code_p && served_plmn_p) { + return mme_data_p; + } } } - /* At this point no MME matches the provided GUMMEI. Select the one with the - * highest relative capacity. - * In case the list of known MME is empty, simply return NULL, that way the RRC - * layer should know about it and reject RRC connectivity. - */ - return mme_highest_capacity_p; + /* At this point no MME matches the selected PLMN and MME code. In this case, + * return NULL. That way the RRC layer should know about it and reject RRC + * connectivity. */ + return NULL; } struct s1ap_eNB_mme_data_s * @@ -167,8 +243,6 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, s1ap_gummei_t gummei) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; - struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - uint8_t current_capacity = 0; RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { struct served_gummei_s *gummei_p = NULL; @@ -207,12 +281,6 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, } } - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; - } - /* Looking for MME gummei matching the one provided by NAS */ STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { struct served_group_id_s *group_id_p = NULL; @@ -248,10 +316,8 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, } } - /* At this point no MME matches the provided GUMMEI. Select the one with the - * highest relative capacity. - * In case the list of known MME is empty, simply return NULL, that way the RRC - * layer should know about it and reject RRC connectivity. - */ - return mme_highest_capacity_p; + /* At this point no MME matches the provided GUMMEI. In this case, return + * NULL. That way the RRC layer should know about it and reject RRC + * connectivity. */ + return NULL; } diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index 78405f34d1b17e0995cfa70e91c57b98cf087786..706f3ada6ff8380bf7e94d6a541817eb83064e07 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -26,9 +26,15 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause); +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity); + struct s1ap_eNB_mme_data_s* s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, + int selected_plmn_identity, uint8_t mme_code); struct s1ap_eNB_mme_data_s* diff --git a/openair3/S1AP/s1ap_eNB_ue_context.h b/openair3/S1AP/s1ap_eNB_ue_context.h index d78c6f7f1a97d42e2654de02b5fb921439c98f21..9adbc5fb2c8af9c9e649a4de05b56f329997cc2b 100644 --- a/openair3/S1AP/s1ap_eNB_ue_context.h +++ b/openair3/S1AP/s1ap_eNB_ue_context.h @@ -67,6 +67,11 @@ typedef struct s1ap_eNB_ue_context_s { /* Reference to MME data this UE is attached to */ struct s1ap_eNB_mme_data_s *mme_ref; + /* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink + * to route NAS messages correctly. 0-based, not 1-based as in TS 36.331 + * 6.2.2 RRC Connection Setup Complete! */ + int selected_plmn_identity; + /* Reference to eNB data this UE is attached to */ s1ap_eNB_instance_t *eNB_instance; } s1ap_eNB_ue_context_t; diff --git a/openair3/SCTP/sctp_common.c b/openair3/SCTP/sctp_common.c index c467290b3698b9687fb858b9df7e745262c74034..55a294392474b73c5e823bb58fec2f61bfc4e558 100644 --- a/openair3/SCTP/sctp_common.c +++ b/openair3/SCTP/sctp_common.c @@ -86,6 +86,12 @@ int sctp_get_sockinfo(int sock, uint16_t *instream, uint16_t *outstream, memset(&status, 0, sizeof(struct sctp_status)); i = sizeof(struct sctp_status); + /* if sock refers to a multi SCTP endpoint, *assoc_id gives us + * the association ID that we want + */ + if (assoc_id != NULL) + status.sstat_assoc_id = *assoc_id; + if (getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &i) < 0) { SCTP_ERROR("Getsockopt SCTP_STATUS failed: %s\n", strerror(errno)); return -1; diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.c b/openair3/SCTP/sctp_eNB_itti_messaging.c index 3517c0597bb54bcba72bdcbdb680ebf21ef03d0d..d2064c74c08671b215bbca98525ca9b58be91d47 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.c +++ b/openair3/SCTP/sctp_eNB_itti_messaging.c @@ -24,6 +24,20 @@ #include "sctp_common.h" #include "sctp_eNB_itti_messaging.h" +int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd) +{ + MessageDef *message_p; + sctp_init_msg_multi_cnf_t *sctp_init_msg_multi_cnf_p; + + message_p = itti_alloc_new_message(TASK_SCTP, SCTP_INIT_MSG_MULTI_CNF); + + sctp_init_msg_multi_cnf_p = &message_p->ittiMsg.sctp_init_msg_multi_cnf; + + sctp_init_msg_multi_cnf_p->multi_sd = multi_sd; + + return itti_send_msg_to_task(task_id, instance, message_p); +} + int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream) { diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.h b/openair3/SCTP/sctp_eNB_itti_messaging.h index 665c5f0e663ed111f1ea9abcfedc89353e872f9a..49d2056a3cc254975c18fe469554d50d07bd8379 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.h +++ b/openair3/SCTP/sctp_eNB_itti_messaging.h @@ -22,6 +22,8 @@ #ifndef SCTP_ITTI_MESSAGING_H_ #define SCTP_ITTI_MESSAGING_H_ +int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd); + int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream); diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 168eb58b3728f4b95cb0bb41ef099f30740522fb..e7265d66d6485c25e74f5cf128e0a89e932001f8 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -61,6 +61,7 @@ enum sctp_connection_type_e { SCTP_TYPE_CLIENT, SCTP_TYPE_SERVER, + SCTP_TYPE_MULTI_SERVER, SCTP_TYPE_MAX }; @@ -91,7 +92,6 @@ typedef struct sctp_cnx_list_elm_s { static STAILQ_HEAD(sctp_cnx_list_head, sctp_cnx_list_elm_s) sctp_cnx_list; static uint16_t sctp_nb_cnx = 0; - //------------------------------------------------------------------------------ struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd) { @@ -112,6 +112,242 @@ struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd) return NULL; } +//------------------------------------------------------------------------------ +static inline +void +sctp_eNB_accept_associations_multi( + struct sctp_cnx_list_elm_s *sctp_cnx) +{ + int ns; + int n; + int flags = 0; + socklen_t from_len; + struct sctp_sndrcvinfo sinfo; + + struct sockaddr_in addr; + uint8_t buffer[SCTP_RECV_BUFFER_SIZE]; + + DevAssert(sctp_cnx != NULL); + + memset((void *)&addr, 0, sizeof(struct sockaddr_in)); + from_len = (socklen_t)sizeof(struct sockaddr_in); + memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + n = sctp_recvmsg(sctp_cnx->sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE, + (struct sockaddr *)&addr, &from_len, + &sinfo, &flags); + + if (n < 0) { + if (errno == ENOTCONN) { + SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); + close(sctp_cnx->sd); + } else { + SCTP_DEBUG("An error occured during read\n"); + SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); + } + return; + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *snp; + snp = (union sctp_notification *)buffer; + + SCTP_DEBUG("Received notification for sd %d, type %u\n", + sctp_cnx->sd, snp->sn_header.sn_type); + + /* Association has changed. */ + if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) { + struct sctp_assoc_change *sctp_assoc_changed; + sctp_assoc_changed = &snp->sn_assoc_change; + + SCTP_DEBUG("Client association changed: %d\n", sctp_assoc_changed->sac_state); + + /* New physical association requested by a peer */ + switch (sctp_assoc_changed->sac_state) { + case SCTP_COMM_UP: { + SCTP_DEBUG("Comm up notified for sd %d, assigned assoc_id %d\n", + sctp_cnx->sd, sctp_assoc_changed->sac_assoc_id); + struct sctp_cnx_list_elm_s *new_cnx; + + new_cnx = calloc(1, sizeof(*sctp_cnx)); + + DevAssert(new_cnx != NULL); + + new_cnx->connection_type = SCTP_TYPE_CLIENT; + + ns = sctp_peeloff(sctp_cnx->sd, sctp_assoc_changed->sac_assoc_id); + + new_cnx->sd = ns; + new_cnx->task_id = sctp_cnx->task_id; + new_cnx->cnx_id = 0; + new_cnx->ppid = sctp_cnx->ppid; + new_cnx->instance = sctp_cnx->instance; + new_cnx->local_port = sctp_cnx->local_port; + new_cnx->assoc_id = sctp_assoc_changed->sac_assoc_id; + + if (sctp_get_sockinfo(ns, &new_cnx->in_streams, &new_cnx->out_streams, + &new_cnx->assoc_id) != 0) { + SCTP_ERROR("sctp_get_sockinfo failed\n"); + close(ns); + free(new_cnx); + return; + } + + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, new_cnx, entries); + sctp_nb_cnx++; + + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, ns); + + sctp_itti_send_association_ind(new_cnx->task_id, new_cnx->instance, + new_cnx->assoc_id, new_cnx->local_port, + new_cnx->out_streams, new_cnx->in_streams); + } + break; + + default: + break; + } + } + } else { + SCTP_DEBUG("No notification from SCTP\n"); + } +} + +//------------------------------------------------------------------------------ +void +sctp_handle_new_association_req_multi( + const instance_t instance, + const task_id_t requestor, + const sctp_new_association_req_multi_t * const sctp_new_association_req_p) +{ + int ns; + int sd; + + int32_t assoc_id = 0; + + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT; + + /* Prepare a new SCTP association as requested by upper layer and try to connect + * to remote host. + */ + DevAssert(sctp_new_association_req_p != NULL); + + sd = sctp_new_association_req_p->multi_sd; + + /* Create new socket with IPv6 affinity */ +//#warning "SCTP may Force IPv4 only, here" + + /* Mark the socket as non-blocking */ + //if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) { + //SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n", + // strerror(errno)); + //close(sd); + //return; + //} + + /* SOCK_STREAM socket type requires an explicit connect to the remote host + * address and port. + * Only use IPv4 for the first connection attempt + */ + if ((sctp_new_association_req_p->remote_address.ipv6 != 0) || + (sctp_new_association_req_p->remote_address.ipv4 != 0)) { + uint8_t address_index = 0; + uint8_t used_address = sctp_new_association_req_p->remote_address.ipv6 + + sctp_new_association_req_p->remote_address.ipv4; + struct sockaddr_in addr[used_address]; + + memset(addr, 0, used_address * sizeof(struct sockaddr_in)); + + if (sctp_new_association_req_p->remote_address.ipv6 == 1) { + if (inet_pton(AF_INET6, sctp_new_association_req_p->remote_address.ipv6_address, + &addr[address_index].sin_addr.s_addr) != 1) { + SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), + sctp_new_association_req_p->remote_address.ipv6_address); + //close(sd); + //return; + exit(1); + } + + SCTP_DEBUG("Converted ipv6 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), + sctp_new_association_req_p->remote_address.ipv6_address); + + addr[address_index].sin_family = AF_INET6; + addr[address_index].sin_port = htons(sctp_new_association_req_p->port); + address_index++; + } + + if (sctp_new_association_req_p->remote_address.ipv4 == 1) { + if (inet_pton(AF_INET, sctp_new_association_req_p->remote_address.ipv4_address, + &addr[address_index].sin_addr.s_addr) != 1) { + SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), + sctp_new_association_req_p->remote_address.ipv4_address); + //close(sd); + //return; + exit(1); + } + + SCTP_DEBUG("Converted ipv4 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), + sctp_new_association_req_p->remote_address.ipv4_address); + + addr[address_index].sin_family = AF_INET; + addr[address_index].sin_port = htons(sctp_new_association_req_p->port); + address_index++; + } + + /* Connect to remote host and port */ + if (sctp_connectx(sd, (struct sockaddr *)addr, 1, &assoc_id) < 0) { + /* sctp_connectx on non-blocking socket return EINPROGRESS */ + if (errno != EINPROGRESS) { + SCTP_ERROR("Connect failed: %s\n", strerror(errno)); + sctp_itti_send_association_resp( + requestor, instance, -1, sctp_new_association_req_p->ulp_cnx_id, + SCTP_STATE_UNREACHABLE, 0, 0); + /* Add the socket to list of fd monitored by ITTI */ + //itti_unsubscribe_event_fd(TASK_SCTP, sd); + //close(sd); + return; + } else { + SCTP_DEBUG("connectx assoc_id %d in progress..., used %d addresses\n", + assoc_id, used_address); + } + } else { + SCTP_DEBUG("sctp_connectx SUCCESS, used %d addresses assoc_id %d\n", + used_address, + assoc_id); + } + } + + ns = sctp_peeloff(sd,assoc_id); + + sctp_cnx = calloc(1, sizeof(*sctp_cnx)); + + sctp_cnx->connection_type = connection_type; + + sctp_cnx->sd = ns; + sctp_cnx->task_id = requestor; + sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id; + sctp_cnx->ppid = sctp_new_association_req_p->ppid; + sctp_cnx->instance = instance; + sctp_cnx->assoc_id = assoc_id; + + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, ns); + + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); + sctp_nb_cnx++; + + SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n", + ns, sctp_nb_cnx, assoc_id); +} + //------------------------------------------------------------------------------ void sctp_handle_new_association_req( @@ -441,7 +677,8 @@ static int sctp_close_association( static int sctp_create_new_listener( const instance_t instance, const task_id_t requestor, - sctp_init_t *init_p) + sctp_init_t *init_p, + int server_type) { struct sctp_event_subscribe event; struct sockaddr *addr = NULL; @@ -501,9 +738,17 @@ static int sctp_create_new_listener( } } - if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { - SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); - return -1; + if (server_type) { + if ((sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { + SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); + return -1; + } + } + else { + if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { + SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); + return -1; + } } memset((void *)&event, 1, sizeof(struct sctp_event_subscribe)); @@ -516,7 +761,13 @@ static int sctp_create_new_listener( sctp_cnx = calloc(1, sizeof(*sctp_cnx)); - sctp_cnx->connection_type = SCTP_TYPE_SERVER; + if (server_type) { + sctp_cnx->connection_type = SCTP_TYPE_MULTI_SERVER; + } + else { + sctp_cnx->connection_type = SCTP_TYPE_SERVER; + } + sctp_cnx->sd = sd; sctp_cnx->local_port = init_p->port; sctp_cnx->in_streams = 32; @@ -729,6 +980,7 @@ sctp_eNB_read_from_socket( break; default: + SCTP_WARN("unhandled: SCTP_ASSOC_CHANGE to %d\n", sctp_assoc_changed->sac_state); break; } } @@ -777,21 +1029,19 @@ sctp_eNB_flush_sockets( if (sctp_cnx->connection_type == SCTP_TYPE_CLIENT) { sctp_eNB_read_from_socket(sctp_cnx); - } else { + } + else if (sctp_cnx->connection_type == SCTP_TYPE_MULTI_SERVER) { + sctp_eNB_accept_associations_multi(sctp_cnx); + } + else { sctp_eNB_accept_associations(sctp_cnx); } } } - //------------------------------------------------------------------------------ -void *sctp_eNB_task(void *arg) +void sctp_eNB_init(void) { - int nb_events; - struct epoll_event *events; - MessageDef *received_msg = NULL; - int result; - SCTP_DEBUG("Starting SCTP layer\n"); STAILQ_INIT(&sctp_cnx_list); @@ -799,7 +1049,16 @@ void *sctp_eNB_task(void *arg) itti_mark_task_ready(TASK_SCTP); MSC_START_USE(); - while (1) { +} + +//------------------------------------------------------------------------------ +void *sctp_eNB_process_itti_msg(void *notUsed) +{ + int nb_events; + struct epoll_event *events; + MessageDef *received_msg = NULL; + int result; + itti_receive_msg(TASK_SCTP, &received_msg); /* Check if there is a packet to handle */ @@ -812,10 +1071,45 @@ void *sctp_eNB_task(void *arg) if (sctp_create_new_listener( ITTI_MESSAGE_GET_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_init) < 0) { + &received_msg->ittiMsg.sctp_init,0) < 0) { + /* SCTP socket creation or bind failed... */ + SCTP_ERROR("Failed to create new SCTP listener\n"); + } + } + break; + + case SCTP_INIT_MSG_MULTI_REQ: { + int multi_sd; + + SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI_REQ\n"); + + multi_sd = sctp_create_new_listener( + ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_init_multi,1); + /* We received a new connection request */ + if (multi_sd < 0) { /* SCTP socket creation or bind failed... */ SCTP_ERROR("Failed to create new SCTP listener\n"); } + sctp_itti_send_init_msg_multi_cnf( + ITTI_MSG_ORIGIN_ID(received_msg), + ITTI_MESSAGE_GET_INSTANCE(received_msg), + multi_sd); + } + break; + + case SCTP_NEW_ASSOCIATION_REQ: { + sctp_handle_new_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_new_association_req); + } + break; + + case SCTP_NEW_ASSOCIATION_REQ_MULTI: { + sctp_handle_new_association_req_multi(ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_new_association_req_multi); } break; @@ -830,13 +1124,6 @@ void *sctp_eNB_task(void *arg) itti_exit_task(); break; - case SCTP_NEW_ASSOCIATION_REQ: { - sctp_handle_new_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_new_association_req); - } - break; - case SCTP_DATA_REQ: { sctp_send_data(ITTI_MESSAGE_GET_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), @@ -858,6 +1145,17 @@ void *sctp_eNB_task(void *arg) nb_events = itti_get_events(TASK_SCTP, &events); /* Now handle notifications for other sockets */ sctp_eNB_flush_sockets(events, nb_events); + + return NULL; +} + +//------------------------------------------------------------------------------ +void *sctp_eNB_task(void *arg) +{ + sctp_eNB_init(); + + while (1) { + (void) sctp_eNB_process_itti_msg(NULL); } return NULL; diff --git a/openair3/SCTP/sctp_eNB_task.h b/openair3/SCTP/sctp_eNB_task.h index 31cb6831025e5eea879ebee904f24cc5dbf14276..e23e80675e647d94460b103ed163455ad73d54c9 100644 --- a/openair3/SCTP/sctp_eNB_task.h +++ b/openair3/SCTP/sctp_eNB_task.h @@ -22,6 +22,8 @@ #ifndef SCTP_ENB_TASK_H_ #define SCTP_ENB_TASK_H_ +void sctp_eNB_init(void); +void *sctp_eNB_process_itti_msg(void *); void *sctp_eNB_task(void *arg); #endif /* SCTP_ENB_TASK_H_ */ diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf index 2571db70a059ac2ec190196b927a159c4a65d540..85cee4dda0685d20afa6b3e6604a45881974d7f1 100644 --- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf +++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf @@ -13,11 +13,8 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "95"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf index e71e7e03f5d368597401d40916d1724aef9114d6..df06231e4a54706a8725faf4fc760cb1bc04753d 100755 --- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf +++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf @@ -13,10 +13,8 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - mobile_network_code = "95"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 9f922d8516d49933a3ae2f3b653f70bc1fd3efbf..546878e57692061c502ac17d56f08fd7a5f336d1 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -46,8 +46,6 @@ #include <pthread.h> -#include "intertask_interface_init.h" -#include "timer.h" #include "assertions.h" #include "s1ap_common.h" #include "intertask_interface.h" diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 1589b83cae6b58bc651f4b0debaed2e59b5a3505..a3963951dce3d41a0fd865a1da1e1cc181fd4ac0 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -36,7 +36,6 @@ #include "play_scenario.h" #include "s1ap_ies_defs.h" #include "play_scenario_s1ap_eNB_defs.h" -#include "timer.h" //------------------------------------------------------------------------------ extern int g_max_speed; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 361b56100c0cee37a8a987dc649b797df5420b8f..d2bf05c0862f8eddd958621744d08f439b836baa 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -38,7 +38,6 @@ #include "intertask_interface.h" -#include "timer.h" #include "platform_types.h" #include "assertions.h" #include "conversions.h" diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c index e0afbeb83875721c061b961908560791c325def3..001834fcab229ac60d4209bfeb215494e524540f 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -43,7 +43,6 @@ #include "intertask_interface.h" -#include "timer.h" #include "platform_types.h" #include "assertions.h" #include "conversions.h" diff --git a/openair3/TEST/oaisim_mme_itti_test.c b/openair3/TEST/oaisim_mme_itti_test.c index bf8ad4471417abe7ceb95411ec3e345847edffea..57cfd412ef12c7b607c011c8125f99675be5c3b6 100644 --- a/openair3/TEST/oaisim_mme_itti_test.c +++ b/openair3/TEST/oaisim_mme_itti_test.c @@ -32,13 +32,12 @@ #include "mme_config.h" #include "gtpv1u_sgw_defs.h" -#include "intertask_interface_init.h" +#include "intertask_interface.h" #include "sctp_primitives_server.h" #include "udp_primitives_server.h" #include "s1ap_mme.h" #include "log.h" -#include "timer.h" #include "sgw_lite_defs.h" #include "ipv4_defs.h" diff --git a/openair3/TEST/oaisim_mme_test_s1c.c b/openair3/TEST/oaisim_mme_test_s1c.c index f006434b9013ca093e592d511f498c5af13b49ee..52623463c6bc4f83091311e3bb5969b5338a8cb1 100644 --- a/openair3/TEST/oaisim_mme_test_s1c.c +++ b/openair3/TEST/oaisim_mme_test_s1c.c @@ -40,9 +40,7 @@ #include "UTIL/LOG/log_extern.h" #include "assertions.h" -#include "intertask_interface_init.h" #include "intertask_interface.h" -#include "timer.h" #include "sctp_eNB_task.h" #include "s1ap_eNB.h" #include "enb_config.h" diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index f61f614a143464d04b255d2980d7cefc701ebfb7..fdcdeb037af62ebddb912651d620f7954e2149b5 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -276,7 +276,7 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) * if the queue is full. */ /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ - if (itti_try_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { LOG_E(UDP_, "Failed to send message %d to task %d\n", UDP_DATA_IND, udp_sock_pP->task_id); diff --git a/openair3/UDP/udp_eNB_task.h b/openair3/UDP/udp_eNB_task.h index 658516212574efbfb5115444d350c47e0c42828d..8b783f7455c08f6aec5a0d80788b51746a9feb51 100644 --- a/openair3/UDP/udp_eNB_task.h +++ b/openair3/UDP/udp_eNB_task.h @@ -31,7 +31,6 @@ #ifndef UDP_ENB_TASK_H_ #define UDP_ENB_TASK_H_ #include "enb_config.h" -#include "intertask_interface_types.h" /** \brief UDP recv callback prototype. Will be called every time a payload is diff --git a/pre-commit b/pre-commit index 82587fce34c8bd8df74b1a87e0ce6bb19ce18679..ab54a821a5436e156a444ac7fc53f9c452eb786d 100644 --- a/pre-commit +++ b/pre-commit @@ -4,7 +4,7 @@ # cp pre-commit .git/hooks # chmod +x .git/hooks/pre-commit -OPTIONS="--convert-tabs --indent=spaces=2 --indent-switches --indent-col1-comments --break-blocks --delete-empty-lines --align-pointer=name --keep-one-line-blocks --keep-one-line-statements --lineend=linux" +OPTIONS="--options=ci-scripts/astyle-options.txt" RETURN=0 ASTYLE=$(which astyle) @@ -28,4 +28,4 @@ if [ $RETURN -eq 1 ]; then echo $OPTIONS >&2 fi -exit $RETURN \ No newline at end of file +exit $RETURN diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 7ff3b820dca5e121f585bd3b9c5a5827ddea1e95..d25826e82e7c060ae75c90c8e51bb9f86941e1cf 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -100,7 +100,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param libname=OAI_TP_LIBNAME; shlib_fdesc[0].fname="transport_init"; } - ret=load_module_shlib(libname,shlib_fdesc,1); + ret=load_module_shlib(libname,shlib_fdesc,1,NULL); if (ret < 0) { fprintf(stderr,"Library %s couldn't be loaded\n",libname); } else { diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 433e29e97db7b15322b51d8f3282daa91b922c09..0ef3cd233f57433e6ca3dad9ad399d630206d7d7 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -199,6 +199,8 @@ typedef struct { double tx_bw; //! clock source clock_source_t clock_source; + //! Manual SDR IP address + char *sdr_addrs; //! Auto calibration flag int autocal[4]; //! rf devices work with x bits iqs when oai have its own iq format diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index e2ecaed04453194c40afe3604d63a3b88385ac9f..c591cc6c0f31f2f324e2b3f09ad899313b7ab46f 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -65,211 +65,191 @@ /*! \brief USRP Configuration */ typedef struct { - // -------------------------------- - // variables for USRP configuration - // -------------------------------- - //! USRP device pointer - uhd::usrp::multi_usrp::sptr usrp; - - //create a send streamer and a receive streamer - //! USRP TX Stream - uhd::tx_streamer::sptr tx_stream; - //! USRP RX Stream - uhd::rx_streamer::sptr rx_stream; - - //! USRP TX Metadata - uhd::tx_metadata_t tx_md; - //! USRP RX Metadata - uhd::rx_metadata_t rx_md; - - //! Sampling rate - double sample_rate; - - //! TX forward samples. We use usrp_time_offset to get this value - int tx_forward_nsamps; //166 for 20Mhz - - // -------------------------------- - // Debug and output control - // -------------------------------- - int num_underflows; - int num_overflows; - int num_seq_errors; - int64_t tx_count; - int64_t rx_count; - int wait_for_first_pps; - int use_gps; - //! timestamp of RX packet - openair0_timestamp rx_timestamp; + // -------------------------------- + // variables for USRP configuration + // -------------------------------- + //! USRP device pointer + uhd::usrp::multi_usrp::sptr usrp; + + //create a send streamer and a receive streamer + //! USRP TX Stream + uhd::tx_streamer::sptr tx_stream; + //! USRP RX Stream + uhd::rx_streamer::sptr rx_stream; + + //! USRP TX Metadata + uhd::tx_metadata_t tx_md; + //! USRP RX Metadata + uhd::rx_metadata_t rx_md; + + //! Sampling rate + double sample_rate; + + //! TX forward samples. We use usrp_time_offset to get this value + int tx_forward_nsamps; //166 for 20Mhz + + // -------------------------------- + // Debug and output control + // -------------------------------- + int num_underflows; + int num_overflows; + int num_seq_errors; + int64_t tx_count; + int64_t rx_count; + int wait_for_first_pps; + int use_gps; + //! timestamp of RX packet + openair0_timestamp rx_timestamp; } usrp_state_t; //void print_notes(void) //{ - // Helpful notes - // std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n"); - // std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n"); - // std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n"); - // std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n"); - // std::cout << boost::format("****************************************************************************************************************\n"); +// Helpful notes +// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n"); +// std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n"); +// std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n"); +// std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n"); +// std::cout << boost::format("****************************************************************************************************************\n"); //} -static int sync_to_gps(openair0_device *device) -{ - uhd::set_thread_priority_safe(); - - //std::string args; - - //Set up program options - //po::options_description desc("Allowed options"); - //desc.add_options() - //("help", "help message") - //("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments") - //; - //po::variables_map vm; - //po::store(po::parse_command_line(argc, argv, desc), vm); - //po::notify(vm); - - //Print the help message - //if (vm.count("help")) - //{ - // std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl; - // return EXIT_FAILURE; - //} - - //Create a USRP device - //std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; - //uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); - //std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); - - usrp_state_t *s = (usrp_state_t*)device->priv; - - try - { - size_t num_mboards = s->usrp->get_num_mboards(); - size_t num_gps_locked = 0; - for (size_t mboard = 0; mboard < num_mboards; mboard++) - { - std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; - - //Set references to GPSDO - s->usrp->set_clock_source("gpsdo", mboard); - s->usrp->set_time_source("gpsdo", mboard); - - //std::cout << std::endl; - //print_notes(); - //std::cout << std::endl; - - //Check for 10 MHz lock - std::vector<std::string> sensor_names = s->usrp->get_mboard_sensor_names(mboard); - if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) - { - std::cout << "Waiting for reference lock..." << std::flush; - bool ref_locked = false; - for (int i = 0; i < 30 and not ref_locked; i++) - { - ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); - if (not ref_locked) - { - std::cout << "." << std::flush; - boost::this_thread::sleep(boost::posix_time::seconds(1)); - } - } - if(ref_locked) - { - std::cout << "LOCKED" << std::endl; - } else { - std::cout << "FAILED" << std::endl; - std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; - exit(EXIT_FAILURE); - } - } - else - { - std::cout << boost::format("ref_locked sensor not present on this board.\n"); - } - - //Wait for GPS lock - bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool(); - if(gps_locked) - { - num_gps_locked++; - std::cout << boost::format("GPS Locked\n"); - } - else - { - std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl; - } +static int sync_to_gps(openair0_device *device) { + uhd::set_thread_priority_safe(); + //std::string args; + //Set up program options + //po::options_description desc("Allowed options"); + //desc.add_options() + //("help", "help message") + //("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments") + //; + //po::variables_map vm; + //po::store(po::parse_command_line(argc, argv, desc), vm); + //po::notify(vm); + //Print the help message + //if (vm.count("help")) + //{ + // std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl; + // return EXIT_FAILURE; + //} + //Create a USRP device + //std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; + //uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); + //std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); + usrp_state_t *s = (usrp_state_t *)device->priv; + + try { + size_t num_mboards = s->usrp->get_num_mboards(); + size_t num_gps_locked = 0; + + for (size_t mboard = 0; mboard < num_mboards; mboard++) { + std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; + //Set references to GPSDO + s->usrp->set_clock_source("gpsdo", mboard); + s->usrp->set_time_source("gpsdo", mboard); + //std::cout << std::endl; + //print_notes(); + //std::cout << std::endl; + //Check for 10 MHz lock + std::vector<std::string> sensor_names = s->usrp->get_mboard_sensor_names(mboard); + + if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { + std::cout << "Waiting for reference lock..." << std::flush; + bool ref_locked = false; + + for (int i = 0; i < 30 and not ref_locked; i++) { + ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); + + if (not ref_locked) { + std::cout << "." << std::flush; + boost::this_thread::sleep(boost::posix_time::seconds(1)); + } + } - //Set to GPS time - uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); - //s->usrp->set_time_next_pps(gps_time+1.0, mboard); - s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); - - //Wait for it to apply - //The wait is 2 seconds because N-Series has a known issue where - //the time at the last PPS does not properly update at the PPS edge - //when the time is actually set. - boost::this_thread::sleep(boost::posix_time::seconds(2)); - - //Check times - gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); - uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard); - std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl; - std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; - //if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) - // std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; - //else - // std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; + if(ref_locked) { + std::cout << "LOCKED" << std::endl; + } else { + std::cout << "FAILED" << std::endl; + std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; + exit(EXIT_FAILURE); } + } else { + std::cout << boost::format("ref_locked sensor not present on this board.\n"); + } - if (num_gps_locked == num_mboards and num_mboards > 1) - { - //Check to see if all USRP times are aligned - //First, wait for PPS. - uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); - while (time_last_pps == s->usrp->get_time_last_pps()) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(1)); - } + //Wait for GPS lock + bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool(); - //Sleep a little to make sure all devices have seen a PPS edge - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); - - //Compare times across all mboards - bool all_matched = true; - uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0); - for (size_t mboard = 1; mboard < num_mboards; mboard++) - { - uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard); - if (mboard_time != mboard0_time) - { - all_matched = false; - std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f") - % mboard0_time.get_real_secs() - % mboard - % mboard_time.get_real_secs()) << std::endl; - } - } - if (all_matched) - { - std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl; - } else { - std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl; - } - } + if(gps_locked) { + num_gps_locked++; + std::cout << boost::format("GPS Locked\n"); + } else { + std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl; + } + + //Set to GPS time + uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); + //s->usrp->set_time_next_pps(gps_time+1.0, mboard); + s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + //Wait for it to apply + //The wait is 2 seconds because N-Series has a known issue where + //the time at the last PPS does not properly update at the PPS edge + //when the time is actually set. + boost::this_thread::sleep(boost::posix_time::seconds(2)); + //Check times + gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); + uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard); + std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl; + std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; + //if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) + // std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; + //else + // std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; } - catch (std::exception& e) - { - std::cout << boost::format("\nError: %s") % e.what(); - std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n"); - std::cout << boost::format("Visit one of these pages if the problem persists:\n"); - std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"); - std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); - std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); - exit(EXIT_FAILURE); + + if (num_gps_locked == num_mboards and num_mboards > 1) { + //Check to see if all USRP times are aligned + //First, wait for PPS. + uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); + + while (time_last_pps == s->usrp->get_time_last_pps()) { + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + } + + //Sleep a little to make sure all devices have seen a PPS edge + boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + //Compare times across all mboards + bool all_matched = true; + uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0); + + for (size_t mboard = 1; mboard < num_mboards; mboard++) { + uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard); + + if (mboard_time != mboard0_time) { + all_matched = false; + std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f") + % mboard0_time.get_real_secs() + % mboard + % mboard_time.get_real_secs()) << std::endl; + } + } + + if (all_matched) { + std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl; + } else { + std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl; + } } + } catch (std::exception &e) { + std::cout << boost::format("\nError: %s") % e.what(); + std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n"); + std::cout << boost::format("Visit one of these pages if the problem persists:\n"); + std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"); + std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); + std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); + exit(EXIT_FAILURE); + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } #if defined(USRP_REC_PLAY) @@ -315,24 +295,18 @@ char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY; @param device pointer to the device structure specific to the RF hardware target */ static int trx_usrp_start(openair0_device *device) { - #if defined(USRP_REC_PLAY) - if (u_sf_mode != 2) { // not replay mode -#endif - - usrp_state_t *s = (usrp_state_t*)device->priv; - - // setup GPIO for TDD, GPIO(4) = ATR_RX - //set data direction register (DDR) to output + if (u_sf_mode != 2) { // not replay mode +#endif + usrp_state_t *s = (usrp_state_t *)device->priv; + // setup GPIO for TDD, GPIO(4) = ATR_RX + //set data direction register (DDR) to output s->usrp->set_gpio_attr("FP0", "DDR", 0x1f, 0x1f); - - //set control register to ATR + //set control register to ATR s->usrp->set_gpio_attr("FP0", "CTRL", 0x1f,0x1f); - - //set ATR register + //set ATR register s->usrp->set_gpio_attr("FP0", "ATR_RX", 1<<4, 0x1f); - // init recv and send streaming uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); LOG_I(PHY,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); @@ -340,28 +314,26 @@ static int trx_usrp_start(openair0_device *device) { if (s->use_gps == 1) { s->wait_for_first_pps = 1; - cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); - } - else { - s->wait_for_first_pps = 0; + cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); + } else { + s->wait_for_first_pps = 0; cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); } cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); s->tx_md.has_time_spec = true; s->tx_md.start_of_burst = true; s->tx_md.end_of_burst = false; - s->rx_count = 0; s->tx_count = 0; s->rx_timestamp = 0; #if defined(USRP_REC_PLAY) - } -#endif - return 0; + } + +#endif + return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use @@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) { static void trx_usrp_end(openair0_device *device) { #if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times... static int done = 0; + if (done == 1) return; + done = 1; - if (u_sf_mode != 2) { // not subframes replay -#endif - usrp_state_t *s = (usrp_state_t*)device->priv; + if (u_sf_mode != 2) { // not subframes replay +#endif + usrp_state_t *s = (usrp_state_t *)device->priv; 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; @@ -382,55 +356,67 @@ static void trx_usrp_end(openair0_device *device) { s->tx_md.end_of_burst = false; sleep(1); #if defined(USRP_REC_PLAY) - } + } + #endif #if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { // subframes store - pFile = fopen (u_sf_filename,"wb+"); - if (pFile == NULL) { - std::cerr << "Cannot open " << u_sf_filename << std::endl; - } else { - unsigned int i = 0; - unsigned int modu = 0; - if ((modu = nb_samples % 10) != 0) { - nb_samples -= modu; // store entire number of frames - } - std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; - for (i = 0; i < nb_samples; i++) { - fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); - } - fclose (pFile); - std::cerr << "File " << u_sf_filename << " closed." << std::endl; + + if (u_sf_mode == 1) { // subframes store + pFile = fopen (u_sf_filename,"wb+"); + + if (pFile == NULL) { + std::cerr << "Cannot open " << u_sf_filename << std::endl; + } else { + unsigned int i = 0; + unsigned int modu = 0; + + if ((modu = nb_samples % 10) != 0) { + nb_samples -= modu; // store entire number of frames + } + + std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; + + for (i = 0; i < nb_samples; i++) { + fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); } + + fclose (pFile); + std::cerr << "File " << u_sf_filename << " closed." << std::endl; } - if (u_sf_mode == 1) { // record + } + + if (u_sf_mode == 1) { // record + if (ms_sample != NULL) { + free((void *)ms_sample); + ms_sample = NULL; + } + } + + if (u_sf_mode == 2) { // replay + if (use_mmap) { + if (ms_sample != MAP_FAILED) { + munmap(ms_sample, sb.st_size); + ms_sample = NULL; + } + + if (mmapfd != 0) { + close(mmapfd); + mmapfd = 0; + } + } else { if (ms_sample != NULL) { - free((void*)ms_sample); - ms_sample = NULL; + free(ms_sample); + ms_sample = NULL; } - } - if (u_sf_mode == 2) { // replay - if (use_mmap) { - if (ms_sample != MAP_FAILED) { - munmap(ms_sample, sb.st_size); - ms_sample = NULL; - } - if (mmapfd != 0) { - close(mmapfd); - mmapfd = 0; - } - } else { - if (ms_sample != NULL) { - free(ms_sample); - ms_sample = NULL; - } - if (iqfd != 0) { - close(iqfd); - iqfd = 0; - } + + if (iqfd != 0) { + close(iqfd); + iqfd = 0; } } -#endif + } + +#endif } /*! \brief Called to send samples to the USRP RF target @@ -444,78 +430,80 @@ static void trx_usrp_end(openair0_device *device) { static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { int ret=0; #if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode -#endif - usrp_state_t *s = (usrp_state_t*)device->priv; - - int nsamps2; // aligned to upper 32 or 16 byte boundary +#endif + usrp_state_t *s = (usrp_state_t *)device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[2][nsamps2]; + nsamps2 = (nsamps+7)>>3; + __m256i buff_tx[2][nsamps2]; #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + __m128i buff_tx[2][nsamps2]; #endif #elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tx[2][nsamps2]; #endif - - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; i<cc; i++) { - for (int j=0; j<nsamps2; j++) { + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - buff_tx[i][j] = _mm256_slli_epi16(((__m256i*)buff[i])[j],4); + buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4); #else - buff_tx[i][j] = _mm_slli_epi16(((__m128i*)buff[i])[j],4); + buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4); #endif #elif defined(__arm__) - buff_tx[i][j] = vshlq_n_s16(((int16x8_t*)buff[i])[j],4); + buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4); #endif + } } - } - s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - s->tx_md.has_time_spec = flags; - - - if(flags>0) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; - - if (flags == 2) { // start of burst - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; - } else if (flags == 3) { // end of burst - s->tx_md.start_of_burst = false; - 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; - } else if (flags==1) { // middle of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = false; - } - 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; - } - if (cc>1) { - std::vector<void *> buff_ptrs; - for (int i=0; i<cc; i++) - buff_ptrs.push_back(buff_tx[i]); - ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); - } else - ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3); - - - - if (ret != nsamps) - LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_md.has_time_spec = flags; + + if(flags>0) + s->tx_md.has_time_spec = true; + else + s->tx_md.has_time_spec = false; + + if (flags == 2) { // start of burst + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; + } else if (flags == 3) { // end of burst + s->tx_md.start_of_burst = false; + 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; + } else if (flags==1) { // middle of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = false; + } + + 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; + } + + if (cc>1) { + std::vector<void *> buff_ptrs; + + for (int i=0; i<cc; i++) + buff_ptrs.push_back(buff_tx[i]); + + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + } else + ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3); + + if (ret != nsamps) + LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); + #if defined(USRP_REC_PLAY) } else { struct timespec req; @@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, nanosleep(&req, NULL); ret = nsamps; } -#endif +#endif return ret; } @@ -541,12 +529,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \returns the number of sample read */ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - usrp_state_t *s = (usrp_state_t*)device->priv; + usrp_state_t *s = (usrp_state_t *)device->priv; int samples_received=0,i,j; int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode -#endif +#endif #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -561,66 +550,79 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp #endif if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); - samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received=0; - while (samples_received != nsamps) { - samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, - nsamps-samples_received, s->rx_md); - if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) - break; - if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { printf("sleep...\n");} //usleep(100); - } - if (samples_received == nsamps) s->wait_for_first_pps=0; + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; + + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); + + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received=0; + + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); + + if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) + break; + + if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { + printf("sleep...\n"); //usleep(100); + } } - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; i<cc; i++) { - for (int j=0; j<nsamps2; j++) { + + if (samples_received == nsamps) s->wait_for_first_pps=0; + } + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); + ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); #else - ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); + ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); #endif #elif defined(__arm__) - ((int16x8_t*)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); + ((int16x8_t *)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); #endif - } } + } } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); - samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); - } + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); + + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); + } } + if (samples_received < nsamps) - LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); + LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - LOG_E(PHY, "%s\n", s->rx_md.to_pp_string(true).c_str()); + LOG_E(PHY, "%s\n", s->rx_md.to_pp_string(true).c_str()); s->rx_count += nsamps; s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; #if defined (USRP_REC_PLAY) } -#endif + +#endif #if defined(USRP_REC_PLAY) + if (u_sf_mode == 1) { // record mode // Copy subframes to memory (later dump on a file) if (nb_samples < u_sf_max) { - (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; + (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; (ms_sample+nb_samples)->ts = *ptimestamp; memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4); nb_samples++; @@ -629,62 +631,78 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp if (cur_samples == nb_samples) { cur_samples = 0; wrap_count++; + if (wrap_count == u_sf_loops) { - std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; - return 0; // should make calling process exit + std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; + return 0; // should make calling process exit } + wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); + if (!use_mmap) { - if (lseek(iqfd, 0, SEEK_SET) == 0) { - std::cerr << "Seeking at the beginning of IQ file" << std::endl; - } else { - std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; - } + if (lseek(iqfd, 0, SEEK_SET) == 0) { + std::cerr << "Seeking at the beginning of IQ file" << std::endl; + } else { + std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; + } } } + if (use_mmap) { if (cur_samples < nb_samples) { - *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } - memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); - cur_samples++; + *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + + memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); + cur_samples++; } } else { // read sample from file if (read(iqfd, ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { - std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; - close(iqfd); - free(ms_sample); - ms_sample = NULL; - iqfd = 0; - exit(-1); + std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; + close(iqfd); + free(ms_sample); + ms_sample = NULL; + iqfd = 0; + exit(-1); } if (cur_samples < nb_samples) { - static int64_t ts0 = 0; - if ((cur_samples == 0) && (wrap_count == 0)) { - ts0 = ms_sample->ts; - } - *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } - memcpy(buff[0], &ms_sample->samples[0], nsamps*4); - cur_samples++; - // Prepare for next read - off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); + static int64_t ts0 = 0; + + if ((cur_samples == 0) && (wrap_count == 0)) { + ts0 = ms_sample->ts; + } + + *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + + memcpy(buff[0], &ms_sample->samples[0], nsamps*4); + cur_samples++; + // Prepare for next read + off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); } } + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = u_sf_read_delay * 1000; + nanosleep(&req, NULL); + return nsamps; } + #endif return samples_received; } @@ -694,16 +712,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp * \param b second variable */ static bool is_equal(double a, double b) { - return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); + return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); } void *freq_thread(void *arg) { - - openair0_device *device=(openair0_device *)arg; - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + openair0_device *device=(openair0_device *)arg; + usrp_state_t *s = (usrp_state_t *)device->priv; + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } /*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use @@ -711,23 +727,20 @@ void *freq_thread(void *arg) { * \param dummy dummy variable not used * \returns 0 in success */ -int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { - - usrp_state_t *s = (usrp_state_t*)device->priv; - pthread_t f_thread; - - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - - // spawn a thread to handle the frequency change to not block the calling thread - if (dont_block == 1) - pthread_create(&f_thread,NULL,freq_thread,(void*)device); - else { - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); - } - - return(0); +int trx_usrp_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) { + usrp_state_t *s = (usrp_state_t *)device->priv; + pthread_t f_thread; + printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); + + // spawn a thread to handle the frequency change to not block the calling thread + if (dont_block == 1) + pthread_create(&f_thread,NULL,freq_thread,(void *)device); + else { + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + } + return(0); } /*! \brief Set RX frequencies @@ -735,21 +748,16 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, * \param openair0_cfg RF frontend parameters set by application * \returns 0 in success */ -int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) { - - usrp_state_t *s = (usrp_state_t*)device->priv; - static int first_call=1; - static double rf_freq,diff; - - uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); - - rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; - rf_freq=openair0_cfg[0].rx_freq[0]; - s->usrp->set_rx_freq(rx_tune_req); - - return(0); - +int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg) { + usrp_state_t *s = (usrp_state_t *)device->priv; + static int first_call=1; + static double rf_freq,diff; + uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); + rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; + rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; + rf_freq=openair0_cfg[0].rx_freq[0]; + s->usrp->set_rx_freq(rx_tune_req); + return(0); } /*! \brief Set Gains (TX/RX) @@ -757,62 +765,62 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open * \param openair0_cfg RF frontend parameters set by application * \returns 0 in success */ -int trx_usrp_set_gains(openair0_device* device, +int trx_usrp_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + usrp_state_t *s = (usrp_state_t *)device->priv; + ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); + s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); + + // limit to maximum gain + if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { + LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); + exit(-1); + } - usrp_state_t *s = (usrp_state_t*)device->priv; - ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); - s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { - LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); - LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], - openair0_cfg[0].rx_gain[0],gain_range.stop()); - - return(0); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); + LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], + openair0_cfg[0].rx_gain[0],gain_range.stop()); + return(0); } /*! \brief Stop USRP * \param card refers to the hardware index to use */ -int trx_usrp_stop(openair0_device* device) { - return(0); +int trx_usrp_stop(openair0_device *device) { + return(0); } /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210[] = { - {3500000000.0,44.0}, - {2660000000.0,49.0}, - {2300000000.0,50.0}, - {1880000000.0,53.0}, - {816000000.0,58.0}, - {-1,0} + {3500000000.0,44.0}, + {2660000000.0,49.0}, + {2300000000.0,50.0}, + {1880000000.0,53.0}, + {816000000.0,58.0}, + {-1,0} }; /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210_38[] = { - {3500000000.0,44.0}, - {2660000000.0,49.8}, - {2300000000.0,51.0}, - {1880000000.0,53.0}, - {816000000.0,57.0}, - {-1,0} + {3500000000.0,44.0}, + {2660000000.0,49.8}, + {2300000000.0,51.0}, + {1880000000.0,53.0}, + {816000000.0,57.0}, + {-1,0} }; /*! \brief USRPx310 RX calibration table */ rx_gain_calib_table_t calib_table_x310[] = { - {3500000000.0,77.0}, - {2660000000.0,81.0}, - {2300000000.0,81.0}, - {1880000000.0,82.0}, - {816000000.0,85.0}, - {-1,0} + {3500000000.0,77.0}, + {2660000000.0,81.0}, + {2300000000.0,81.0}, + {1880000000.0,82.0}, + {816000000.0,85.0}, + {-1,0} }; /*! \brief Set RX gain offset @@ -821,72 +829,81 @@ rx_gain_calib_table_t calib_table_x310[] = { * \returns 0 in success */ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff,gain_adj=0.0; - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff,gain_adj=0.0; - if (bw_gain_adjust==1) { - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - break; - case 23040000: - gain_adj=1.25; - break; - case 15360000: - gain_adj=3.0; - break; - case 7680000: - gain_adj=6.0; - break; - case 3840000: - gain_adj=9.0; - break; - case 1920000: - gain_adj=12.0; - break; - default: - LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); - exit(-1); - break; - } + if (bw_gain_adjust==1) { + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + break; + + case 23040000: + gain_adj=1.25; + break; + + case 15360000: + gain_adj=3.0; + break; + + case 7680000: + gain_adj=6.0; + break; + + case 3840000: + gain_adj=9.0; + break; + + case 1920000: + gain_adj=12.0; + break; + + default: + LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); + exit(-1); + break; } - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; - } - i++; + } + + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, + openair0_cfg->rx_gain_calib_table[i].offset,diff); + + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; } + + i++; + } } /*! \brief print the USRP statistics * \param device the hardware to use * \returns 0 on success */ -int trx_usrp_get_stats(openair0_device* device) { - return(0); +int trx_usrp_get_stats(openair0_device *device) { + return(0); } /*! \brief Reset the USRP statistics * \param device the hardware to use * \returns 0 on success */ -int trx_usrp_reset_stats(openair0_device* device) { - return(0); +int trx_usrp_reset_stats(openair0_device *device) { + return(0); } #if defined(USRP_REC_PLAY) extern "C" { -/*! \brief Initializer for USRP record/playback config - * \param parameter array description - * \returns 0 on success - */ -int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { + /*! \brief Initializer for USRP record/playback config + * \param parameter array description + * \returns 0 on success + */ + int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { // --subframes-file memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file)); usrp_recplay_params[0].helpstr = config_hlp_sf_file; @@ -943,456 +960,483 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE; usrp_recplay_params[6].type=TYPE_UINT; usrp_recplay_params[6].numelt=0; - return 0; // always ok -} + } } #endif extern "C" { - /*! \brief Initialize Openair USRP target. It returns 0 if OK - * \param device the hardware to use - * \param openair0_cfg RF frontend parameters set by application - */ - int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { + /*! \brief Initialize Openair USRP target. It returns 0 if OK + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + */ + int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + LOG_D(PHY, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs); + LOG_D(PHY, "openair0_cfg[0].clock_source == '%d'\n", openair0_cfg[0].clock_source); #if defined(USRP_REC_PLAY) - paramdef_t usrp_recplay_params[7]; - struct sysinfo systeminfo; - // to check - static int done = 0; - if (done == 1) { - return 0; - } // prevent from multiple init - done = 1; - // end to check - // Use mmap for IQ files for systems with less than 6GB total RAM - sysinfo(&systeminfo); - if (systeminfo.totalram < 6144000000) { - use_mmap = 0; + paramdef_t usrp_recplay_params[7]; + struct sysinfo systeminfo; + // to check + static int done = 0; + + if (done == 1) { + return 0; + } // prevent from multiple init + + done = 1; + // end to check + // Use mmap for IQ files for systems with less than 6GB total RAM + sysinfo(&systeminfo); + + if (systeminfo.totalram < 6144000000) { + use_mmap = 0; + } + + memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); + memset(&u_sf_filename[0], 0, 1024); + + if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { + std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; + return -1; + } + + config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); + + if (strlen(u_sf_filename) == 0) { + (void) strcpy(u_sf_filename, DEF_SF_FILE); + } + + if (u_sf_replay == 1) u_sf_mode = 2; + + if (u_sf_record == 1) u_sf_mode = 1; + + if (u_sf_mode == 2) { + // Replay subframes from from file + int bw_gain_adjust=0; + device->openair0_cfg = openair0_cfg; + device->type = USRP_B200_DEV; + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + 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->priv = NULL; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; + std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" + << use_mmap << std::endl; + } else { +#endif + uhd::set_thread_priority_safe(1.0); + usrp_state_t *s = (usrp_state_t *)calloc(sizeof(usrp_state_t),1); + + if (openair0_cfg[0].clock_source==gpsdo) + s->use_gps =1; + + // Initialize USRP device + device->openair0_cfg = openair0_cfg; + int vers=0,subvers=0,subsubvers=0; + int bw_gain_adjust=0; +#if defined(USRP_REC_PLAY) + + if (u_sf_mode == 1) { + std::cerr << "USRP device initialized in subframes record mode" << std::endl; + } + +#endif + sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); + LOG_I(PHY,"Checking for USRPs : UHD %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; } - memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); - memset(&u_sf_filename[0], 0, 1024); - if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { - std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; + + uhd::device_addrs_t device_adds = uhd::device::find(args); + + if (device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } else if (device_adds.size() > 1) { + std::cerr<<"More than one USRP Device Found. Please specify device more precisely in config file." << std::endl; + free(s); return -1; } - config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); - if (strlen(u_sf_filename) == 0) { - (void) strcpy(u_sf_filename, DEF_SF_FILE); + std::cerr << "Found USRP " << device_adds[0].get("type") << "\n"; + 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=15360, recv_frame_size=15360" ; } - if (u_sf_replay == 1) u_sf_mode = 2; - if (u_sf_record == 1) u_sf_mode = 1; - - if (u_sf_mode == 2) { - // Replay subframes from from file - int bw_gain_adjust=0; - device->openair0_cfg = openair0_cfg; - device->type = USRP_B200_DEV; - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - 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->priv = NULL; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" - << use_mmap << std::endl; - } else { -#endif - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); - - if (openair0_cfg[0].clock_source==gpsdo) - s->use_gps =1; + 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); + } - // Initialize USRP device - device->openair0_cfg = openair0_cfg; + 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); + } - std::string args = "type=b200"; - uhd::device_addrs_t device_adds = uhd::device::find(args); + s->usrp = uhd::usrp::multi_usrp::make(args); - int vers=0,subvers=0,subsubvers=0; - int bw_gain_adjust=0; + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); + if (device->type==USRP_X300_DEV) { + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; #if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { - std::cerr << "USRP device initialized in subframes record mode" << std::endl; - } -#endif - sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); - LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", - uhd::get_version_string().c_str(),vers,subvers,subsubvers); - - if(device_adds.size() == 0) { - double usrp_master_clock = 184.32e6; - std::string args = "type=x300"; - - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate - args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - - // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - uhd::device_addrs_t device_adds = uhd::device::find(args); - - if(device_adds.size() == 0) { - args += ",addr=192.168.30.2"; - - uhd::device_addrs_t device_adds = uhd::device::find(args); - - if(device_adds.size() == 0) { - - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - } - } - LOG_I(PHY,"Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); + std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info +#endif + LOG_I(PHY,"%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; - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; + 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; - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); + 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; - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + 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(PHY,"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; #if defined(USRP_REC_PLAY) - std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info + std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info #endif + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; +#if defined(USRP_REC_PLAY) + std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info +#endif + } - LOG_I(PHY,"%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 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 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(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + switch ((int)openair0_cfg[0].sample_rate) { + 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; - } else { - LOG_I(PHY,"Found USRP B200\n"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); + 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; - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); + 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; - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming + 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; - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal){ - s->usrp->set_clock_source("internal"); - } - else{ - s->usrp->set_clock_source("external"); - s->usrp->set_time_source("external"); - } - - 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; -#if defined(USRP_REC_PLAY) - std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info -#endif - } else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; -#if defined(USRP_REC_PLAY) - std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info -#endif - } + 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; - switch ((int)openair0_cfg[0].sample_rate) { - 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(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + default: + LOG_E(PHY,"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<s->usrp->get_rx_num_channels(); i++) { - if (i<openair0_cfg[0].rx_num_channels) { - s->usrp->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(PHY,"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()); - } + /* 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<s->usrp->get_rx_num_channels(); i++) { + if (i<openair0_cfg[0].rx_num_channels) { + s->usrp->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(PHY,"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()); } + } - for(int i=0; i<s->usrp->get_tx_num_channels(); i++) { - ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); - if (i<openair0_cfg[0].tx_num_channels) { - s->usrp->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_D(PHY, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels()); + LOG_D(PHY, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels); - LOG_I(PHY,"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]); - } - } + for(int i=0; i<s->usrp->get_tx_num_channels(); i++) { + ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); - //s->usrp->set_clock_source("external"); - //s->usrp->set_time_source("external"); - - // display USRP settings - LOG_I(PHY,"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(PHY,"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(PHY,"rx_max_num_samps %zu\n", - s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); - - for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) - stream_args_rx.channels.push_back(i); - s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); - - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++) - stream_args_tx.channels.push_back(i); - s->tx_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<s->usrp->get_tx_num_channels() && i<openair0_cfg[0].tx_num_channels; i++) - s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - - for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++) - s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - - for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) { - LOG_I(PHY,"RX Channel %d\n",i); - LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6); - LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); - LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); - LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); - LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + if (i<openair0_cfg[0].tx_num_channels) { + s->usrp->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(PHY,"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]); } + } - for (int i=0; i<openair0_cfg[0].tx_num_channels; i++) { - LOG_I(PHY,"TX Channel %d\n",i); - LOG_I(PHY," Actual TX sample rate: %fMSps...\n", s->usrp->get_tx_rate(i)/1e6); - LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); - LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); - LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); - LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); - } + //s->usrp->set_clock_source("external"); + //s->usrp->set_time_source("external"); + // display USRP settings + LOG_I(PHY,"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(PHY,"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(PHY,"rx_max_num_samps %zu\n", + s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + + for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) + stream_args_rx.channels.push_back(i); + + s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + + for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++) + stream_args_tx.channels.push_back(i); + + s->tx_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<s->usrp->get_tx_num_channels() && i<openair0_cfg[0].tx_num_channels; i++) + s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + + for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++) + s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); + + for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) { + LOG_I(PHY,"RX Channel %d\n",i); + LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6); + LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); + LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); + LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); + LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + } + + for (int i=0; i<openair0_cfg[0].tx_num_channels; i++) { + LOG_I(PHY,"TX Channel %d\n",i); + LOG_I(PHY," Actual TX sample rate: %fMSps...\n", s->usrp->get_tx_rate(i)/1e6); + LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); + LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); + LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); + LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); + } - LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - - device->priv = s; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - - 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->use_gps == 1) { - if (sync_to_gps(device)) { - LOG_I(PHY,"USRP fails to sync with GPS...\n"); - exit(0); - } + LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); + device->priv = s; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; + 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->use_gps == 1) { + if (sync_to_gps(device)) { + LOG_I(PHY,"USRP fails to sync with GPS...\n"); + exit(0); } - -#if defined(USRP_REC_PLAY) } + +#if defined(USRP_REC_PLAY) + } + #endif #if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { // record mode - ms_sample = (iqrec_t*) malloc(u_sf_max * sizeof(iqrec_t)); - if (ms_sample == NULL) { - std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; - exit(-1); - } - memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + + if (u_sf_mode == 1) { // record mode + ms_sample = (iqrec_t *) malloc(u_sf_max * sizeof(iqrec_t)); + + if (ms_sample == NULL) { + std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; + exit(-1); } - if (u_sf_mode == 2) { - if (use_mmap) { - // use mmap - mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); - if (mmapfd != 0) { - fstat(mmapfd, &sb); - std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; - ms_sample = (iqrec_t*) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); - if (ms_sample != MAP_FAILED) { - nb_samples = (sb.st_size / sizeof(iqrec_t)); - int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; - std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; - if (aligned == 0) { - std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; - close(mmapfd); - exit(-1); - } - } else { - std::cerr << "Cannot mmap file, exiting." << std::endl; - close(mmapfd); - exit(-1); - } - } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; - exit(-1); - } - } else { - iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); - if (iqfd != 0) { - fstat(iqfd, &sb); - nb_samples = (sb.st_size / sizeof(iqrec_t)); - std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename - << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; - // allocate buffer for 1 sample at a time - ms_sample = (iqrec_t*) malloc(sizeof(iqrec_t)); - if (ms_sample == NULL) { - std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; - close(iqfd); - exit(-1); - } - memset(ms_sample, 0, sizeof(iqrec_t)); - // point at beginning of file - if (lseek(iqfd, 0, SEEK_SET) == 0) { - std::cerr << "Initial seek at beginning of the file" << std::endl; - } else { - std::cerr << "Problem initial seek at beginning of the file" << std::endl; - } - } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; - exit(-1); - } - } + + memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + } + + if (u_sf_mode == 2) { + if (use_mmap) { + // use mmap + mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + + if (mmapfd != 0) { + fstat(mmapfd, &sb); + std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); + + if (ms_sample != MAP_FAILED) { + nb_samples = (sb.st_size / sizeof(iqrec_t)); + int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; + std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; + + if (aligned == 0) { + std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; + close(mmapfd); + exit(-1); + } + } else { + std::cerr << "Cannot mmap file, exiting." << std::endl; + close(mmapfd); + exit(-1); + } + } else { + std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + exit(-1); + } + } else { + iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + + if (iqfd != 0) { + fstat(iqfd, &sb); + nb_samples = (sb.st_size / sizeof(iqrec_t)); + std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename + << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + // allocate buffer for 1 sample at a time + ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); + + if (ms_sample == NULL) { + std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; + close(iqfd); + exit(-1); + } + + memset(ms_sample, 0, sizeof(iqrec_t)); + + // point at beginning of file + if (lseek(iqfd, 0, SEEK_SET) == 0) { + std::cerr << "Initial seek at beginning of the file" << std::endl; + } else { + std::cerr << "Problem initial seek at beginning of the file" << std::endl; + } + } else { + std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + exit(-1); + } } -#endif - return 0; } + +#endif + return 0; + } } /*@}*/ diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index ba6d96db93372c3407d0d1c41ff666e3a2a85606..32fddb9c2dcffcb811fdbe4136c3da45fa5e0be0 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -44,6 +44,7 @@ typedef struct { int sock; int samples_per_subframe; uint64_t timestamp; + uint64_t next_tx_timestamp; int is_enb; } tcp_bridge_state_t; @@ -141,11 +142,27 @@ int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void { if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } tcp_bridge_state_t *t = device->priv; + /* deal with discontinuities in output (think: eNB in TDD mode) */ + if (t->next_tx_timestamp && timestamp != t->next_tx_timestamp) { + uint32_t b[4096]; + uint64_t to_send = timestamp - t->next_tx_timestamp; + memset(b, 0, 4096 * sizeof(uint32_t)); + while (to_send) { + int len = to_send > 4096 ? 4096 : to_send; + int n = fullwrite(t->sock, b, len * 4); + if (n != len * 4) { + printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); + abort(); + } + to_send -= len; + } + } int n = fullwrite(t->sock, buff[0], nsamps * 4); if (n != nsamps * 4) { printf("tcp_bridge: write error ret %d (wanted %d) error %s\n", n, nsamps*4, strerror(errno)); abort(); } + t->next_tx_timestamp = timestamp + nsamps; return nsamps; } @@ -253,7 +270,7 @@ int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timest tcp_bridge_state_t *t = device->priv; uint32_t b[t->samples_per_subframe * 12]; - memset(b, 0, nsamps * 4); + memset(b, 0, t->samples_per_subframe * 12 * 4); int n = fullwrite(t->sock, b, t->samples_per_subframe * 12 * 4); if (n != t->samples_per_subframe * 12 * 4) { printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 391e448deb590584e9a4b917edd4a6210b1fa1a5..0d306ee50b34908c74ecd73931ac70365753f551 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -22,15 +22,18 @@ #if defined(ENABLE_ITTI) # include "intertask_interface.h" # include "create_tasks.h" -# include "log.h" +# include "common/utils/LOG/log.h" # ifdef OPENAIR2 # if defined(ENABLE_USE_MME) # include "sctp_eNB_task.h" +# include "x2ap_eNB.h" # include "s1ap_eNB.h" # include "nas_ue_task.h" # include "udp_eNB_task.h" # include "gtpv1u_eNB_task.h" +# else +# define EPC_MODE_ENABLED 0 # endif # if ENABLE_RAL # include "lteRALue.h" @@ -59,9 +62,14 @@ int create_tasks(uint32_t enb_nb) return -1; } } - -# if defined(ENABLE_USE_MME) +# if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { if (enb_nb > 0) { + if (itti_create_task (TASK_X2AP, x2ap_task, NULL) < 0) { + LOG_E(X2AP, "Create task for X2AP 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; @@ -84,8 +92,8 @@ int create_tasks(uint32_t enb_nb) } } -# endif - + } /* if (EPC_MODE_ENABLED) */ +#endif if (enb_nb > 0) { LOG_I(RRC,"Creating RRC eNB Task\n"); diff --git a/targets/COMMON/create_tasks_ue.c b/targets/COMMON/create_tasks_ue.c index db531b0e9ddd73294530a337909d04c8878039fd..20b5979f31ee1c5829aee774739c4095afe50a49 100644 --- a/targets/COMMON/create_tasks_ue.c +++ b/targets/COMMON/create_tasks_ue.c @@ -22,7 +22,7 @@ #if defined(ENABLE_ITTI) # include "intertask_interface.h" # include "create_tasks.h" -# include "log.h" +# include "common/utils/LOG/log.h" # ifdef OPENAIR2 # if defined(ENABLE_USE_MME) diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf index 09406d98cf534b27fd1abe11b54562c086be25b7..86131b3e8e97e0b98fadfe7d6617a37f67a9e569 100755 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf @@ -15,12 +15,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "15"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - + tracking_area_code = 15; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; @@ -47,6 +44,9 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.13.10/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf index 47c12a79266b8ff907c3d26e75fe9a12ce7d5005..e87a37f9fb8cc5a3fd9e523307f0e18fc17a6bd6 100755 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf @@ -15,12 +15,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "15"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - + tracking_area_code = 15; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; @@ -59,6 +56,9 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.13.10/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; # available options for level: error, warn, notice, info, debug, trace # available options for verbosity: none, low, medium, high, full diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf index 4360884c1db1bcb6f1ca30a5b275e1e1938deedc..af4f4236a7b2059f04193edd9d9be5eb56ff6eeb 100755 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf @@ -14,12 +14,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "15"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - + tracking_area_code = 15; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; @@ -46,6 +43,9 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1U = "eth1"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.13.10/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/targets/PROJECTS/E-MBMS/enb.conf b/targets/PROJECTS/E-MBMS/enb.conf index 852f7bbf5f146c260713a64a396e99f4c452a16b..ea256487b078c12f14d046ba4b44d2a02ff91058 100755 --- a/targets/PROJECTS/E-MBMS/enb.conf +++ b/targets/PROJECTS/E-MBMS/enb.conf @@ -11,12 +11,9 @@ eNBs = eNB_name = "eNB_Eurecom_0"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 1; - - mobile_country_code = 208; - - mobile_network_code = 10; - + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 10; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf index 73da2a8b3f37c65507ef1994f930021d7bacfd29..8c080b7d1059c6cc4bfd03808b24f3fba1779bef 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf @@ -13,10 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -151,8 +150,20 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; +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 ="debug"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf index bd0503a4669b698fc568a782272a99571c76b6e8..83954a00d52c3e2522371336db87fb6b574ff051 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf @@ -13,10 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: @@ -151,8 +150,20 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; +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 ="debug"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index 9a2ca88257352d763a3d67cf9cfed17a4d7e8b5b..60b47c5c493e62a245dbbcb8d50a5267a21b9ed8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -149,12 +147,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth6"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -191,6 +191,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf index 99df987b43797da367931ff5f08f2583bb1523e0..823c5fb1c3e7ec1c9e04fd42fe3cee6af3afac72 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,12 +181,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.13.10/24"; ENB_INTERFACE_NAME_FOR_S1U = "lo"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.13.10/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -233,6 +233,15 @@ NETWORK_CONTROLLER : FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); /* log_config : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf index 7d73e55c6c8e494e556bfb508eb6c9cd28ad81ef..476d4903f1c5b04e16b3caa927c68ed2e057fc76 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,14 +181,14 @@ eNBs = 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 = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/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 }; } ); @@ -225,6 +223,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 69166672d79298d91ff605d5fa2fbf21b5cc6515..83834bfeca6d51a6c8866d95d31d3ef680eed9aa 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,12 +181,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -236,6 +236,15 @@ NETWORK_CONTROLLER : FLEXRAN_AWAIT_RECONF = "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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + log_config : { global_log_level ="info"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf index 1197c4ad937638de4825c6ac99237438bb7f18e6..403e5f24f54cb114dfd9e971f5d2a9541c7625e7 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -150,12 +148,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.19/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -190,6 +190,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf index c4d23bac42b3a9bb8f0be3ad40f14b64a0834be5..7eb16a3b7a9f0f0da3fdd706c254211c6cf53d01 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf @@ -16,11 +16,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -152,12 +150,14 @@ eNBs = 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 }; } ); @@ -197,6 +197,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf index 71a163209ded9e16fd01ac56ad8b0d73491dc11f..47047e5626cbf9e170515b920507b665030dfe25 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf @@ -13,12 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - #mobile_network_code = "93"; - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -153,12 +150,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "vboxnet0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.56.1/24"; ENB_INTERFACE_NAME_FOR_S1U = "vboxnet0"; ENB_IPV4_ADDRESS_FOR_S1U = "192.168.56.1/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.56.1/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } @@ -180,6 +179,15 @@ MACRLCs = ( } ); +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 ="debug"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index a6da42c2f563cbed744420b8f4832c81da5079c0..ced031163d242aef51b065bf8a73cdc5142547cc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -183,12 +181,14 @@ eNBs = 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 }; } ); @@ -208,6 +208,15 @@ MACRLCs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index 550de4e1a2c5a56b846a8d5bf296a08f2ddaabad..d989ac8b1087ec181e1da88ffca01aee0130ed7f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -16,11 +16,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -152,12 +150,14 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.19/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -196,6 +196,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index 2b5a0ca68469eae11ba2587f9aae402a8dba7fc5..79bd48cd0c5dac9287810cdf377c8322aec000ca 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -16,11 +16,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -151,12 +149,14 @@ eNBs = 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 }; } ); @@ -195,6 +195,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf index 41b322fb55865e6a519f31ecfc587a50c9acaf9a..ba2e7f1ada542e7df2d29af491890c7b30cf6e4c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf @@ -17,6 +17,15 @@ RUs = ( } ); +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"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf index da1481ac7bc24260490a177884d91108bb5451c1..494086defdc827df902b90f7b5446bd38753f451 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf @@ -18,6 +18,15 @@ RUs = ( } ); +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"; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index c8c35cf2e88d57cf20f61182df6fc4b492405fdd..e2415e115683da77ccf35fbafc9783053c249490 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -33,7 +33,6 @@ #define _GNU_SOURCE #include <pthread.h> -#include "time_utils.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all @@ -112,8 +111,6 @@ extern volatile int start_UE; #endif extern volatile int oai_exit; -extern openair0_config_t openair0_cfg[MAX_CARDS]; - extern int transmission_mode; extern int oaisim_flag; @@ -142,7 +139,6 @@ static struct { extern double cpuf; -void exit_fun(const char* s); void init_eNB(int,int); void stop_eNB(int nb_inst); @@ -153,7 +149,8 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif -extern int codingw; +extern PARALLEL_CONF_t get_thread_parallel_conf(void); +extern WORKER_CONF_t get_thread_worker_conf(void); extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); @@ -225,7 +222,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 ); - if(!eNB->single_thread_flag && get_nprocs() >= 8){ + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT){ if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx); return(-1); @@ -247,7 +244,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam /* CONFLICT RESOLUTION: BEGIN */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 ); if(oai_exit) return(-1); - if(eNB->single_thread_flag || get_nprocs() <= 4){ + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){ #ifndef PHY_TX_THREAD phy_procedures_eNB_TX(eNB, proc, 1); #endif @@ -261,7 +258,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx); LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", - softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, + softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time, TICK_TO_US(eNB->phy_proc), TICK_TO_US(eNB->phy_proc_tx), TICK_TO_US(eNB->phy_proc_rx), @@ -423,8 +420,8 @@ static void* eNB_thread_rxtx( void* param ) { } pthread_mutex_unlock( &proc->mutex_rxtx ); if (nfapi_mode!=2){ - if(get_nprocs() >= 8) wakeup_tx(eNB,eNB->proc.ru_proc); - else + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,eNB->proc.ru_proc); + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) { phy_procedures_eNB_TX(eNB, proc, 1); wakeup_txfh(proc,eNB->proc.ru_proc); @@ -783,10 +780,10 @@ static void* eNB_thread_prach( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; + if (oai_exit) break; LOG_D(PHY,"Running eNB prach procedures\n"); prach_procedures(eNB @@ -824,10 +821,10 @@ static void* eNB_thread_prach_br( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; + if (oai_exit) break; LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n"); prach_procedures(eNB,1); @@ -883,7 +880,7 @@ static void* process_stats_thread(void* param) { void init_eNB_proc(int inst) { - int i=0; + /*int i=0;*/ int CC_id; PHY_VARS_eNB *eNB; eNB_proc_t *proc; @@ -955,7 +952,7 @@ void init_eNB_proc(int inst) { // attr_te = &proc->attr_te; #endif - if(get_nprocs() > 2 && codingw) + if(get_thread_worker_conf() == WORKER_ENABLE) { init_te_thread(eNB); init_td_thread(eNB); @@ -964,7 +961,7 @@ void init_eNB_proc(int inst) { LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); - if (eNB->single_thread_flag==0 && nfapi_mode!=2) { + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); } @@ -972,13 +969,13 @@ void init_eNB_proc(int inst) { #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); #endif - char name[16]; + /*char name[16]; if (eNB->single_thread_flag==0) { snprintf( name, sizeof(name), "RXTX0 %d", i ); pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); snprintf( name, sizeof(name), "RXTX1 %d", i ); pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - } + }*/ AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); @@ -1031,8 +1028,10 @@ void kill_eNB_proc(int inst) { proc = &eNB->proc; proc_rxtx = &proc->proc_rxtx[0]; - kill_td_thread(eNB); - kill_te_thread(eNB); + if(get_thread_worker_conf() == WORKER_ENABLE) { + kill_td_thread(eNB); + kill_te_thread(eNB); + } LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); for (i=0; i<2; i++) { pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); @@ -1041,8 +1040,10 @@ void kill_eNB_proc(int inst) { pthread_cond_signal(&proc_rxtx[i].cond_rxtx); pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); } + pthread_mutex_lock(&proc->mutex_prach); proc->instance_cnt_prach = 0; pthread_cond_signal( &proc->cond_prach ); + pthread_mutex_unlock(&proc->mutex_prach); pthread_cond_signal( &proc->cond_asynch_rxtx ); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); @@ -1069,6 +1070,16 @@ void kill_eNB_proc(int inst) { pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); } + + pthread_attr_destroy(&proc->attr_prach); + pthread_attr_destroy(&proc->attr_asynch_rxtx); + pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); + pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); +#ifdef Rel14 + pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); + pthread_attr_destroy(&proc->attr_prach_br); +#endif + } } @@ -1106,10 +1117,10 @@ void free_transport(PHY_VARS_eNB *eNB) int j; for (i=0; i<NUMBER_OF_UE_MAX; i++) { - LOG_I(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i); + LOG_D(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i); for (j=0; j<2; j++) free_eNB_dlsch(eNB->dlsch[i][j]); - LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); free_eNB_ulsch(eNB->ulsch[1+i]); } free_eNB_ulsch(eNB->ulsch[0]); @@ -1311,8 +1322,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { #endif - eNB->td = ulsch_decoding_data_all;//(get_nprocs()<=4) ? ulsch_decoding_data : ulsch_decoding_data_2thread; - eNB->te = dlsch_encoding_all;//(get_nprocs()<=4) ? dlsch_encoding : dlsch_encoding_2threads; + eNB->td = ulsch_decoding_data_all; + eNB->te = dlsch_encoding_all; LOG_I(PHY,"Registering with MAC interface module\n"); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index a0339e8f0f738ce18ab909710d7c01d73e8ca9fb..7002bc4ebd0020f38fff3002eebe952a84356ae0 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -119,10 +119,10 @@ static int DEFENBS[] = {0}; extern volatile int oai_exit; extern int emulate_rf; extern int numerology; -extern int fepw; -extern int single_thread_flag; extern clock_source_t clock_source; +extern PARALLEL_CONF_t get_thread_parallel_conf(void); +extern WORKER_CONF_t get_thread_worker_conf(void); extern void phy_init_RU(RU_t*); extern void phy_free_RU(RU_t*); @@ -1080,8 +1080,8 @@ static void* ru_thread_prach( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; + if (oai_exit) break; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); if (ru->eNB_list[0]){ prach_procedures( @@ -1130,8 +1130,8 @@ static void* ru_thread_prach_br( void* param ) { while (!oai_exit) { - if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"ru_prach_thread_br") < 0) break; + if (oai_exit) break; rx_prach(NULL, ru, NULL, @@ -1257,7 +1257,7 @@ void wakeup_eNBs(RU_t *ru) { LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); - if (ru->num_eNB==1 && ru->eNB_top!=0 && (get_nprocs() <= 4 || single_thread_flag)) { + if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { // call eNB function directly char string[20]; @@ -1456,6 +1456,12 @@ int setup_RU_buffers(RU_t *ru) { if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624; else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; +#if BASIC_SIMULATOR + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + ru->N_TA_offset = 0; +#endif } if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions @@ -1782,7 +1788,7 @@ static void* ru_thread( void* param ) { if (ru->num_eNB>0) wakeup_eNBs(ru); #ifndef PHY_TX_THREAD - if(get_nprocs() <= 4 || ru->num_eNB==0 || single_thread_flag){ + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){ // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1882,13 +1888,13 @@ void *ru_thread_synch(void *arg) { LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); -LOG_M_BEGIN(RU) - if ((peak_val > 300000) && (sync_pos > 0)) { - LOG_M("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2); - LOG_M("ru_rx.m","rxs",&(ru->eNB_list[0]->common_vars.rxdata[0][0]),fp->samples_per_tti*10,1,1); - exit(-1); - } -LOG_M_END + if (LOG_DEBUGFLAG(RU)) { + if ((peak_val > 300000) && (sync_pos > 0)) { + LOG_M("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2); + LOG_M("ru_rx.m","rxs",&(ru->eNB_list[0]->common_vars.rxdata[0][0]),fp->samples_per_tti*10,1,1); + exit(-1); + } + } ru->in_synch=1; } } @@ -2195,7 +2201,7 @@ void init_RU_proc(RU_t *ru) { if(emulate_rf) pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc ); - if (!single_thread_flag && get_nprocs() > 4) + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru ); if (ru->function == NGFI_RRU_IF4p5) { @@ -2222,7 +2228,7 @@ void init_RU_proc(RU_t *ru) { pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); } - if (get_nprocs()> 2 && fepw) { + if (get_thread_worker_conf() == WORKER_ENABLE) { init_fep_thread(ru,NULL); init_feptx_thread(ru,NULL); } @@ -2230,12 +2236,37 @@ void init_RU_proc(RU_t *ru) { } -void kill_RU_proc(int inst) +void kill_RU_proc(RU_t *ru) { - RU_t *ru = RC.ru[inst]; RU_proc_t *proc = &ru->proc; - if (get_nprocs() > 2 && fepw) { +#if defined(PRE_SCD_THREAD) + pthread_mutex_lock(&proc->mutex_pre_scd); + ru->proc.instance_pre_scd = 0; + pthread_cond_signal(&proc->cond_pre_scd); + pthread_mutex_unlock(&proc->mutex_pre_scd); + pthread_join(proc->pthread_pre_scd, NULL); + pthread_mutex_destroy(&proc->mutex_pre_scd); + pthread_cond_destroy(&proc->cond_pre_scd); +#endif +#ifdef PHY_TX_THREAD + pthread_mutex_lock(&proc->mutex_phy_tx); + proc->instance_cnt_phy_tx = 0; + pthread_cond_signal(&proc->cond_phy_tx); + pthread_mutex_unlock(&proc->mutex_phy_tx); + pthread_join(ru->proc.pthread_phy_tx, NULL); + pthread_mutex_destroy( &proc->mutex_phy_tx); + pthread_cond_destroy( &proc->cond_phy_tx); + pthread_mutex_lock(&proc->mutex_rf_tx); + proc->instance_cnt_rf_tx = 0; + pthread_cond_signal(&proc->cond_rf_tx); + pthread_mutex_unlock(&proc->mutex_rf_tx); + pthread_join(proc->pthread_rf_tx, NULL); + pthread_mutex_destroy( &proc->mutex_rf_tx); + pthread_cond_destroy( &proc->cond_rf_tx); +#endif + + if (get_thread_worker_conf() == WORKER_ENABLE) { LOG_D(PHY, "killing FEP thread\n"); kill_fep_thread(ru); LOG_D(PHY, "killing FEP TX thread\n"); @@ -2271,8 +2302,10 @@ void kill_RU_proc(int inst) pthread_mutex_lock(&proc->mutex_eNBs); proc->ru_tx_ready = 0; - proc->instance_cnt_eNBs = 0; - pthread_cond_signal(&proc->cond_eNBs); + proc->instance_cnt_eNBs = 1; + // cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send + // a broadcast to wake up both threads + pthread_cond_broadcast(&proc->cond_eNBs); pthread_mutex_unlock(&proc->mutex_eNBs); pthread_mutex_lock(&proc->mutex_asynch_rxtx); @@ -2280,10 +2313,12 @@ void kill_RU_proc(int inst) pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - /*LOG_D(PHY, "Joining pthread_FH\n"); + LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); - LOG_D(PHY, "Joining pthread_FHTX\n"); - pthread_join(proc->pthread_FH1, NULL);*/ + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { + LOG_D(PHY, "Joining pthread_FHTX\n"); + pthread_join(proc->pthread_FH1, NULL); + } if (ru->function == NGFI_RRU_IF4p5) { LOG_D(PHY, "Joining pthread_prach\n"); pthread_join(proc->pthread_prach, NULL); @@ -2554,8 +2589,8 @@ void set_function_spec_param(RU_t *ru) ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception ru->fh_south_out = tx_rf; // send output to RF ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full :ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) ru->feptx_prec = NULL; ru->start_if = start_if; // need to start the if interface for if4p5 ru->ifdevice.host_type = RRU_HOST; @@ -2576,8 +2611,8 @@ void set_function_spec_param(RU_t *ru) } else if (ru->function == eNodeB_3GPP) { ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full : ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding ru->feptx_prec = feptx_prec; // this is fep with idft and precoding ru->fh_north_in = NULL; // no incoming fronthaul from north ru->fh_north_out = NULL; // no outgoing fronthaul to north @@ -2605,9 +2640,9 @@ void set_function_spec_param(RU_t *ru) case REMOTE_IF5: // the remote unit is IF5 RRU ru->do_prach = 0; - ru->feprx = (get_nprocs()<=2 || !fepw) ? fep_full : fep_full; // this is frequency-shift + DFTs + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full; // this is frequency-shift + DFTs ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs if (ru->if_timing == synch_to_other) { ru->fh_south_in = fh_slave_south_in; // synchronize to master ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass @@ -2755,45 +2790,11 @@ void init_RU(char *rf_config_file) { } - - - -void stop_ru(RU_t *ru) { - -#if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD) - int *status; -#endif - printf("Stopping RU %p processing threads\n",(void*)ru); -#if defined(PRE_SCD_THREAD) - if(ru){ - ru->proc.instance_pre_scd = 0; - pthread_cond_signal( &ru->proc.cond_pre_scd ); - pthread_join(ru->proc.pthread_pre_scd, (void**)&status ); - pthread_mutex_destroy(&ru->proc.mutex_pre_scd ); - pthread_cond_destroy(&ru->proc.cond_pre_scd ); - } -#endif -#ifdef PHY_TX_THREAD - if(ru){ - ru->proc.instance_cnt_phy_tx = 0; - pthread_cond_signal(&ru->proc.cond_phy_tx); - pthread_join( ru->proc.pthread_phy_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_phy_tx ); - pthread_cond_destroy( &ru->proc.cond_phy_tx ); - ru->proc.instance_cnt_rf_tx = 0; - pthread_cond_signal(&ru->proc.cond_rf_tx); - pthread_join( ru->proc.pthread_rf_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_rf_tx ); - pthread_cond_destroy( &ru->proc.cond_rf_tx ); - } -#endif -} - void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - kill_RU_proc(inst); + kill_RU_proc(RC.ru[inst]); } } @@ -2838,6 +2839,24 @@ void RCconfig_RU(void) { RC.ru[j]->num_eNB = 0; for (i=0;i<RC.ru[j]->num_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { + RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); + } + + if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) { + if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) { + RC.ru[j]->openair0_cfg.clock_source = internal; + LOG_D(PHY, "RU clock source set as internal\n"); + } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) { + RC.ru[j]->openair0_cfg.clock_source = external; + LOG_D(PHY, "RU clock source set as external\n"); + } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) { + RC.ru[j]->openair0_cfg.clock_source = gpsdo; + LOG_D(PHY, "RU clock source set as gpsdo\n"); + } else { + LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); + } + } if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index e84f99e67f4126d2a6ee8b0efe49099a12022a34..03a461454fc376e39ec4fa37ce03b141e406c8a1 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -83,7 +83,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #endif #if defined(ENABLE_ITTI) -#include "intertask_interface_init.h" #include "create_tasks.h" #endif @@ -108,6 +107,10 @@ unsigned char scope_enb_num_ue = 2; static pthread_t forms_thread; //xforms #endif //XFORMS +#ifndef ENABLE_USE_MME +#define EPC_MODE_ENABLED 0 +#endif + pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex @@ -168,8 +171,6 @@ double rx_gain_off = 0.0; double sample_rate=30.72e6; double bw = 10.0e6; -static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; - char rf_config_file[1024]; int chain_offset=0; @@ -196,7 +197,6 @@ int otg_enabled; //int number_of_cards = 1; -static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; @@ -216,16 +216,37 @@ extern void init_eNB_afterRU(void); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int codingw = 0; -int fepw = 0; +char *parallel_config = NULL; +char *worker_config = NULL; + +static THREAD_STRUCT thread_struct; +void set_parallel_conf(char *parallel_conf) +{ + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) +{ + if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; + printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) +{ + return thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) +{ + return thread_struct.worker_conf; +} /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; -openair0_config_t openair0_cfg[MAX_CARDS]; - double cpuf; extern char uecap_xer[1024]; @@ -318,15 +339,23 @@ void signal_handler(int sig) { #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_fun(const char* s) +void exit_function(const char* file, const char* function, const int line, const char* s) { int ru_id; if (s != NULL) { - printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } oai_exit = 1; @@ -346,11 +375,11 @@ void exit_fun(const char* s) } -#if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first +#if defined(ENABLE_ITTI) itti_terminate_tasks (TASK_UNKNOWN); #endif - + exit(1); } @@ -445,46 +474,22 @@ void *l2l1_task(void *arg) { itti_set_task_real_time(TASK_L2L1); itti_mark_task_ready(TASK_L2L1); - /* Wait for the initialize message */ - printf("Wait for the ITTI initialize message\n"); - do { - if (message_p != NULL) { - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - - itti_receive_msg (TASK_L2L1, &message_p); - - switch (ITTI_MSG_ID(message_p)) { - case INITIALIZE_MESSAGE: - /* Start eNB thread */ - printf("L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); - start_eNB = 1; - break; - - case TERMINATE_MESSAGE: - printf("received terminate message\n"); - oai_exit=1; - start_eNB = 0; - itti_exit_task (); - break; - - default: - printf("Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } - } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE); - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); -/* ???? no else but seems to be UE only ??? - do { - // Wait for a message + /* Wait for the initialize message */ + printf("Wait for the ITTI initialize message\n"); + while (1) { itti_receive_msg (TASK_L2L1, &message_p); switch (ITTI_MSG_ID(message_p)) { + case INITIALIZE_MESSAGE: + /* Start eNB thread */ + LOG_D(PHY, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); + start_eNB = 1; + break; + case TERMINATE_MESSAGE: + LOG_W(PHY, " *** Exiting L2L1 thread\n"); oai_exit=1; + start_eNB = 0; itti_exit_task (); break; @@ -507,14 +512,15 @@ void *l2l1_task(void *arg) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } while(!oai_exit); -*/ + message_p = NULL; + }; + return NULL; } #endif -static void get_options(void) { +static void get_options(unsigned int *start_msc) { int tddflag, nonbiotflag; @@ -548,11 +554,9 @@ static void get_options(void) { set_glog(glog_level); } if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0); + load_module_shlib("telnetsrv",NULL,0,NULL); } - - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { memset((void*)&RC,0,sizeof(RC)); /* Read RC configuration file */ @@ -568,6 +572,8 @@ static void get_options(void) { RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0; } } + if(parallel_config != NULL) set_parallel_conf(parallel_config); + if(worker_config != NULL) set_worker_conf(worker_config); } @@ -621,112 +627,6 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { } - -void init_openair0(void) { - - int card; - int i; - - - for (card=0; card<MAX_CARDS; card++) { - - openair0_cfg[card].mmapped_dma=mmapped_dma; - openair0_cfg[card].configFilename = NULL; - - if(frame_parms[0]->N_RB_DL == 100) { - if(numerology == 0) - { - if (frame_parms[0]->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - }else if(numerology == 1) - { - openair0_cfg[card].sample_rate=61.44e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; - }else if(numerology == 2) - { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; - }else - { - printf("Un supported numerology\n"); - } - } else if(frame_parms[0]->N_RB_DL == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - } else if (frame_parms[0]->N_RB_DL == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; - } else if (frame_parms[0]->N_RB_DL == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; - } - - - if (frame_parms[0]->frame_type==TDD) - openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD - openair0_cfg[card].duplex_mode = duplex_mode_FDD; - - printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - RC.eNB[0][0]->frame_parms.nb_antennas_tx , - RC.eNB[0][0]->frame_parms.nb_antennas_rx ); - openair0_cfg[card].Mod_id = 0; - - openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; - - openair0_cfg[card].clock_source = clock_source; - - - openair0_cfg[card].tx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_tx ); - openair0_cfg[card].rx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_rx ); - - for (i=0; i<4; i++) { - - if (i<openair0_cfg[card].tx_num_channels) - openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i] ; - else - openair0_cfg[card].tx_freq[i]=0.0; - - if (i<openair0_cfg[card].rx_num_channels) - openair0_cfg[card].rx_freq[i] =downlink_frequency[0][i] + uplink_frequency_offset[0][i] ; - else - openair0_cfg[card].rx_freq[i]=0.0; - - openair0_cfg[card].autocal[i] = 1; - openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB; - - - openair0_cfg[card].configFilename = 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], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } - } /* for loop on cards */ -} - - void wait_RUs(void) { LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); @@ -771,12 +671,13 @@ void wait_eNBs(void) { /* * helper function to terminate a certain ITTI task */ -void terminate_task(task_id_t task_id, module_id_t mod_id) +void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { - LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE from task %s (%d) to task %s (%d)\n", + itti_get_task_name(from), from, itti_get_task_name(to), to); 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); + msg = itti_alloc_new_message (from, TERMINATE_MESSAGE); + itti_send_msg_to_task (to, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } extern void free_transport(PHY_VARS_eNB *); @@ -785,39 +686,20 @@ extern void phy_free_RU(RU_t*); int stop_L1L2(module_id_t enb_id) { LOG_W(ENB_APP, "stopping lte-softmodem\n"); - oai_exit = 1; if (!RC.ru) { - LOG_F(ENB_APP, "no RU configured\n"); - return -1; - } - - /* stop trx devices, multiple carrier currently not supported by RU */ - if (RC.ru[enb_id]) { - if (RC.ru[enb_id]->rfdevice.trx_stop_func) { - RC.ru[enb_id]->rfdevice.trx_stop_func(&RC.ru[enb_id]->rfdevice); - LOG_I(ENB_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"); - } - if (RC.ru[enb_id]->ifdevice.trx_stop_func) { - RC.ru[enb_id]->ifdevice.trx_stop_func(&RC.ru[enb_id]->ifdevice); - LOG_I(ENB_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"); - } - } else { - LOG_W(ENB_APP, "no RU found for index %d\n", enb_id); + LOG_UI(ENB_APP, "no RU configured\n"); return -1; } /* these tasks need to pick up new configuration */ - terminate_task(TASK_RRC_ENB, enb_id); - terminate_task(TASK_L2L1, enb_id); + terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); + terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1); + oai_exit = 1; + LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); + kill_RU_proc(RC.ru[enb_id]); LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); - LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); - kill_RU_proc(enb_id); oai_exit = 0; for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) { free_transport(RC.eNB[enb_id][cc_id]); @@ -840,7 +722,9 @@ int restart_L1L2(module_id_t enb_id) LOG_W(ENB_APP, "restarting lte-softmodem\n"); /* block threads */ + pthread_mutex_lock(&sync_mutex); sync_var = -1; + pthread_mutex_unlock(&sync_mutex); for (cc_id = 0; cc_id < RC.nb_L1_CC[enb_id]; cc_id++) { RC.eNB[enb_id][cc_id]->configured = 0; @@ -851,6 +735,9 @@ int restart_L1L2(module_id_t enb_id) /* TODO this should be done for all RUs associated to this eNB */ memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); set_function_spec_param(RC.ru[enb_id]); + /* reset the list of connected UEs in the MAC, since in this process with + * loose all UEs (have to reconnect) */ + init_UE_list(&RC.mac[enb_id]->UE_list); LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { @@ -901,16 +788,7 @@ static void wait_nfapi_init(char *thread_name) { pthread_mutex_unlock(&nfapi_sync_mutex); - /* - * Raphael Defosseux: temporary workaround for CI - * -- Repeating the message thrice to make sure - * -- it is present during flush. - */ printf( "NFAPI: got sync (%s)\n", thread_name); - printf( "NFAPI: got sync (%s)\n", thread_name); - printf( "NFAPI: got sync (%s)\n", thread_name); - fflush(stdout); - fflush(stderr); } int main( int argc, char **argv ) @@ -925,6 +803,7 @@ int main( int argc, char **argv ) #if defined (XFORMS) int ret; #endif + unsigned int start_msc=0; if ( load_configmodule(argc,argv) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); @@ -932,9 +811,6 @@ int main( int argc, char **argv ) mode = normal_txrx; - memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); - - memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); set_latency_target(); @@ -942,7 +818,7 @@ int main( int argc, char **argv ) printf("Reading in command-line options\n"); - get_options (); + get_options (&start_msc); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); @@ -967,22 +843,19 @@ int main( int argc, char **argv ) #if defined(ENABLE_ITTI) - printf("ITTI init\n"); + printf("ITTI init, useMME: %i\n" ,EPC_MODE_ENABLED); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); // initialize mscgen log after ITTI + if (start_msc) { + load_module_shlib("msc",NULL,0,&msc_interface); + } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); #endif if (opt_type != OPT_NONE) { - radio_type_t radio_type; - - if (frame_parms[0]->frame_type == FDD) - radio_type = RADIO_TYPE_FDD; - else - radio_type = RADIO_TYPE_TDD; - - if (init_opt(in_path, in_ip, NULL, radio_type) == -1) + if (init_opt(in_path, in_ip) == -1) LOG_E(OPT,"failed to run OPT \n"); } @@ -1000,6 +873,11 @@ int main( int argc, char **argv ) signal(SIGINT, signal_handler); #endif +#if defined(ENABLE_ITTI) + signal(SIGINT, signal_handler_itti); + signal(SIGTERM, signal_handler_itti); + signal(SIGABRT, signal_handler_itti); +#endif check_clock(); @@ -1192,6 +1070,8 @@ int main( int argc, char **argv ) } printf("wait RUs\n"); + fflush(stdout); + fflush(stderr); wait_RUs(); printf("ALL RUs READY!\n"); printf("RC.nb_RU:%d\n", RC.nb_RU); @@ -1264,25 +1144,20 @@ int main( int argc, char **argv ) printf("stopping MODEM threads\n"); - // cleanup - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { - stop_ru(RC.ru[ru_id]); - } - - stop_eNB(NB_eNB_INST); - stop_RU(RC.nb_RU); - /* release memory used by the RU/eNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - for (int inst = 0; inst < NB_eNB_INST; inst++) { - for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { - free_transport(RC.eNB[inst][cc_id]); - phy_free_lte_eNB(RC.eNB[inst][cc_id]); - } + stop_eNB(NB_eNB_INST); + stop_RU(RC.nb_RU); + /* release memory used by the RU/eNB threads (incomplete), after all + * threads have been stopped (they partially use the same memory) */ + for (int inst = 0; inst < NB_eNB_INST; inst++) { + for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { + free_transport(RC.eNB[inst][cc_id]); + phy_free_lte_eNB(RC.eNB[inst][cc_id]); } - for (int inst = 0; inst < RC.nb_RU; inst++) { - phy_free_RU(RC.ru[inst]); - } - free_lte_top(); + } + for (int inst = 0; inst < RC.nb_RU; inst++) { + phy_free_RU(RC.ru[inst]); + } + free_lte_top(); printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); end_configmodule(); @@ -1296,8 +1171,6 @@ int main( int argc, char **argv ) pthread_mutex_destroy(&ue_pf_po_mutex); - // *** Handle per CC_id openair0 - for(ru_id=0; ru_id<RC.nb_RU; ru_id++) { if (RC.ru[ru_id]->rfdevice.trx_end_func) { diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 2f8209f2d311ab5214952e670f4d6c4c19335b51..96ab799c3d11c5e1e2c2b0ce02710b50bf453873 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -92,12 +92,15 @@ #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" #define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" -#define CONFIG_HLP_CODINGW "coding worker thread enable(disable by defult)\n" -#define CONFIG_HLP_FEPW "FEP worker thread enabled(disable by defult)\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_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" +#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n" + /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument when calling config_get or config_getlist functions */ @@ -147,7 +150,9 @@ {"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ {"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ -} +{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ +{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \ + } #define DEFAULT_DLF 2680000000 @@ -186,14 +191,15 @@ {"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, 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}, \ -{"codingw" , CONFIG_HLP_CODINGW, PARAMFLAG_BOOL, iptr:&codingw, defintval:0, TYPE_INT, 0}, \ -{"fepw" , CONFIG_HLP_FEPW, PARAMFLAG_BOOL, iptr:&fepw, defintval:0, TYPE_INT, 0}, \ -{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, 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}, \ +{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ } #define CONFIG_HLP_FLOG "Enable online log \n" -#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n" +#define CONFIG_HLP_LOGL "Set the global log level, valide options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))\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 */ @@ -202,6 +208,7 @@ {"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}, \ } #define CMDLINE_ONLINELOG_IDX 0 #define CMDLINE_GLOGLEVEL_IDX 1 @@ -240,7 +247,6 @@ extern volatile int start_UE; #include "threads_t.h" extern threads_t threads; -extern void exit_fun(const char* s); // In lte-enb.c extern void init_eNB(int single_thread_flag,int wait_for_sync); extern void stop_eNB(int); @@ -251,7 +257,7 @@ extern void init_RU(const char*); extern void stop_ru(RU_t *ru); extern void init_RU_proc(RU_t *ru); extern void stop_RU(int nb_ru); -extern void kill_RU_proc(int inst); +extern void kill_RU_proc(RU_t *ru); extern void set_function_spec_param(RU_t *ru); // In lte-ue.c @@ -278,6 +284,10 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); void init_eNB_afterRU(void); +PARALLEL_CONF_t get_thread_parallel_conf(void); +WORKER_CONF_t get_thread_worker_conf(void); +void set_parallel_conf(char *parallel_conf); +void set_worker_conf(char *worker_conf); extern int stop_L1L2(module_id_t enb_id); extern int restart_L1L2(module_id_t enb_id); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index ab84249f9fe660bf0af91c6434396f4519da00dd..c49a54b98ac32c59f4e18e17f990209989f784ca 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -333,6 +333,13 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti } else UE->N_TA_offset = 0; +#if BASIC_SIMULATOR + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + UE->N_TA_offset = 0; +#endif + if (simL1flag == 1) init_ue_devices(UE); LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); init_UE_threads(inst); @@ -446,7 +453,6 @@ static void *UE_thread_synch(void *arg) int freq_offset=0; char threadname[128]; - UE->is_synchronized = 0; printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); cpu_set_t cpuset; @@ -522,11 +528,6 @@ static void *UE_thread_synch(void *arg) printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - while (oai_exit==0) { AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); while (UE->proc.instance_cnt_synch < 0) @@ -755,7 +756,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE_rxtx_proc_t *proc = rtd->proc; PHY_VARS_UE *UE = rtd->UE; - proc->instance_cnt_rxtx=-1; proc->subframe_rx=proc->sub_frame_start; char threadname[256]; @@ -1457,20 +1457,25 @@ void *UE_thread(void *arg) { int sub_frame=-1; //int cumulated_shift=0; + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + } while (!oai_exit) { +#if BASIC_SIMULATOR + while (!(UE->proc.instance_cnt_synch < 0)) { + printf("ue sync not ready\n"); + usleep(500*1000); + } +#endif + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); int instance_cnt_synch = UE->proc.instance_cnt_synch; int is_synchronized = UE->is_synchronized; AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if (is_synchronized == 0) { -#if BASIC_SIMULATOR - while (!((instance_cnt_synch = UE->proc.instance_cnt_synch) < 0)) { - printf("ue sync not ready\n"); - usleep(500*1000); - } -#endif if (instance_cnt_synch < 0) { // we can invoke the synch // grab 10 ms of signal and wakeup synch thread for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) @@ -1661,12 +1666,7 @@ void *UE_thread(void *arg) { proc->instance_cnt_rxtx++; LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); - if (proc->instance_cnt_rxtx == 0) { - if (pthread_cond_signal(&proc->cond_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); - exit_fun("nothing to add"); - } - } else { + if (proc->instance_cnt_rxtx != 0) { LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); if (proc->instance_cnt_rxtx > 2) exit_fun("instance_cnt_rxtx > 2"); @@ -1717,6 +1717,8 @@ void init_UE_threads(int inst) { pthread_mutex_init(&UE->proc.mutex_synch,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL); + UE->proc.instance_cnt_synch = -1; + UE->is_synchronized = 0; // the threads are not yet active, therefore access is allowed without locking int nb_threads=RX_NB_TH; @@ -1728,6 +1730,7 @@ void init_UE_threads(int inst) { pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].instance_cnt_rxtx = -1; UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index a2a12f9dd9f301a43c0f6a9767db995bc5d2f8a6..69556b19f263eb445f86de64d04a26c5ad458904 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -84,7 +84,6 @@ #endif #if defined(ENABLE_ITTI) -#include "intertask_interface_init.h" #include "create_tasks.h" #endif @@ -221,8 +220,34 @@ int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int codingw = 0; -int fepw = 0; +char *parallel_config = NULL; +char *worker_config = NULL; + +char* usrp_args=NULL; +char* usrp_clksrc=NULL; + +static THREAD_STRUCT thread_struct; +void set_parallel_conf(char *parallel_conf) +{ + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) +{ + if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; + printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) +{ + return thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) +{ + return thread_struct.worker_conf; +} /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; @@ -323,13 +348,13 @@ void signal_handler(int sig) { -void exit_fun(const char* s) +void exit_function(const char* file, const char* function, const int line, const char* s) { int CC_id; logClean(); if (s != NULL) { - printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } oai_exit = 1; @@ -342,10 +367,11 @@ void exit_fun(const char* s) PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); } -#if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first +#if defined(ENABLE_ITTI) itti_terminate_tasks (TASK_UNKNOWN); #endif + exit(1); } #ifdef XFORMS @@ -470,7 +496,7 @@ void *l2l1_task(void *arg) { extern int16_t dlsch_demod_shift; -static void get_options(void) { +static void get_options(unsigned int *start_msc) { int CC_id; int tddflag, nonbiotflag; char *loopfile=NULL; @@ -505,7 +531,7 @@ static void get_options(void) { set_glog(glog_level); } if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0); + load_module_shlib("telnetsrv",NULL,0,NULL); } paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; @@ -583,6 +609,8 @@ static void get_options(void) { if(nfapi_mode!=3) uecap_xer_in=1; } *//* UE with config file */ + if(parallel_config != NULL) set_parallel_conf(parallel_config); + if(worker_config != NULL) set_worker_conf(worker_config); } @@ -714,6 +742,26 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) { openair0_cfg[card].tx_freq[i], openair0_cfg[card].rx_freq[i]); } + + if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args; + if (usrp_clksrc) { + if (strcmp(usrp_clksrc, "internal") == 0) { + openair0_cfg[card].clock_source = internal; + LOG_D(PHY, "USRP clock source set as internal\n"); + } else if (strcmp(usrp_clksrc, "external") == 0) { + openair0_cfg[card].clock_source = external; + LOG_D(PHY, "USRP clock source set as external\n"); + } else if (strcmp(usrp_clksrc, "gpsdo") == 0) { + openair0_cfg[card].clock_source = gpsdo; + LOG_D(PHY, "USRP clock source set as gpsdo\n"); + } else { + openair0_cfg[card].clock_source = internal; + LOG_I(PHY, "USRP clock source unknown ('%s'). defaulting to internal\n", usrp_clksrc); + } + } else { + openair0_cfg[card].clock_source = internal; + LOG_I(PHY, "USRP clock source not specified. defaulting to internal\n"); + } } } @@ -770,6 +818,7 @@ int main( int argc, char **argv ) int CC_id; uint8_t abstraction_flag=0; + unsigned int start_msc=0; // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues @@ -797,7 +846,9 @@ int main( int argc, char **argv ) printf("Reading in command-line options\n"); for (int i=0;i<MAX_NUM_CCs;i++) tx_max_power[i]=23; - get_options (); + get_options (&start_msc); + +printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker config [%d] \n", get_thread_parallel_conf(), get_thread_worker_conf()); printf("Running with %d UE instances\n",NB_UE_INST); @@ -830,21 +881,6 @@ int main( int argc, char **argv ) //randominit (0); set_taus_seed (0); - - set_log(HW, OAILOG_DEBUG, 1); - set_log(PHY, OAILOG_INFO, 1); - set_log(MAC, OAILOG_INFO, 1); - set_log(RLC, OAILOG_INFO, 1); - set_log(PDCP, OAILOG_INFO, 1); - set_log(OTG, OAILOG_INFO, 1); - set_log(RRC, OAILOG_INFO, 1); -#if defined(ENABLE_ITTI) - set_log(SIM, OAILOG_INFO, 1); -# if defined(ENABLE_USE_MME) - set_log(NAS, OAILOG_INFO, 1); -# endif -#endif - cpuf=get_cpu_freq_GHz(); pthread_cond_init(&sync_cond,NULL); @@ -858,18 +894,14 @@ int main( int argc, char **argv ) itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); // initialize mscgen log after ITTI + if (start_msc) { + load_module_shlib("msc",NULL,0,&msc_interface); + } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); #endif if (opt_type != OPT_NONE) { - radio_type_t radio_type; - - if (frame_parms[0]->frame_type == FDD) - radio_type = RADIO_TYPE_FDD; - else - radio_type = RADIO_TYPE_TDD; - - if (init_opt(in_path, in_ip, NULL, radio_type) == -1) + if (init_opt(in_path, in_ip) == -1) LOG_E(OPT,"failed to run OPT \n"); }