/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ #include "rrc_defs.h" #include "rrc_extern.h" #include "rrc_eNB_UE_context.h" #include "common/ran_context.h" #include "LTE_DL-DCCH-Message.h" #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> extern RAN_CONTEXT_t RC; extern mui_t rrc_eNB_mui; int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config, OCTET_STRING_t *scg_RB_config) { asn_enc_rval_t enc_rval; LTE_DL_DCCH_Message_t dl_dcch_msg; LTE_RRCConnectionReconfiguration_t *r; int trans_id; LTE_RadioResourceConfigDedicated_t rrcd; LTE_DRB_ToAddModList_t drb_list; struct LTE_DRB_ToAddMod drb; long eps_bearer_id; struct LTE_RLC_Config rlc; long lcid; struct LTE_LogicalChannelConfig lc; struct LTE_LogicalChannelConfig__ul_SpecificParameters ul_params; long lcg; struct LTE_RadioResourceConfigDedicated__mac_MainConfig mac; struct LTE_MAC_MainConfig__ext4 mac_ext4; struct LTE_MAC_MainConfig__ext4__dualConnectivityPHR dc_phr; memset(&rrcd, 0, sizeof(rrcd)); memset(&drb_list, 0, sizeof(drb_list)); memset(&drb, 0, sizeof(drb)); memset(&rlc, 0, sizeof(rlc)); memset(&lc, 0, sizeof(lc)); memset(&ul_params, 0, sizeof(ul_params)); memset(&mac, 0, sizeof(mac)); memset(&mac_ext4, 0, sizeof(mac_ext4)); memset(&dc_phr, 0, sizeof(dc_phr)); trans_id = rrc_eNB_get_next_transaction_identifier(ctxt->module_id); memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; r = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration; r->rrc_TransactionIdentifier = trans_id; r->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1; r->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8; r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated = &rrcd; rrcd.drb_ToAddModList = &drb_list; eps_bearer_id = 5; drb.eps_BearerIdentity = &eps_bearer_id; drb.drb_Identity = 5; drb.rlc_Config = &rlc; lcid = 4; drb.logicalChannelIdentity = &lcid; drb.logicalChannelConfig = &lc; rlc.present = LTE_RLC_Config_PR_am; rlc.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; rlc.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; rlc.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; rlc.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; rlc.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; rlc.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; lc.ul_SpecificParameters = &ul_params; ul_params.priority = 12; ul_params.prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; ul_params.bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300; lcg = 3; ul_params.logicalChannelGroup = &lcg; rrcd.mac_MainConfig = &mac; mac.present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; mac.choice.explicitValue.timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_sf10240; mac.choice.explicitValue.ext4 = &mac_ext4; mac_ext4.dualConnectivityPHR = &dc_phr; dc_phr.present = LTE_MAC_MainConfig__ext4__dualConnectivityPHR_PR_setup; dc_phr.choice.setup.phr_ModeOtherCG_r12 = LTE_MAC_MainConfig__ext4__dualConnectivityPHR__setup__phr_ModeOtherCG_r12_virtual; /* NR config */ struct LTE_RRCConnectionReconfiguration_v890_IEs cr_890; struct LTE_RRCConnectionReconfiguration_v920_IEs cr_920; struct LTE_RRCConnectionReconfiguration_v1020_IEs cr_1020; struct LTE_RRCConnectionReconfiguration_v1130_IEs cr_1130; struct LTE_RRCConnectionReconfiguration_v1250_IEs cr_1250; struct LTE_RRCConnectionReconfiguration_v1310_IEs cr_1310; struct LTE_RRCConnectionReconfiguration_v1430_IEs cr_1430; struct LTE_RRCConnectionReconfiguration_v1510_IEs cr_1510; struct LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15 nr; memset(&cr_890, 0, sizeof(cr_890)); memset(&cr_920, 0, sizeof(cr_920)); memset(&cr_1020, 0, sizeof(cr_1020)); memset(&cr_1130, 0, sizeof(cr_1130)); memset(&cr_1250, 0, sizeof(cr_1250)); memset(&cr_1310, 0, sizeof(cr_1310)); memset(&cr_1430, 0, sizeof(cr_1430)); memset(&cr_1510, 0, sizeof(cr_1510)); memset(&nr, 0, sizeof(nr)); r->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = &cr_890; cr_890.nonCriticalExtension = &cr_920; cr_920.nonCriticalExtension = &cr_1020; cr_1020.nonCriticalExtension = &cr_1130; cr_1130.nonCriticalExtension = &cr_1250; cr_1250.nonCriticalExtension = &cr_1310; cr_1310.nonCriticalExtension = &cr_1430; cr_1430.nonCriticalExtension = &cr_1510; cr_1510.nr_Config_r15 = &nr; nr.present = LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15_PR_setup; nr.choice.setup.endc_ReleaseAndAdd_r15 = 0; /* FALSE */ OCTET_STRING_t dummy_scg_conf; unsigned char scg_conf_buf[4] = { 0, 0, 0, 0 }; if (scg_group_config!=NULL) nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = scg_group_config; //&scg_conf; else{ nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = &dummy_scg_conf; dummy_scg_conf.buf = scg_conf_buf; dummy_scg_conf.size = 4; } long sk_counter = 0; cr_1510.sk_Counter_r15 = &sk_counter; OCTET_STRING_t dummy_nr1_conf; unsigned char nr1_buf[4] = { 0, 0, 0, 0 }; if(scg_RB_config!=NULL) cr_1510.nr_RadioBearerConfig1_r15 = scg_RB_config; else{ cr_1510.nr_RadioBearerConfig1_r15 = &dummy_nr1_conf; dummy_nr1_conf.buf = nr1_buf; dummy_nr1_conf.size = 4; } OCTET_STRING_t nr2_conf; unsigned char nr2_buf[4] = { 0, 0, 0, 0 }; cr_1510.nr_RadioBearerConfig2_r15 = &nr2_conf; nr2_conf.buf = nr2_buf; nr2_conf.size = 4; ASN_SEQUENCE_ADD(&drb_list.list, &drb); enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, (void *)&dl_dcch_msg, buffer, buffer_size); { int len = (enc_rval.encoded + 7) / 8; int i; printf("len = %d\n", len); for (i = 0; i < len; i++) printf(" %2.2x", buffer[i]); printf("\n"); } return (enc_rval.encoded + 7) / 8; } volatile int go_nr; struct rrc_eNB_ue_context_s * get_first_ue_context(eNB_RRC_INST *rrc_instance_pP) { struct rrc_eNB_ue_context_s *ue_context_p = NULL; RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { return ue_context_p; } return NULL; } void rrc_go_nr(void) { protocol_ctxt_t ctxt; rrc_eNB_ue_context_t *ue_context; unsigned char buffer[8192]; int size; go_nr = 0; ue_context = get_first_ue_context(RC.rrc[0]); PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, ENB_FLAG_YES, ue_context->ue_context.rnti, 0, 0); size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, NULL, NULL); rrc_data_req(&ctxt, DCCH, rrc_eNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } static void new_thread(void *(*f)(void *), void *data) { pthread_t t; pthread_attr_t att; if (pthread_attr_init(&att)) { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } if (pthread_attr_setstacksize(&att, 10000000)) { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } if (pthread_create(&t, &att, f, data)) { fprintf(stderr, "pthread_create err\n"); exit(1); } if (pthread_attr_destroy(&att)) { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } } static int create_listen_socket(char *addr, int port) { struct sockaddr_in a; int s; int v; s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("socket"); exit(1); } v = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int))) { perror("setsockopt"); exit(1); } a.sin_family = AF_INET; a.sin_port = htons(port); a.sin_addr.s_addr = inet_addr(addr); if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } if (listen(s, 5)) { perror("listen"); exit(1); } return s; } static int socket_accept(int s) { struct sockaddr_in a; socklen_t alen; alen = sizeof(a); return accept(s, (struct sockaddr *)&a, &alen); } static int fullread(int fd, void *_buf, int count) { char *buf = _buf; int ret = 0; int l; while (count) { l = read(fd, buf, count); if (l <= 0) return -1; count -= l; buf += l; ret += l; } return ret; } void *nr_hack(void *_) { int s = create_listen_socket("0.0.0.0", 9001); int t; over: t = socket_accept(s); while (1) { char c; if (fullread(t, &c, 1) != 1) { close(t); goto over; } if (c != '\n') continue; printf("setting go_nr to 1\n"); go_nr = 1; } return 0; } void rrc_endc_hack_init(void) { new_thread(nr_hack, NULL); }