mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
8.6 KiB
C
223 lines
8.6 KiB
C
/**
|
|
*
|
|
* \section COPYRIGHT
|
|
*
|
|
* Copyright 2013-2014 The libLTE Developers. See the
|
|
* COPYRIGHT file at the top-level directory of this distribution.
|
|
*
|
|
* \section LICENSE
|
|
*
|
|
* This file is part of the libLTE library.
|
|
*
|
|
* libLTE is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation, either version 3 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* libLTE is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* A copy of the GNU Lesser General Public License can be found in
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
* and at http://www.gnu.org/licenses/.
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "liblte/rrc/common/rrc_common.h"
|
|
#include "liblte/rrc/messages/bcch.h"
|
|
#include "liblte/rrc/messages/sib1.h"
|
|
#include "liblte/phy/utils/bit.h"
|
|
#include "liblte/rrc/asn/rrc_asn.h"
|
|
|
|
void read_plmn(PLMN_IdentityInfo_t *msg, plmn_identity_t *plmn) {
|
|
MCC_t *mcc = msg->plmn_Identity.mcc;
|
|
plmn->mcc = *((int*) mcc->list.array[0])*100+*((int*)mcc->list.array[1])*10+*((int*)mcc->list.array[2]);
|
|
plmn->mnc = *((int*) msg->plmn_Identity.mnc.list.array[0])*10+*((int*) msg->plmn_Identity.mnc.list.array[1]);
|
|
}
|
|
|
|
uint32_t bcch_dlsch_sib1_get_freq_num(void *bcch_dlsch_msg) {
|
|
BCCH_DL_SCH_Message_t *msg = (BCCH_DL_SCH_Message_t*) bcch_dlsch_msg;
|
|
SystemInformationBlockType1_t *sib1 = &(msg->message.choice.c1.choice.systemInformationBlockType1);
|
|
return (uint32_t) sib1->freqBandIndicator;
|
|
}
|
|
|
|
void bcch_dlsch_sib1_get_plmns(void *bcch_dlsch_msg, plmn_identity_t *plmns, uint32_t max_plmn_identities) {
|
|
int i;
|
|
BCCH_DL_SCH_Message_t *msg = (BCCH_DL_SCH_Message_t*) bcch_dlsch_msg;
|
|
SystemInformationBlockType1_t *sib1 = &(msg->message.choice.c1.choice.systemInformationBlockType1);
|
|
for (i=0;i<MIN(max_plmn_identities,sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count);i++) {
|
|
read_plmn(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i], &plmns[i]);
|
|
}
|
|
}
|
|
|
|
void bcch_dlsch_sib1_get_cell_access_info(void *bcch_dlsch_msg, cell_access_info_t *info) {
|
|
BCCH_DL_SCH_Message_t *msg = (BCCH_DL_SCH_Message_t*) bcch_dlsch_msg;
|
|
SystemInformationBlockType1_t *sib1 = &(msg->message.choice.c1.choice.systemInformationBlockType1);
|
|
info->tracking_area_code = sib1->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8|
|
|
sib1->cellAccessRelatedInfo.trackingAreaCode.buf[1];
|
|
info->cell_id = (sib1->cellAccessRelatedInfo.cellIdentity.buf[0]<<24)|
|
|
(sib1->cellAccessRelatedInfo.cellIdentity.buf[1]<<16)|
|
|
(sib1->cellAccessRelatedInfo.cellIdentity.buf[2]<<8)|
|
|
(sib1->cellAccessRelatedInfo.cellIdentity.buf[3]&0xF0);
|
|
info->cell_id >>= 4;
|
|
info->cellBarred =
|
|
sib1->cellAccessRelatedInfo.cellBarred ==
|
|
SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_barred;
|
|
info->intraFreqReselection =
|
|
sib1->cellAccessRelatedInfo.intraFreqReselection ==
|
|
SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_allowed;
|
|
}
|
|
|
|
uint32_t get_si_period(long int period) {
|
|
return 8<<(period);
|
|
}
|
|
|
|
sib_type_t get_si_type(SIB_Type_t *type) {
|
|
switch(*type) {
|
|
case SIB_Type_sibType3: return SIB3;
|
|
case SIB_Type_sibType4: return SIB4;
|
|
case SIB_Type_sibType5: return SIB5;
|
|
case SIB_Type_sibType6: return SIB6;
|
|
case SIB_Type_sibType7: return SIB7;
|
|
case SIB_Type_sibType8: return SIB8;
|
|
case SIB_Type_sibType9: return SIB9;
|
|
default: return SIB_ERROR;
|
|
}
|
|
}
|
|
|
|
uint32_t get_window(long int window_length) {
|
|
switch(window_length) {
|
|
case SystemInformationBlockType1__si_WindowLength_ms1: return 1;
|
|
case SystemInformationBlockType1__si_WindowLength_ms2: return 2;
|
|
case SystemInformationBlockType1__si_WindowLength_ms5: return 5;
|
|
case SystemInformationBlockType1__si_WindowLength_ms10: return 10;
|
|
case SystemInformationBlockType1__si_WindowLength_ms15: return 15;
|
|
case SystemInformationBlockType1__si_WindowLength_ms20: return 20;
|
|
case SystemInformationBlockType1__si_WindowLength_ms40: return 40;
|
|
default: return 0;
|
|
}
|
|
}
|
|
int bcch_dlsch_sib1_get_scheduling_info(void *bcch_dlsch_msg,
|
|
uint32_t *si_window_length,
|
|
scheduling_info_t *info,
|
|
uint32_t max_elems)
|
|
{
|
|
BCCH_DL_SCH_Message_t *msg = (BCCH_DL_SCH_Message_t*) bcch_dlsch_msg;
|
|
SystemInformationBlockType1_t *sib1 = &(msg->message.choice.c1.choice.systemInformationBlockType1);
|
|
|
|
uint32_t nelems = 0;
|
|
|
|
if (max_elems > 0 && info != NULL) {
|
|
/* First is always SIB2 */
|
|
info[0].type = SIB2;
|
|
info[0].n = 0;
|
|
info[0].period = get_si_period(sib1->schedulingInfoList.list.array[0]->si_Periodicity);
|
|
nelems++;
|
|
for (int i=0;i<sib1->schedulingInfoList.list.count;i++) {
|
|
SchedulingInfo_t *s = sib1->schedulingInfoList.list.array[i];
|
|
|
|
for (int j=0;j<s->sib_MappingInfo.list.count;j++) {
|
|
if (nelems < max_elems) {
|
|
info[nelems].type = get_si_type(s->sib_MappingInfo.list.array[j]);
|
|
info[nelems].n = i;
|
|
info[nelems].period = get_si_period(s->si_Periodicity);
|
|
nelems++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
if (si_window_length) {
|
|
*si_window_length = get_window(sib1->si_WindowLength);
|
|
}
|
|
return nelems;
|
|
}
|
|
|
|
MCC_MNC_Digit_t *dup_digit(MCC_MNC_Digit_t value) {
|
|
MCC_MNC_Digit_t *x = calloc(1, sizeof(MCC_MNC_Digit_t));
|
|
*x = value;
|
|
return x;
|
|
}
|
|
void bcch_dlsch_sib1(BCCH_DL_SCH_Message_t *msg,
|
|
MCC_MNC_Digit_t mcc_val[3],
|
|
MCC_MNC_Digit_t mnc_val[2],
|
|
uint8_t tac_val[2],
|
|
uint8_t cid_val[4],
|
|
int freq_band)
|
|
{
|
|
|
|
bzero(msg, sizeof(BCCH_DL_SCH_Message_t));
|
|
|
|
msg->message.present = BCCH_DL_SCH_MessageType_PR_c1;
|
|
msg->message.choice.c1.present = BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1;
|
|
SystemInformationBlockType1_t *sib1 = &(msg->message.choice.c1.choice.systemInformationBlockType1);
|
|
|
|
PLMN_IdentityInfo_t *PLMN_identity_info = calloc(1, sizeof(PLMN_IdentityInfo_t));
|
|
MCC_t *mcc = calloc(1, sizeof(MCC_t));
|
|
PLMN_identity_info->plmn_Identity.mcc = mcc;
|
|
asn_set_empty(&mcc->list);
|
|
for (int i=0;i<3;i++) {
|
|
ASN_SEQUENCE_ADD(&mcc->list,dup_digit(mcc_val[i]));
|
|
}
|
|
asn_set_empty(&PLMN_identity_info->plmn_Identity.mnc.list);
|
|
for (int i=0;i<2;i++) {
|
|
ASN_SEQUENCE_ADD(&PLMN_identity_info->plmn_Identity.mnc.list,dup_digit(mnc_val[i]));
|
|
}
|
|
PLMN_identity_info->cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved;
|
|
|
|
ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list,PLMN_identity_info);
|
|
|
|
sib1->cellAccessRelatedInfo.trackingAreaCode.buf=malloc(2);
|
|
for (int i=0;i<2;i++) {
|
|
sib1->cellAccessRelatedInfo.trackingAreaCode.buf[i] = tac_val[i];
|
|
}
|
|
sib1->cellAccessRelatedInfo.trackingAreaCode.size=2;
|
|
sib1->cellAccessRelatedInfo.trackingAreaCode.bits_unused=0;
|
|
|
|
sib1->cellAccessRelatedInfo.cellIdentity.buf=malloc(4);
|
|
for (int i=0;i<4;i++) {
|
|
sib1->cellAccessRelatedInfo.cellIdentity.buf[i] = cid_val[i];
|
|
}
|
|
sib1->cellAccessRelatedInfo.cellIdentity.size=4;
|
|
sib1->cellAccessRelatedInfo.cellIdentity.bits_unused=4;
|
|
|
|
sib1->cellAccessRelatedInfo.cellBarred=SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_barred;
|
|
|
|
sib1->cellAccessRelatedInfo.intraFreqReselection=SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_allowed;
|
|
sib1->cellAccessRelatedInfo.csg_Indication=0;
|
|
|
|
sib1->cellSelectionInfo.q_RxLevMin=-60;
|
|
sib1->cellSelectionInfo.q_RxLevMinOffset=NULL;
|
|
|
|
sib1->freqBandIndicator = (long int) freq_band;
|
|
|
|
|
|
SchedulingInfo_t *schedulingInfo_3 = calloc(2, sizeof(SchedulingInfo_t));
|
|
SchedulingInfo_t *schedulingInfo_6 = calloc(2, sizeof(SchedulingInfo_t));
|
|
SIB_Type_t *sib_type_3 = calloc(1, sizeof(SIB_Type_t));
|
|
SIB_Type_t *sib_type_6 = calloc(1, sizeof(SIB_Type_t));
|
|
|
|
schedulingInfo_3->si_Periodicity=SchedulingInfo__si_Periodicity_rf16;
|
|
*sib_type_3=SIB_Type_sibType3;
|
|
ASN_SEQUENCE_ADD(&schedulingInfo_3->sib_MappingInfo.list,sib_type_3);
|
|
ASN_SEQUENCE_ADD(&sib1->schedulingInfoList.list,schedulingInfo_3);
|
|
|
|
schedulingInfo_6->si_Periodicity=SchedulingInfo__si_Periodicity_rf64;
|
|
*sib_type_6=SIB_Type_sibType6;
|
|
ASN_SEQUENCE_ADD(&schedulingInfo_6->sib_MappingInfo.list,sib_type_6);
|
|
ASN_SEQUENCE_ADD(&sib1->schedulingInfoList.list,schedulingInfo_6);
|
|
|
|
sib1->si_WindowLength=SystemInformationBlockType1__si_WindowLength_ms40;
|
|
sib1->systemInfoValueTag=8;
|
|
}
|
|
|
|
|
|
|
|
|
|
|